Commit 2d2f05ce authored by Andy Simmonett's avatar Andy Simmonett
Browse files

Merge branch 'master' of github.com:pandegroup/openmm into genpt

parents 94823d84 4d32047c
...@@ -128,21 +128,15 @@ State RPMDIntegrator::getState(int copy, int types, bool enforcePeriodicBox, int ...@@ -128,21 +128,15 @@ State RPMDIntegrator::getState(int copy, int types, bool enforcePeriodicBox, int
center *= 1.0/molecules[i].size(); center *= 1.0/molecules[i].size();
// Find the displacement to move it into the first periodic box. // Find the displacement to move it into the first periodic box.
Vec3 diff;
int xcell = (int) floor(center[0]/periodicBoxSize[0][0]); diff += periodicBoxSize[2]*floor(center[2]/periodicBoxSize[2][2]);
int ycell = (int) floor(center[1]/periodicBoxSize[1][1]); diff += periodicBoxSize[1]*floor((center[1]-diff[1])/periodicBoxSize[1][1]);
int zcell = (int) floor(center[2]/periodicBoxSize[2][2]); diff += periodicBoxSize[0]*floor((center[0]-diff[0])/periodicBoxSize[0][0]);
double dx = xcell*periodicBoxSize[0][0];
double dy = ycell*periodicBoxSize[1][1];
double dz = zcell*periodicBoxSize[2][2];
// Translate all the particles in the molecule. // Translate all the particles in the molecule.
for (int j = 0; j < (int) molecules[i].size(); j++) { for (int j = 0; j < (int) molecules[i].size(); j++) {
Vec3& pos = positions[molecules[i][j]]; Vec3& pos = positions[molecules[i][j]];
pos[0] -= dx; pos -= diff;
pos[1] -= dy;
pos[2] -= dz;
} }
} }
...@@ -170,7 +164,7 @@ double RPMDIntegrator::computeKineticEnergy() { ...@@ -170,7 +164,7 @@ double RPMDIntegrator::computeKineticEnergy() {
void RPMDIntegrator::step(int steps) { void RPMDIntegrator::step(int steps) {
if (context == NULL) if (context == NULL)
throw OpenMMException("This Integrator is not bound to a context!"); throw OpenMMException("This Integrator is not bound to a context!");
if (!hasSetPosition) { if (!hasSetPosition) {
// Initialize the positions from the context. // Initialize the positions from the context.
......
...@@ -75,6 +75,6 @@ SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES LINK_FLAGS "${EXTRA_LINK_FLAGS ...@@ -75,6 +75,6 @@ SET_TARGET_PROPERTIES(${SHARED_TARGET} PROPERTIES LINK_FLAGS "${EXTRA_LINK_FLAGS
INSTALL(TARGETS ${SHARED_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/plugins) INSTALL(TARGETS ${SHARED_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/plugins)
IF(BUILD_TESTING) IF(BUILD_TESTING AND OPENMM_BUILD_REFERENCE_TESTS)
SUBDIRS (tests) SUBDIRS (tests)
ENDIF(BUILD_TESTING) ENDIF(BUILD_TESTING AND OPENMM_BUILD_REFERENCE_TESTS)
...@@ -6,6 +6,8 @@ INSTALL_FILES(/include/openmm/serialization FILES ${CMAKE_CURRENT_SOURCE_DIR}/in ...@@ -6,6 +6,8 @@ INSTALL_FILES(/include/openmm/serialization FILES ${CMAKE_CURRENT_SOURCE_DIR}/in
INSTALL_FILES(/include/openmm/serialization FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/openmm/serialization/SerializationProxy.h) INSTALL_FILES(/include/openmm/serialization FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/openmm/serialization/SerializationProxy.h)
INSTALL_FILES(/include/openmm/serialization FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/openmm/serialization/XmlSerializer.h) INSTALL_FILES(/include/openmm/serialization FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/openmm/serialization/XmlSerializer.h)
IF(BUILD_TESTING) SET(OPENMM_BUILD_SERIALIZATION_TESTS TRUE CACHE BOOL "Whether to build serialization test cases")
MARK_AS_ADVANCED(OPENMM_BUILD_SERIALIZATION_TESTS)
IF(BUILD_TESTING AND OPENMM_BUILD_SERIALIZATION_TESTS)
ADD_SUBDIRECTORY(tests) ADD_SUBDIRECTORY(tests)
ENDIF(BUILD_TESTING) ENDIF(BUILD_TESTING AND OPENMM_BUILD_SERIALIZATION_TESTS)
#ifndef OPENMM_COMPOUND_INTEGRATOR_PROXY_H_
#define OPENMM_COMPOUND_INTEGRATOR_PROXY_H_
#include "openmm/serialization/XmlSerializer.h"
namespace OpenMM {
class CompoundIntegratorProxy : public SerializationProxy {
public:
CompoundIntegratorProxy();
void serialize(const void* object, SerializationNode& node) const;
void* deserialize(const SerializationNode& node) const;
};
}
#endif /*OPENMM_COMPOUND_INTEGRATOR_PROXY_H_*/
\ No newline at end of file
...@@ -105,7 +105,7 @@ public: ...@@ -105,7 +105,7 @@ public:
/** /**
* Determine whether this node has a property with a particular node. * Determine whether this node has a property with a particular node.
* *
* @param the name of the property to check for * @param name the name of the property to check for
*/ */
bool hasProperty(const std::string& name) const; bool hasProperty(const std::string& name) const;
/** /**
......
#ifndef OPENMM_GBVIFORCEFIELDIMPL_H_
#define OPENMM_GBVIFORCEFIELDIMPL_H_
/* -------------------------------------------------------------------------- * /* -------------------------------------------------------------------------- *
* OpenMM * * OpenMM *
* -------------------------------------------------------------------------- * * -------------------------------------------------------------------------- *
...@@ -9,7 +6,7 @@ ...@@ -9,7 +6,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 Stanford University and the Authors. * * Portions copyright (c) 2015 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -32,46 +29,29 @@ ...@@ -32,46 +29,29 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. * * USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
#include "ForceImpl.h" #include "openmm/serialization/CompoundIntegratorProxy.h"
#include "openmm/GBVIForce.h" #include <OpenMM.h>
#include "openmm/Kernel.h"
#include <string> using namespace std;
using namespace OpenMM;
namespace OpenMM {
CompoundIntegratorProxy::CompoundIntegratorProxy() : SerializationProxy("CompoundIntegrator") {
/** }
* This is the internal implementation of GBVIForce.
*/ void CompoundIntegratorProxy::serialize(const void* object, SerializationNode& node) const {
node.setIntProperty("version", 1);
class GBVIForceImpl : public ForceImpl { const CompoundIntegrator& integrator = *reinterpret_cast<const CompoundIntegrator*>(object);
public: node.setIntProperty("currentIntegrator", integrator.getCurrentIntegrator());
GBVIForceImpl(const GBVIForce& owner); for (int i = 0; i < integrator.getNumIntegrators(); i++)
void initialize(ContextImpl& context); node.createChildNode("Integrator", &integrator.getIntegrator(i));
const GBVIForce& getOwner() const { }
return owner;
} void* CompoundIntegratorProxy::deserialize(const SerializationNode& node) const {
if (node.getIntProperty("version") != 1)
// calculate scaled radii (Eq. 5 of Labute paper [JCC 29 1693-1698 2008]) throw OpenMMException("Unsupported version number");
CompoundIntegrator *integrator = new CompoundIntegrator();
void findScaledRadii( int numberOfParticles, const std::vector<std::vector<int> >& bondIndices, for (int i = 0; i < node.getChildren().size(); i++)
const std::vector<double> & bondLengths, std::vector<double> & scaledRadii) const; integrator->addIntegrator(node.getChildren()[i].decodeObject<Integrator>());
integrator->setCurrentIntegrator(node.getIntProperty("currentIntegrator"));
// if bond info not set, then use bond forces/constraints return integrator;
int getBondsFromForces(ContextImpl& context); }
\ No newline at end of file
void updateContextState(ContextImpl& context) {
// This force field doesn't update the state directly.
}
double calcForcesAndEnergy(ContextImpl& context, bool includeForces, bool includeEnergy, int groups);
std::map<std::string, double> getDefaultParameters() {
return std::map<std::string, double>(); // This force field doesn't define any parameters.
}
std::vector<std::string> getKernelNames();
private:
const GBVIForce& owner;
Kernel kernel;
};
} // namespace OpenMM
#endif /*OPENMM_GBVIFORCEFIELDIMPL_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) 2010-2014 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "openmm/serialization/GBVIForceProxy.h"
#include "openmm/serialization/SerializationNode.h"
#include "openmm/Force.h"
#include "openmm/GBVIForce.h"
#include <sstream>
using namespace OpenMM;
using namespace std;
GBVIForceProxy::GBVIForceProxy() : SerializationProxy("GBVIForce") {
}
void GBVIForceProxy::serialize(const void* object, SerializationNode& node) const {
node.setIntProperty("version", 2);
const GBVIForce& force = *reinterpret_cast<const GBVIForce*>(object);
node.setIntProperty("forceGroup", force.getForceGroup());
node.setIntProperty("method", (int) force.getNonbondedMethod());
node.setIntProperty("scalingMethod", (int) force.getBornRadiusScalingMethod());
node.setDoubleProperty("quinticLowerLimitFactor", force.getQuinticLowerLimitFactor());
node.setDoubleProperty("quinticUpperBornRadiusLimit", force.getQuinticUpperBornRadiusLimit());
node.setDoubleProperty("cutoff", force.getCutoffDistance());
node.setDoubleProperty("soluteDielectric", force.getSoluteDielectric());
node.setDoubleProperty("solventDielectric", force.getSolventDielectric());
SerializationNode& particles = node.createChildNode("Particles");
for (int i = 0; i < force.getNumParticles(); i++) {
double charge, radius, gamma;
force.getParticleParameters(i, charge, radius, gamma);
particles.createChildNode("Particle").setDoubleProperty("q", charge).setDoubleProperty("r", radius).setDoubleProperty("gamma", gamma);
}
SerializationNode& bonds = node.createChildNode("Bonds");
for (int i = 0; i < force.getNumBonds(); i++) {
int particle1, particle2;
double distance;
force.getBondParameters(i, particle1, particle2, distance);
bonds.createChildNode("Bond").setIntProperty("p1", particle1).setIntProperty("p2", particle2).setDoubleProperty("d", distance);
}
}
void* GBVIForceProxy::deserialize(const SerializationNode& node) const {
if (node.getIntProperty("version") != 1 && node.getIntProperty("version") != 2)
throw OpenMMException("Unsupported version number");
GBVIForce* force = new GBVIForce();
try {
force->setForceGroup(node.getIntProperty("forceGroup", 0));
force->setNonbondedMethod((GBVIForce::NonbondedMethod) node.getIntProperty("method"));
force->setCutoffDistance(node.getDoubleProperty("cutoff"));
force->setSoluteDielectric(node.getDoubleProperty("soluteDielectric"));
force->setSolventDielectric(node.getDoubleProperty("solventDielectric"));
if( node.getIntProperty("version") >= 2 ){
force->setBornRadiusScalingMethod( (GBVIForce::BornRadiusScalingMethod) node.getIntProperty( "scalingMethod"));
force->setQuinticLowerLimitFactor(node.getDoubleProperty("quinticLowerLimitFactor"));
force->setQuinticUpperBornRadiusLimit(node.getDoubleProperty("quinticUpperBornRadiusLimit"));
}
const SerializationNode& particles = node.getChildNode("Particles");
for (int i = 0; i < (int) particles.getChildren().size(); i++) {
const SerializationNode& particle = particles.getChildren()[i];
force->addParticle(particle.getDoubleProperty("q"), particle.getDoubleProperty("r"), particle.getDoubleProperty("gamma"));
}
const SerializationNode& bonds = node.getChildNode("Bonds");
for (int i = 0; i < (int) bonds.getChildren().size(); i++) {
const SerializationNode& bond = bonds.getChildren()[i];
force->addBond(bond.getIntProperty("p1"), bond.getIntProperty("p2"), bond.getDoubleProperty("d"));
}
}
catch (...) {
delete force;
throw;
}
return force;
}
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,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) 2010-2014 Stanford University and the Authors. * * Portions copyright (c) 2010-2015 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "openmm/BrownianIntegrator.h" #include "openmm/BrownianIntegrator.h"
#include "openmm/CMAPTorsionForce.h" #include "openmm/CMAPTorsionForce.h"
#include "openmm/CMMotionRemover.h" #include "openmm/CMMotionRemover.h"
#include "openmm/CompoundIntegrator.h"
#include "openmm/CustomAngleForce.h" #include "openmm/CustomAngleForce.h"
#include "openmm/CustomBondForce.h" #include "openmm/CustomBondForce.h"
#include "openmm/CustomCompoundBondForce.h" #include "openmm/CustomCompoundBondForce.h"
...@@ -44,7 +45,6 @@ ...@@ -44,7 +45,6 @@
#include "openmm/CustomNonbondedForce.h" #include "openmm/CustomNonbondedForce.h"
#include "openmm/CustomTorsionForce.h" #include "openmm/CustomTorsionForce.h"
#include "openmm/GBSAOBCForce.h" #include "openmm/GBSAOBCForce.h"
#include "openmm/GBVIForce.h"
#include "openmm/HarmonicAngleForce.h" #include "openmm/HarmonicAngleForce.h"
#include "openmm/HarmonicBondForce.h" #include "openmm/HarmonicBondForce.h"
#include "openmm/LangevinIntegrator.h" #include "openmm/LangevinIntegrator.h"
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
#include "openmm/serialization/AndersenThermostatProxy.h" #include "openmm/serialization/AndersenThermostatProxy.h"
#include "openmm/serialization/CMAPTorsionForceProxy.h" #include "openmm/serialization/CMAPTorsionForceProxy.h"
#include "openmm/serialization/CMMotionRemoverProxy.h" #include "openmm/serialization/CMMotionRemoverProxy.h"
#include "openmm/serialization/CompoundIntegratorProxy.h"
#include "openmm/serialization/CustomAngleForceProxy.h" #include "openmm/serialization/CustomAngleForceProxy.h"
#include "openmm/serialization/CustomBondForceProxy.h" #include "openmm/serialization/CustomBondForceProxy.h"
#include "openmm/serialization/CustomCompoundBondForceProxy.h" #include "openmm/serialization/CustomCompoundBondForceProxy.h"
...@@ -76,7 +77,6 @@ ...@@ -76,7 +77,6 @@
#include "openmm/serialization/CustomNonbondedForceProxy.h" #include "openmm/serialization/CustomNonbondedForceProxy.h"
#include "openmm/serialization/CustomTorsionForceProxy.h" #include "openmm/serialization/CustomTorsionForceProxy.h"
#include "openmm/serialization/GBSAOBCForceProxy.h" #include "openmm/serialization/GBSAOBCForceProxy.h"
#include "openmm/serialization/GBVIForceProxy.h"
#include "openmm/serialization/HarmonicAngleForceProxy.h" #include "openmm/serialization/HarmonicAngleForceProxy.h"
#include "openmm/serialization/HarmonicBondForceProxy.h" #include "openmm/serialization/HarmonicBondForceProxy.h"
#include "openmm/serialization/LangevinIntegratorProxy.h" #include "openmm/serialization/LangevinIntegratorProxy.h"
...@@ -112,6 +112,7 @@ extern "C" void registerSerializationProxies() { ...@@ -112,6 +112,7 @@ extern "C" void registerSerializationProxies() {
SerializationProxy::registerProxy(typeid(BrownianIntegrator), new BrownianIntegratorProxy()); SerializationProxy::registerProxy(typeid(BrownianIntegrator), new BrownianIntegratorProxy());
SerializationProxy::registerProxy(typeid(CMAPTorsionForce), new CMAPTorsionForceProxy()); SerializationProxy::registerProxy(typeid(CMAPTorsionForce), new CMAPTorsionForceProxy());
SerializationProxy::registerProxy(typeid(CMMotionRemover), new CMMotionRemoverProxy()); SerializationProxy::registerProxy(typeid(CMMotionRemover), new CMMotionRemoverProxy());
SerializationProxy::registerProxy(typeid(CompoundIntegrator), new CompoundIntegratorProxy());
SerializationProxy::registerProxy(typeid(Continuous1DFunction), new Continuous1DFunctionProxy()); SerializationProxy::registerProxy(typeid(Continuous1DFunction), new Continuous1DFunctionProxy());
SerializationProxy::registerProxy(typeid(Continuous2DFunction), new Continuous2DFunctionProxy()); SerializationProxy::registerProxy(typeid(Continuous2DFunction), new Continuous2DFunctionProxy());
SerializationProxy::registerProxy(typeid(Continuous3DFunction), new Continuous3DFunctionProxy()); SerializationProxy::registerProxy(typeid(Continuous3DFunction), new Continuous3DFunctionProxy());
...@@ -129,7 +130,6 @@ extern "C" void registerSerializationProxies() { ...@@ -129,7 +130,6 @@ extern "C" void registerSerializationProxies() {
SerializationProxy::registerProxy(typeid(Discrete2DFunction), new Discrete2DFunctionProxy()); SerializationProxy::registerProxy(typeid(Discrete2DFunction), new Discrete2DFunctionProxy());
SerializationProxy::registerProxy(typeid(Discrete3DFunction), new Discrete3DFunctionProxy()); SerializationProxy::registerProxy(typeid(Discrete3DFunction), new Discrete3DFunctionProxy());
SerializationProxy::registerProxy(typeid(GBSAOBCForce), new GBSAOBCForceProxy()); SerializationProxy::registerProxy(typeid(GBSAOBCForce), new GBSAOBCForceProxy());
SerializationProxy::registerProxy(typeid(GBVIForce), new GBVIForceProxy());
SerializationProxy::registerProxy(typeid(HarmonicAngleForce), new HarmonicAngleForceProxy()); SerializationProxy::registerProxy(typeid(HarmonicAngleForce), new HarmonicAngleForceProxy());
SerializationProxy::registerProxy(typeid(HarmonicBondForce), new HarmonicBondForceProxy()); SerializationProxy::registerProxy(typeid(HarmonicBondForce), new HarmonicBondForceProxy());
SerializationProxy::registerProxy(typeid(LangevinIntegrator), new LangevinIntegratorProxy()); SerializationProxy::registerProxy(typeid(LangevinIntegrator), new LangevinIntegratorProxy());
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,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) 2010 Stanford University and the Authors. * * Portions copyright (c) 2010-2015 Stanford University and the Authors. *
* Authors: Peter Eastman, Yutong Zhao * * Authors: Peter Eastman, Yutong Zhao *
* Contributors: * * Contributors: *
* * * *
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "openmm/internal/AssertionUtilities.h" #include "openmm/internal/AssertionUtilities.h"
#include "openmm/BrownianIntegrator.h" #include "openmm/BrownianIntegrator.h"
#include "openmm/CompoundIntegrator.h"
#include "openmm/CustomIntegrator.h" #include "openmm/CustomIntegrator.h"
#include "openmm/LangevinIntegrator.h" #include "openmm/LangevinIntegrator.h"
#include "openmm/VariableLangevinIntegrator.h" #include "openmm/VariableLangevinIntegrator.h"
...@@ -185,6 +186,29 @@ void testSerializeCustomIntegrator() { ...@@ -185,6 +186,29 @@ void testSerializeCustomIntegrator() {
delete intg2; delete intg2;
} }
void testSerializeCompoundIntegrator() {
CompoundIntegrator integ;
integ.addIntegrator(new LangevinIntegrator(372.4, 1.234, 0.0018));
integ.addIntegrator(new VerletIntegrator(0.002));
integ.setCurrentIntegrator(1);
stringstream ss;
XmlSerializer::serialize<Integrator>(&integ, "CompoundIntegrator", ss);
CompoundIntegrator *integ2 = dynamic_cast<CompoundIntegrator*>(XmlSerializer::deserialize<Integrator>(ss));
ASSERT_EQUAL(integ.getCurrentIntegrator(), integ2->getCurrentIntegrator());
LangevinIntegrator& langevin1 = dynamic_cast<LangevinIntegrator&>(integ.getIntegrator(0));
LangevinIntegrator& langevin2 = dynamic_cast<LangevinIntegrator&>(integ2->getIntegrator(0));
ASSERT_EQUAL(langevin1.getConstraintTolerance(), langevin2.getConstraintTolerance());
ASSERT_EQUAL(langevin1.getStepSize(), langevin2.getStepSize());
ASSERT_EQUAL(langevin1.getTemperature(), langevin2.getTemperature());
ASSERT_EQUAL(langevin1.getFriction(), langevin2.getFriction());
ASSERT_EQUAL(langevin1.getRandomNumberSeed(), langevin2.getRandomNumberSeed());
VerletIntegrator& verlet1 = dynamic_cast<VerletIntegrator&>(integ.getIntegrator(1));
VerletIntegrator& verlet2 = dynamic_cast<VerletIntegrator&>(integ2->getIntegrator(1));
ASSERT_EQUAL(verlet1.getConstraintTolerance(), verlet2.getConstraintTolerance());
ASSERT_EQUAL(verlet1.getStepSize(), verlet2.getStepSize());
delete integ2;
}
int main() { int main() {
try { try {
testSerializeBrownianIntegrator(); testSerializeBrownianIntegrator();
...@@ -193,6 +217,7 @@ int main() { ...@@ -193,6 +217,7 @@ int main() {
testSerializeVariableLangevinIntegrator(); testSerializeVariableLangevinIntegrator();
testSerializeVariableVerletIntegrator(); testSerializeVariableVerletIntegrator();
testSerializeLangevinIntegrator(); testSerializeLangevinIntegrator();
testSerializeCompoundIntegrator();
} }
catch(const exception& e) { catch(const exception& e) {
return 1; return 1;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,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-2009 Stanford University and the Authors. * * Portions copyright (c) 2015 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -29,214 +29,194 @@ ...@@ -29,214 +29,194 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. * * USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
/**
* This tests the reference implementation of GBVIForce.
*/
#include "openmm/internal/AssertionUtilities.h" #include "openmm/internal/AssertionUtilities.h"
#include "openmm/BrownianIntegrator.h"
#include "openmm/CompoundIntegrator.h"
#include "openmm/Context.h" #include "openmm/Context.h"
#include "ReferencePlatform.h"
#include "openmm/HarmonicBondForce.h" #include "openmm/HarmonicBondForce.h"
#include "openmm/GBVIForce.h"
#include "openmm/GBSAOBCForce.h"
#include "openmm/System.h"
#include "openmm/LangevinIntegrator.h" #include "openmm/LangevinIntegrator.h"
#include "openmm/NonbondedForce.h" #include "openmm/System.h"
#include "openmm/VerletIntegrator.h"
#include "SimTKOpenMMRealType.h" #include "SimTKOpenMMRealType.h"
#include "sfmt/SFMT.h"
#include <iostream> #include <iostream>
#include <vector> #include <vector>
using namespace OpenMM; using namespace OpenMM;
using namespace std; using namespace std;
ReferencePlatform platform;
const double TOL = 1e-5; const double TOL = 1e-5;
void testSingleParticle() { void testChangingIntegrator() {
System system; System system;
system.addParticle(2.0); system.addParticle(2.0);
LangevinIntegrator integrator(0, 0.1, 0.01); system.addParticle(2.0);
GBVIForce* forceField = new GBVIForce();
double charge = -1.0;
double radius = 0.15;
double gamma = 1.0;
forceField->addParticle(charge, radius, gamma);
system.addForce(forceField);
ASSERT(!forceField->usesPeriodicBoundaryConditions());
ASSERT(!system.usesPeriodicBoundaryConditions());
Context context(system, integrator, platform);
vector<Vec3> positions(1);
positions[0] = Vec3(0, 0, 0);
context.setPositions(positions);
State state = context.getState(State::Energy);
double bornRadius = radius;
double eps0 = EPSILON0;
double tau = (1.0/forceField->getSoluteDielectric()-1.0/forceField->getSolventDielectric());
double bornEnergy = (-charge*charge/(8*PI_M*eps0))*tau/bornRadius;
double nonpolarEnergy = -gamma*tau*std::pow(radius/bornRadius, 3.0);
double expectedE = (bornEnergy+nonpolarEnergy);
double obtainedE = state.getPotentialEnergy();
double diff = fabs((obtainedE - expectedE)/expectedE);
ASSERT_EQUAL_TOL((bornEnergy+nonpolarEnergy), state.getPotentialEnergy(), 0.01);
}
void testEnergyEthane(int applyBornRadiiScaling) {
const int numParticles = 8;
System system;
LangevinIntegrator integrator(0, 0.1, 0.01);
// harmonic bond
double C_HBondDistance = 0.1097;
double C_CBondDistance = 0.1504;
HarmonicBondForce* bonds = new HarmonicBondForce(); HarmonicBondForce* bonds = new HarmonicBondForce();
bonds->addBond(0, 1, C_HBondDistance, 0.0); bonds->addBond(0, 1, 1.5, 1);
bonds->addBond(2, 1, C_HBondDistance, 0.0);
bonds->addBond(3, 1, C_HBondDistance, 0.0);
bonds->addBond(1, 4, C_CBondDistance, 0.0);
bonds->addBond(5, 4, C_HBondDistance, 0.0);
bonds->addBond(6, 4, C_HBondDistance, 0.0);
bonds->addBond(7, 4, C_HBondDistance, 0.0);
system.addForce(bonds); system.addForce(bonds);
CompoundIntegrator integrator;
double C_radius, C_gamma, C_charge, H_radius, H_gamma, H_charge; integrator.addIntegrator(new VerletIntegrator(0.01));
integrator.addIntegrator(new LangevinIntegrator(300.0, 10.0, 0.011));
int AM1_BCC = 1; integrator.addIntegrator(new BrownianIntegrator(300.0, 10.0, 0.012));
H_charge = -0.053; Context context(system, integrator, platform);
C_charge = -3.0*H_charge; ASSERT_EQUAL(0, integrator.getCurrentIntegrator());
if (AM1_BCC) { vector<Vec3> positions(2);
C_radius = 0.180; positions[0] = Vec3(-1, 0, 0);
C_gamma = -0.2863; positions[1] = Vec3(1, 0, 0);
H_radius = 0.125; for (int iteration = 0; iteration < 2; ++iteration) {
H_gamma = 0.2437; context.setPositions(positions);
}
else { // First integrate with the Verlet integrator and compare it to the analytical solution.
C_radius = 0.215;
C_gamma = -1.1087; const double freq = 1.0;
H_radius = 0.150; State state = context.getState(State::Energy);
H_gamma = 0.1237; const double initialEnergy = state.getKineticEnergy()+state.getPotentialEnergy();
for (int i = 0; i < 100; ++i) {
state = context.getState(State::Positions | State::Velocities | State::Energy);
double time = state.getTime();
double expectedDist = 1.5+0.5*std::cos(freq*time);
ASSERT_EQUAL_VEC(Vec3(-0.5*expectedDist, 0, 0), state.getPositions()[0], 0.02);
ASSERT_EQUAL_VEC(Vec3(0.5*expectedDist, 0, 0), state.getPositions()[1], 0.02);
double expectedSpeed = -0.5*freq*std::sin(freq*time);
ASSERT_EQUAL_VEC(Vec3(-0.5*expectedSpeed, 0, 0), state.getVelocities()[0], 0.02);
ASSERT_EQUAL_VEC(Vec3(0.5*expectedSpeed, 0, 0), state.getVelocities()[1], 0.02);
double energy = state.getKineticEnergy()+state.getPotentialEnergy();
ASSERT_EQUAL_TOL(initialEnergy, energy, 0.01);
integrator.step(1);
}
ASSERT_EQUAL_TOL(100*0.01, context.getState(0).getTime(), 1e-5);
// Switch to the Langevin integrator and make sure that it heats up.
integrator.setCurrentIntegrator(1);
integrator.step(100);
double ke = 0.0;
for (int i = 0; i < 1000; ++i) {
integrator.step(10);
state = context.getState(State::Energy);
ke += state.getKineticEnergy();
}
double expectedKE = 0.5*2*3*BOLTZ*300.0;
ASSERT_USUALLY_EQUAL_TOL(expectedKE, ke/1000, 0.1);
ASSERT_EQUAL_TOL(100*0.01+10100*0.011, context.getState(0).getTime(), 1e-5);
// Now reinitialize the context and repeat all of these tests to make sure that works correctly.
context.reinitialize();
integrator.setCurrentIntegrator(0);
} }
}
NonbondedForce* nonbonded = new NonbondedForce(); void testChangingParameters() {
nonbonded->setNonbondedMethod(NonbondedForce::NoCutoff); System system;
system.addParticle(1.0);
GBVIForce* forceField = new GBVIForce(); CompoundIntegrator integrator;
if (applyBornRadiiScaling) { integrator.addIntegrator(new VerletIntegrator(0.01));
forceField->setBornRadiusScalingMethod(GBVIForce::QuinticSpline); integrator.addIntegrator(new LangevinIntegrator(300.0, 10.0, 0.02));
integrator.addIntegrator(new BrownianIntegrator(300.0, 10.0, 0.03));
// Try getting and setting the step size for different component integrators.
for (int i = 0; i < 3; i++) {
integrator.setCurrentIntegrator(i);
ASSERT_EQUAL_TOL(0.01*(i+1), integrator.getStepSize(), 1e-7);
} }
else { for (int i = 0; i < 3; i++) {
forceField->setBornRadiusScalingMethod(GBVIForce::NoScaling); integrator.setCurrentIntegrator(i);
integrator.setStepSize(0.02*(i+1));
ASSERT_EQUAL_TOL(0.02*(i+1), integrator.getStepSize(), 1e-7);
} }
for (int i = 0; i < numParticles; i++) { for (int i = 0; i < 3; i++) {
system.addParticle(1.0); integrator.setCurrentIntegrator(i);
forceField->addParticle(H_charge, H_radius, H_gamma); ASSERT_EQUAL_TOL(0.02*(i+1), integrator.getStepSize(), 1e-7);
nonbonded->addParticle( H_charge, H_radius, 0.0);
} }
forceField->setParticleParameters(1, C_charge, C_radius, C_gamma);
forceField->setParticleParameters(4, C_charge, C_radius, C_gamma);
nonbonded->setParticleParameters( 1, C_charge, C_radius, 0.0);
nonbonded->setParticleParameters( 4, C_charge, C_radius, 0.0);
forceField->addBond(0, 1, C_HBondDistance);
forceField->addBond(2, 1, C_HBondDistance);
forceField->addBond(3, 1, C_HBondDistance);
forceField->addBond(1, 4, C_CBondDistance);
forceField->addBond(5, 4, C_HBondDistance);
forceField->addBond(6, 4, C_HBondDistance);
forceField->addBond(7, 4, C_HBondDistance);
std::vector<pair<int, int> > bondExceptions;
std::vector<double> bondDistances;
bondExceptions.push_back(pair<int, int>(0, 1));
bondDistances.push_back(C_HBondDistance);
bondExceptions.push_back(pair<int, int>(2, 1));
bondDistances.push_back(C_HBondDistance);
bondExceptions.push_back(pair<int, int>(3, 1)); // Try getting and setting the constraint tolerance for different component integrators.
bondDistances.push_back(C_HBondDistance);
bondExceptions.push_back(pair<int, int>(1, 4)); for (int i = 0; i < 3; i++) {
bondDistances.push_back(C_CBondDistance); integrator.setCurrentIntegrator(i);
ASSERT_EQUAL_TOL(1e-5, integrator.getConstraintTolerance(), 1e-7);
bondExceptions.push_back(pair<int, int>(5, 4)); }
bondDistances.push_back(C_HBondDistance); for (int i = 0; i < 3; i++) {
integrator.setCurrentIntegrator(i);
bondExceptions.push_back(pair<int, int>(6, 4)); integrator.setConstraintTolerance(1e-4*(i+1));
bondDistances.push_back(C_HBondDistance); ASSERT_EQUAL_TOL(1e-4*(i+1), integrator.getConstraintTolerance(), 1e-7);
}
bondExceptions.push_back(pair<int, int>(7, 4)); for (int i = 0; i < 3; i++) {
bondDistances.push_back(C_HBondDistance); integrator.setCurrentIntegrator(i);
ASSERT_EQUAL_TOL(1e-4*(i+1), integrator.getConstraintTolerance(), 1e-7);
nonbonded->createExceptionsFromBonds(bondExceptions, 0.0, 0.0); }
}
system.addForce(forceField);
system.addForce(nonbonded);
void testDifferentStepSizes() {
System system;
system.addParticle(2.0);
system.addParticle(2.0);
HarmonicBondForce* bonds = new HarmonicBondForce();
bonds->addBond(0, 1, 1.5, 1);
system.addForce(bonds);
CompoundIntegrator integrator;
integrator.addIntegrator(new VerletIntegrator(0.005));
integrator.addIntegrator(new VerletIntegrator(0.01));
Context context(system, integrator, platform); Context context(system, integrator, platform);
ASSERT_EQUAL(0, integrator.getCurrentIntegrator());
vector<Vec3> positions(numParticles); vector<Vec3> positions(2);
positions[0] = Vec3(0.5480, 1.7661, 0.0000); positions[0] = Vec3(-1, 0, 0);
positions[1] = Vec3(0.7286, 0.8978, 0.6468); positions[1] = Vec3(1, 0, 0);
positions[2] = Vec3(0.4974, 0.0000, 0.0588);
positions[3] = Vec3(0.0000, 0.9459, 1.4666);
positions[4] = Vec3(2.1421, 0.8746, 1.1615);
positions[5] = Vec3(2.3239, 0.0050, 1.8065);
positions[6] = Vec3(2.8705, 0.8295, 0.3416);
positions[7] = Vec3(2.3722, 1.7711, 1.7518);
context.setPositions(positions); context.setPositions(positions);
State state = context.getState(State::Forces | State::Energy); // Integrate with the first Verlet integrator and compare it to the analytical solution.
// Take a small step in the direction of the energy gradient. const double freq = 1.0;
double expectedTime = 0;
double norm = 0.0; for (int i = 0; i < 100; ++i) {
double forceSum[3] = { 0.0, 0.0, 0.0 }; State state = context.getState(State::Positions);
for (int i = 0; i < numParticles; ++i) { double time = state.getTime();
Vec3 f = state.getForces()[i]; ASSERT_EQUAL_TOL(expectedTime, time, 1e-5);
norm += f[0]*f[0] + f[1]*f[1] + f[2]*f[2]; double expectedDist = 1.5+0.5*std::cos(freq*time);
forceSum[0] += f[0]; ASSERT_EQUAL_VEC(Vec3(-0.5*expectedDist, 0, 0), state.getPositions()[0], 0.02);
forceSum[1] += f[1]; ASSERT_EQUAL_VEC(Vec3(0.5*expectedDist, 0, 0), state.getPositions()[1], 0.02);
forceSum[2] += f[2]; integrator.step(1);
expectedTime += 0.005;
} }
norm = std::sqrt(norm);
const double delta = 1e-4;
double step = delta/norm;
for (int i = 0; i < numParticles; ++i) {
Vec3 p = positions[i];
Vec3 f = state.getForces()[i];
positions[i] = Vec3(p[0]-f[0]*step, p[1]-f[1]*step, p[2]-f[2]*step);
}
context.setPositions(positions);
State state2 = context.getState(State::Energy); // Now switch to the second Verlet integrator which has a different step size.
// See whether the potential energy changed by the expected amount. integrator.setCurrentIntegrator(1);
for (int i = 0; i < 100; ++i) {
State state = context.getState(State::Positions);
double time = state.getTime();
ASSERT_EQUAL_TOL(expectedTime, time, 1e-5);
double expectedDist = 1.5+0.5*std::cos(freq*time);
ASSERT_EQUAL_VEC(Vec3(-0.5*expectedDist, 0, 0), state.getPositions()[0], 0.02);
ASSERT_EQUAL_VEC(Vec3(0.5*expectedDist, 0, 0), state.getPositions()[1], 0.02);
integrator.step(1);
expectedTime += 0.01;
}
ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state.getPotentialEnergy())/delta, 0.01) // Finally, switch back to the first one again.
integrator.setCurrentIntegrator(0);
for (int i = 0; i < 100; ++i) {
State state = context.getState(State::Positions);
double time = state.getTime();
ASSERT_EQUAL_TOL(expectedTime, time, 1e-5);
double expectedDist = 1.5+0.5*std::cos(freq*time);
ASSERT_EQUAL_VEC(Vec3(-0.5*expectedDist, 0, 0), state.getPositions()[0], 0.02);
ASSERT_EQUAL_VEC(Vec3(0.5*expectedDist, 0, 0), state.getPositions()[1], 0.02);
integrator.step(1);
expectedTime += 0.005;
}
} }
int main() { void runPlatformTests();
int main(int argc, char* argv[]) {
try { try {
testSingleParticle(); initializeTests(argc, argv);
testEnergyEthane(0); testChangingIntegrator();
testEnergyEthane(1); testChangingParameters();
testDifferentStepSizes();
runPlatformTests();
} }
catch(const exception& e) { catch(const exception& e) {
cout << "exception: " << e.what() << endl; cout << "exception: " << e.what() << endl;
......
...@@ -167,6 +167,38 @@ void testPeriodic() { ...@@ -167,6 +167,38 @@ void testPeriodic() {
} }
} }
void testZeroPeriodicDistance() {
Vec3 vx(5, 0, 0);
Vec3 vy(0, 6, 0);
Vec3 vz(1, 2, 7);
double x0 = 51, y0 = -17, z0 = 11.2;
System system;
system.setDefaultPeriodicBoxVectors(vx, vy, vz);
system.addParticle(1.0);
CustomExternalForce* force = new CustomExternalForce("periodicdistance(x, y, z, x0, y0, z0)^2");
force->addPerParticleParameter("x0");
force->addPerParticleParameter("y0");
force->addPerParticleParameter("z0");
vector<double> params(3);
params[0] = x0;
params[1] = y0;
params[2] = z0;
force->addParticle(0, params);
system.addForce(force);
ASSERT(force->usesPeriodicBoundaryConditions());
ASSERT(system.usesPeriodicBoundaryConditions());
VerletIntegrator integrator(0.01);
Context context(system, integrator, platform);
vector<Vec3> positions(1);
positions[0] = Vec3(x0, y0, z0);
context.setPositions(positions);
State state = context.getState(State::Positions | State::Forces | State::Energy);
vector<Vec3> forces = state.getForces();
for (int i = 0; i < 3; i++)
ASSERT_EQUAL(forces[0][i], forces[0][i]);
}
void testIllegalVariable() { void testIllegalVariable() {
System system; System system;
system.addParticle(1.0); system.addParticle(1.0);
...@@ -192,6 +224,7 @@ int main(int argc, char* argv[]) { ...@@ -192,6 +224,7 @@ int main(int argc, char* argv[]) {
testForce(); testForce();
testManyParameters(); testManyParameters();
testPeriodic(); testPeriodic();
testZeroPeriodicDistance();
testIllegalVariable(); testIllegalVariable();
runPlatformTests(); runPlatformTests();
} }
......
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
* 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) 2010-2014 Stanford University and the Authors. * * Portions copyright (c) 2010-2015 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Robert McGibbon *
* Contributors: * * Contributors: *
* * * *
* Permission is hereby granted, free of charge, to any person obtaining a * * Permission is hereby granted, free of charge, to any person obtaining a *
...@@ -30,74 +30,70 @@ ...@@ -30,74 +30,70 @@
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
#include "openmm/internal/AssertionUtilities.h" #include "openmm/internal/AssertionUtilities.h"
#include "openmm/GBVIForce.h" #include "openmm/Context.h"
#include "openmm/serialization/XmlSerializer.h" #include "openmm/NonbondedForce.h"
#include "openmm/Platform.h"
#include "openmm/VerletIntegrator.h"
#include "sfmt/SFMT.h"
#include <iostream> #include <iostream>
#include <sstream>
using namespace OpenMM; using namespace OpenMM;
using namespace std; using namespace std;
void testSerialization() { void testTruncatedOctahedron() {
// Create a Force. const int numMolecules = 50;
const int numParticles = numMolecules*2;
GBVIForce force; const float cutoff = 2.0;
force.setForceGroup(3); Vec3 a(6.7929, 0, 0);
force.setNonbondedMethod(GBVIForce::CutoffPeriodic); Vec3 b(-2.264163559406279, 6.404455775962287, 0);
force.setBornRadiusScalingMethod(GBVIForce::QuinticSpline); Vec3 c(-2.264163559406279, -3.2019384603140684, 5.54658849047036);
force.setQuinticLowerLimitFactor(0.123);
force.setQuinticUpperBornRadiusLimit(5.123); System system;
force.setCutoffDistance(2.0); system.setDefaultPeriodicBoxVectors(a, b, c);
force.setSoluteDielectric(5.1); NonbondedForce* force = new NonbondedForce();
force.setSolventDielectric(50.0); OpenMM_SFMT::SFMT sfmt;
force.addParticle(1, 0.1, 0.01); init_gen_rand(0, sfmt);
force.addParticle(0.5, 0.2, 0.02); vector<Vec3> positions(numParticles);
force.addParticle(-0.5, 0.3, 0.03);
force.addBond(0, 1, 2.0); force->setCutoffDistance(cutoff);
force.addBond(3, 5, 1.2); force->setNonbondedMethod(NonbondedForce::CutoffPeriodic);
// Serialize and then deserialize it. for (int i = 0; i < numMolecules; i++) {
system.addParticle(1.0);
stringstream buffer; system.addParticle(1.0);
XmlSerializer::serialize<GBVIForce>(&force, "Force", buffer); force->addParticle(-1, 0.2, 0.2);
GBVIForce* copy = XmlSerializer::deserialize<GBVIForce>(buffer); force->addParticle(1, 0.2, 0.2);
positions[2*i] = a*(5*genrand_real2(sfmt)-2) + b*(5*genrand_real2(sfmt)-2) + c*(5*genrand_real2(sfmt)-2);
// Compare the two forces to see if they are identical. positions[2*i+1] = positions[2*i] + Vec3(1.0, 0.0, 0.0);
system.addConstraint(2*i, 2*i+1, 1.0);
GBVIForce& force2 = *copy;
ASSERT_EQUAL(force.getForceGroup(), force2.getForceGroup());
ASSERT_EQUAL(force.getNonbondedMethod(), force2.getNonbondedMethod());
ASSERT_EQUAL(force.getCutoffDistance(), force2.getCutoffDistance());
ASSERT_EQUAL(force.getSoluteDielectric(), force2.getSoluteDielectric());
ASSERT_EQUAL(force.getSolventDielectric(), force2.getSolventDielectric());
ASSERT_EQUAL(force.getNumParticles(), force2.getNumParticles());
ASSERT_EQUAL(force.getQuinticUpperBornRadiusLimit(), force2.getQuinticUpperBornRadiusLimit());
ASSERT_EQUAL(force.getQuinticLowerLimitFactor(), force2.getQuinticLowerLimitFactor());
ASSERT_EQUAL(force.getBornRadiusScalingMethod(), force2.getBornRadiusScalingMethod());
for (int i = 0; i < force.getNumParticles(); i++) {
double charge1, radius1, scale1;
double charge2, radius2, scale2;
force.getParticleParameters(i, charge1, radius1, scale1);
force2.getParticleParameters(i, charge2, radius2, scale2);
ASSERT_EQUAL(charge1, charge2);
ASSERT_EQUAL(radius1, radius2);
ASSERT_EQUAL(scale1, scale2);
} }
ASSERT_EQUAL(force.getNumBonds(), force2.getNumBonds()); system.addForce(force);
for (int i = 0; i < force.getNumBonds(); i++) {
int a1, a2, b1, b2; VerletIntegrator integrator(0.01);
double da, db; Context context(system, integrator, Platform::getPlatformByName("Reference"));
force.getBondParameters(i, a1, a2, da); context.setPositions(positions);
force2.getBondParameters(i, b1, b2, db); State initialState = context.getState(State::Positions | State::Energy, true);
ASSERT_EQUAL(a1, b1); for (int i = 0; i < numMolecules; i++) {
ASSERT_EQUAL(a2, b2); Vec3 center = (initialState.getPositions()[2*i]+initialState.getPositions()[2*i+1])*0.5;
ASSERT_EQUAL(da, db); ASSERT(center[0] >= 0.0);
ASSERT(center[1] >= 0.0);
ASSERT(center[2] >= 0.0);
ASSERT(center[0] <= a[0]);
ASSERT(center[1] <= b[1]);
ASSERT(center[2] <= c[2]);
} }
double initialEnergy = initialState.getPotentialEnergy();
context.setState(initialState);
State finalState = context.getState(State::Positions | State::Energy, true);
double finalEnergy = finalState.getPotentialEnergy();
ASSERT_EQUAL_TOL(initialEnergy, finalEnergy, 1e-4);
} }
int main() { int main(int argc, char* argv[]) {
try { try {
testSerialization(); testTruncatedOctahedron();
} }
catch(const exception& e) { catch(const exception& e) {
cout << "exception: " << e.what() << endl; cout << "exception: " << e.what() << endl;
......
...@@ -255,7 +255,7 @@ void testForce(int numParticles, NonbondedForce::NonbondedMethod method, GBSAOBC ...@@ -255,7 +255,7 @@ void testForce(int numParticles, NonbondedForce::NonbondedMethod method, GBSAOBC
State state2 = context.getState(State::Energy); State state2 = context.getState(State::Energy);
context.setPositions(positions3); context.setPositions(positions3);
State state3 = context.getState(State::Energy); State state3 = context.getState(State::Energy);
ASSERT_EQUAL_TOL(norm, (state2.getPotentialEnergy()-state3.getPotentialEnergy())/delta, 1e-2) ASSERT_EQUAL_TOL(state2.getPotentialEnergy(), state3.getPotentialEnergy()+norm*delta, 1e-5)
} }
} }
......
...@@ -251,8 +251,8 @@ void testRandomSeed() { ...@@ -251,8 +251,8 @@ void testRandomSeed() {
for (int i = 0; i < numParticles; i++) { for (int i = 0; i < numParticles; i++) {
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
ASSERT(state1.getPositions()[i][j] == state2.getPositions()[i][j]); ASSERT_EQUAL_TOL(state1.getPositions()[i][j], state2.getPositions()[i][j], 1e-6);
ASSERT(state3.getPositions()[i][j] == state4.getPositions()[i][j]); ASSERT_EQUAL_TOL(state3.getPositions()[i][j], state4.getPositions()[i][j], 1e-6);
ASSERT(state1.getPositions()[i][j] != state3.getPositions()[i][j]); ASSERT(state1.getPositions()[i][j] != state3.getPositions()[i][j]);
} }
} }
......
...@@ -78,7 +78,7 @@ void testLargeSystem() { ...@@ -78,7 +78,7 @@ void testLargeSystem() {
const int numParticles = numMolecules*2; const int numParticles = numMolecules*2;
const double cutoff = 2.0; const double cutoff = 2.0;
const double boxSize = 4.0; const double boxSize = 4.0;
const double tolerance = 10; const double tolerance = 15;
System system; System system;
system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize)); system.setDefaultPeriodicBoxVectors(Vec3(boxSize, 0, 0), Vec3(0, boxSize, 0), Vec3(0, 0, boxSize));
NonbondedForce* nonbonded = new NonbondedForce(); NonbondedForce* nonbonded = new NonbondedForce();
......
...@@ -149,6 +149,8 @@ void testMathFunctions() { ...@@ -149,6 +149,8 @@ void testMathFunctions() {
ASSERT_VEC4_EQUAL(max(f1, f2), 1.1, 1.9, 1.3, -3.8); ASSERT_VEC4_EQUAL(max(f1, f2), 1.1, 1.9, 1.3, -3.8);
ASSERT_VEC4_EQUAL(sqrt(fvec4(1.5, 3.1, 4.0, 15.0)), sqrt(1.5), sqrt(3.1), sqrt(4.0), sqrt(15.0)); ASSERT_VEC4_EQUAL(sqrt(fvec4(1.5, 3.1, 4.0, 15.0)), sqrt(1.5), sqrt(3.1), sqrt(4.0), sqrt(15.0));
ASSERT_VEC4_EQUAL(rsqrt(fvec4(1.5, 3.1, 4.0, 15.0)), 1.0/sqrt(1.5), 1.0/sqrt(3.1), 1.0/sqrt(4.0), 1.0/sqrt(15.0)); ASSERT_VEC4_EQUAL(rsqrt(fvec4(1.5, 3.1, 4.0, 15.0)), 1.0/sqrt(1.5), 1.0/sqrt(3.1), 1.0/sqrt(4.0), 1.0/sqrt(15.0));
ASSERT_VEC4_EQUAL(exp(fvec4(-2.1, -0.5, 1.5, 3.1)), expf(-2.1), expf(-0.5), expf(1.5), expf(3.1));
ASSERT_VEC4_EQUAL(log(fvec4(1.5, 3.1, 4.0, 15.0)), logf(1.5), logf(3.1), logf(4.0), logf(15.0));
ASSERT_EQUAL_TOL(f1[0]*f2[0]+f1[1]*f2[1]+f1[2]*f2[2], dot3(f1, f2), 1e-6); ASSERT_EQUAL_TOL(f1[0]*f2[0]+f1[1]*f2[1]+f1[2]*f2[2], dot3(f1, f2), 1e-6);
ASSERT_EQUAL_TOL(f1[0]*f2[0]+f1[1]*f2[1]+f1[2]*f2[2]+f1[3]*f2[3], dot4(f1, f2), 1e-6); ASSERT_EQUAL_TOL(f1[0]*f2[0]+f1[1]*f2[1]+f1[2]*f2[2]+f1[3]*f2[3], dot4(f1, f2), 1e-6);
ASSERT(any(f1 > 0.5)); ASSERT(any(f1 > 0.5));
......
...@@ -69,6 +69,7 @@ foreach(SUBDIR ${SUBDIRS}) ...@@ -69,6 +69,7 @@ foreach(SUBDIR ${SUBDIRS})
"${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/*.str" "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/*.str"
"${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/*psf" "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/*psf"
"${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/charmm22.*" "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/charmm22.*"
"${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIR}/par*.inp"
) )
foreach(file ${STAGING_INPUT_FILES1}) foreach(file ${STAGING_INPUT_FILES1})
set(STAGING_INPUT_FILES ${STAGING_INPUT_FILES} "${file}") set(STAGING_INPUT_FILES ${STAGING_INPUT_FILES} "${file}")
......
from __future__ import print_function from __future__ import print_function
import re
import sys import sys
import textwrap
from inspect import cleandoc
from numpydoc.docscrape import NumpyDocString
# Doxygen does a bad job of generating documentation based on docstrings. This script is run as a filter # Doxygen does a bad job of generating documentation based on docstrings.
# on each file, and converts the docstrings into Doxygen style comments so we get better documentation. # This script is run as a filter
# on each file, and converts the docstrings into Doxygen style comments
# so we get better documentation.
input = open(sys.argv[1]) input = open(sys.argv[1])
while True: while True:
line = input.readline() line = input.readline()
if len(line) == 0: if len(line) == 0:
...@@ -15,46 +24,57 @@ while True: ...@@ -15,46 +24,57 @@ while True:
split = stripped.split() split = stripped.split()
if split[0] == 'class' and split[1][0].islower(): if split[0] == 'class' and split[1][0].islower():
# Classes that start with a lowercase letter were defined by SWIG. We want to hide them. # Classes that start with a lowercase letter were defined by SWIG. We want to hide them.
print("%s## @private" % prefix) print("%s## @private" % prefix, end='')
if split[1][0] == '_' and split[1][1] != '_': if split[1][0] == '_' and split[1][1] != '_':
# Names starting with a single _ are assumed to be private. # Names starting with a single _ are assumed to be private.
print("%s## @private" % prefix) print("%s## @private" % prefix, end='')
# We're at the start of a class or function definition. Find all lines that contain the declaration. # We're at the start of a class or function definition. Find all lines that contain the declaration.
declaration = line declaration = line
while len(line) > 0 and line.find(':') == -1: while len(line) > 0 and line.find(':') == -1:
line = input.readline() line = input.readline()
declaration += line declaration += line
# Now look for a docstring. # Now look for a docstring.
docstringlines = []
docstrings = []
line = input.readline() line = input.readline()
stripped = line.lstrip() l = line.strip()
if stripped.startswith('"""'): if l.startswith('"""') or l.startswith("'''"):
line = stripped[3:] if l.count('"""') == 2 or l.count("'''") == 2:
readingParameters = False docstringlines.append(l[3:-3])
while line.find('"""') == -1: else:
docstrings.append(line) docstringlines.append(l[3:])
line = input.readline() line = input.readline()
if line.strip() == 'Parameters:': l = line.strip()
readingParameters = True while l.find('"""') == -1 and l.find("'''") == -1:
docstringlines.append(line.rstrip())
line = input.readline() line = input.readline()
stripped = line.lstrip() l = line.strip()
if readingParameters and stripped.startswith('- '): if line.rstrip().endswith('"""') or line.rstrip().endswith("'''"):
line = "@param %s" % stripped[2:] # last line
elif stripped.startswith('Returns:'): docstringlines.append(line.rstrip()[:-3])
line = "@return %s" % stripped[8:]
line = line[:line.find('"""')] docstring = NumpyDocString(cleandoc('\n'.join(docstringlines)))
docstrings.append(line) # print(docstringlines)
# Print out the docstring in Doxygen syntax, followed by the declaration. # Print out the docstring in Doxygen syntax, followed by the declaration.
for line in docstring['Summary']:
for s in docstrings: print('{prefix}## {line}'.format(prefix=prefix, line=line))
print("%s##%s" % (prefix, s.strip())) if len(docstring['Extended Summary']) > 0:
print(declaration) print('{prefix}##'.format(prefix=prefix))
if len(docstrings) == 0: for line in docstring['Extended Summary']:
print(line) print('{prefix}## {line}'.format(prefix=prefix, line=line.strip()))
print('{prefix}##'.format(prefix=prefix))
for name, type, descr in docstring['Parameters']:
print('{prefix}## @param {name} ({type}) {descr}'.format(prefix=prefix, type=type, name=name, descr=' '.join(descr)))
for name, type, descr in docstring['Returns']:
if type == '':
type = name
print('{prefix}## @return ({type}) {descr}'.format(prefix=prefix, type=type, name=name, descr=' '.join(descr)))
print(declaration, end='')
if len(docstringlines) == 0:
print(line, end='')
else: else:
print(line) print(line, end='')
\ No newline at end of file
...@@ -193,6 +193,13 @@ def buildKeywordDictionary(major_version_num=MAJOR_VERSION_NUM, ...@@ -193,6 +193,13 @@ def buildKeywordDictionary(major_version_num=MAJOR_VERSION_NUM,
if platform.system() == 'Darwin': if platform.system() == 'Darwin':
extra_compile_args += ['-stdlib=libc++', '-mmacosx-version-min=10.7'] extra_compile_args += ['-stdlib=libc++', '-mmacosx-version-min=10.7']
extra_link_args += ['-stdlib=libc++', '-mmacosx-version-min=10.7', '-Wl', '-rpath', openmm_lib_path] extra_link_args += ['-stdlib=libc++', '-mmacosx-version-min=10.7', '-Wl', '-rpath', openmm_lib_path]
# Hard-code CC and CXX to clang, since gcc/g++ will *not* work with
# Anaconda, despite the fact that distutils will try to use them.
# System Python, homebrew, and MacPorts on Macs will always use
# clang, so this hack should always work and fix issues with users
# that have GCC installed from MacPorts or homebrew *and* Anaconda
os.environ['CC'] = 'clang'
os.environ['CXX'] = 'clang++'
library_dirs=[openmm_lib_path] library_dirs=[openmm_lib_path]
include_dirs=openmm_include_path.split(';') include_dirs=openmm_include_path.split(';')
......
...@@ -10,7 +10,7 @@ Portions copyright (c) 2012 Stanford University and the Authors. ...@@ -10,7 +10,7 @@ Portions copyright (c) 2012 Stanford University and the Authors.
Authors: Peter Eastman, Steffen Lindert Authors: Peter Eastman, Steffen Lindert
Contributors: Contributors:
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, the rights to use, copy, modify, merge, publish, distribute, sublicense,
...@@ -37,22 +37,26 @@ from simtk.unit import kilojoules_per_mole, is_quantity ...@@ -37,22 +37,26 @@ from simtk.unit import kilojoules_per_mole, is_quantity
class AMDIntegrator(CustomIntegrator): class AMDIntegrator(CustomIntegrator):
"""AMDIntegrator implements the aMD integration algorithm. """AMDIntegrator implements the aMD integration algorithm.
The system is integrated based on a modified potential. Whenever the energy V(r) is less than a The system is integrated based on a modified potential. Whenever the energy V(r) is less than a
cutoff value E, the following effective potential is used: cutoff value E, the following effective potential is used:
V*(r) = V(r) + (E-V(r))^2 / (alpha+E-V(r)) V*(r) = V(r) + (E-V(r))^2 / (alpha+E-V(r))
For details, see Hamelberg et al., J. Chem. Phys. 127, 155102 (2007). For details, see Hamelberg et al., J. Chem. Phys. 127, 155102 (2007).
""" """
def __init__(self, dt, alpha, E): def __init__(self, dt, alpha, E):
"""Create an AMDIntegrator. """Create an AMDIntegrator.
Parameters: Parameters
- dt (time) The integration time step to use ----------
- alpha (energy) The alpha parameter to use dt : time
- E (energy) The energy cutoff to use The integration time step to use
alpha : energy
The alpha parameter to use
E : energy
The energy cutoff to use
""" """
CustomIntegrator.__init__(self, dt) CustomIntegrator.__init__(self, dt)
self.addGlobalVariable("alpha", alpha) self.addGlobalVariable("alpha", alpha)
...@@ -64,23 +68,23 @@ class AMDIntegrator(CustomIntegrator): ...@@ -64,23 +68,23 @@ class AMDIntegrator(CustomIntegrator):
self.addComputePerDof("x", "x+dt*v") self.addComputePerDof("x", "x+dt*v")
self.addConstrainPositions() self.addConstrainPositions()
self.addComputePerDof("v", "(x-oldx)/dt") self.addComputePerDof("v", "(x-oldx)/dt")
def getAlpha(self): def getAlpha(self):
"""Get the value of alpha for the integrator.""" """Get the value of alpha for the integrator."""
return self.getGlobalVariable(0)*kilojoules_per_mole return self.getGlobalVariable(0)*kilojoules_per_mole
def setAlpha(self, alpha): def setAlpha(self, alpha):
"""Set the value of alpha for the integrator.""" """Set the value of alpha for the integrator."""
self.setGlobalVariable(0, alpha) self.setGlobalVariable(0, alpha)
def getE(self): def getE(self):
"""Get the energy threshold E for the integrator.""" """Get the energy threshold E for the integrator."""
return self.getGlobalVariable(1)*kilojoules_per_mole return self.getGlobalVariable(1)*kilojoules_per_mole
def setE(self, E): def setE(self, E):
"""Set the energy threshold E for the integrator.""" """Set the energy threshold E for the integrator."""
self.setGlobalVariable(1, E) self.setGlobalVariable(1, E)
def getEffectiveEnergy(self, energy): def getEffectiveEnergy(self, energy):
"""Given the actual potential energy of the system, return the value of the effective potential.""" """Given the actual potential energy of the system, return the value of the effective potential."""
alpha = self.getAlpha() alpha = self.getAlpha()
...@@ -94,21 +98,26 @@ class AMDIntegrator(CustomIntegrator): ...@@ -94,21 +98,26 @@ class AMDIntegrator(CustomIntegrator):
class AMDForceGroupIntegrator(CustomIntegrator): class AMDForceGroupIntegrator(CustomIntegrator):
"""AMDForceGroupIntegrator implements a single boost aMD integration algorithm. """AMDForceGroupIntegrator implements a single boost aMD integration algorithm.
This is similar to AMDIntegrator, but is applied based on the energy of a single force group This is similar to AMDIntegrator, but is applied based on the energy of a single force group
(typically representing torsions). (typically representing torsions).
For details, see Hamelberg et al., J. Chem. Phys. 127, 155102 (2007). For details, see Hamelberg et al., J. Chem. Phys. 127, 155102 (2007).
""" """
def __init__(self, dt, group, alphaGroup, EGroup): def __init__(self, dt, group, alphaGroup, EGroup):
"""Create a AMDForceGroupIntegrator. """Create a AMDForceGroupIntegrator.
Parameters: Parameters
- dt (time) The integration time step to use ----------
- group (int) The force group to apply the boost to dt : time
- alphaGroup (energy) The alpha parameter to use for the boosted force group The integration time step to use
- EGroup (energy) The energy cutoff to use for the boosted force group group : int
The force group to apply the boost to
alphaGroup : energy
The alpha parameter to use for the boosted force group
EGroup : energy
The energy cutoff to use for the boosted force group
""" """
CustomIntegrator.__init__(self, dt) CustomIntegrator.__init__(self, dt)
self.addGlobalVariable("alphaGroup", alphaGroup) self.addGlobalVariable("alphaGroup", alphaGroup)
...@@ -124,29 +133,35 @@ class AMDForceGroupIntegrator(CustomIntegrator): ...@@ -124,29 +133,35 @@ class AMDForceGroupIntegrator(CustomIntegrator):
self.addComputePerDof("x", "x+dt*v") self.addComputePerDof("x", "x+dt*v")
self.addConstrainPositions() self.addConstrainPositions()
self.addComputePerDof("v", "(x-oldx)/dt") self.addComputePerDof("v", "(x-oldx)/dt")
def getAlphaGroup(self): def getAlphaGroup(self):
"""Get the value of alpha for the boosted force group.""" """Get the value of alpha for the boosted force group."""
return self.getGlobalVariable(0)*kilojoules_per_mole return self.getGlobalVariable(0)*kilojoules_per_mole
def setAlphaGroup(self, alpha): def setAlphaGroup(self, alpha):
"""Set the value of alpha for the boosted force group.""" """Set the value of alpha for the boosted force group."""
self.setGlobalVariable(0, alpha) self.setGlobalVariable(0, alpha)
def getEGroup(self): def getEGroup(self):
"""Get the energy threshold E for the boosted force group.""" """Get the energy threshold E for the boosted force group."""
return self.getGlobalVariable(1)*kilojoules_per_mole return self.getGlobalVariable(1)*kilojoules_per_mole
def setEGroup(self, E): def setEGroup(self, E):
"""Set the energy threshold E for the boosted force group.""" """Set the energy threshold E for the boosted force group."""
self.setGlobalVariable(1, E) self.setGlobalVariable(1, E)
def getEffectiveEnergy(self, groupEnergy): def getEffectiveEnergy(self, groupEnergy):
"""Given the actual group energy of the system, return the value of the effective potential. """Given the actual group energy of the system, return the value of the effective potential.
Parameters: Parameters
- groupEnergy (energy): the actual potential energy of the boosted force group ----------
Returns: the value of the effective potential groupEnergy : energy
the actual potential energy of the boosted force group
Returns
-------
energy
the value of the effective potential
""" """
alphaGroup = self.getAlphaGroup() alphaGroup = self.getAlphaGroup()
EGroup = self.getEGroup() EGroup = self.getEGroup()
...@@ -161,24 +176,31 @@ class AMDForceGroupIntegrator(CustomIntegrator): ...@@ -161,24 +176,31 @@ class AMDForceGroupIntegrator(CustomIntegrator):
class DualAMDIntegrator(CustomIntegrator): class DualAMDIntegrator(CustomIntegrator):
"""DualAMDIntegrator implements a dual boost aMD integration algorithm. """DualAMDIntegrator implements a dual boost aMD integration algorithm.
This is similar to AMDIntegrator, but two different boosts are applied to the potential: This is similar to AMDIntegrator, but two different boosts are applied to the potential:
one based on the total energy, and one based on the energy of a single force group one based on the total energy, and one based on the energy of a single force group
(typically representing torsions). (typically representing torsions).
For details, see Hamelberg et al., J. Chem. Phys. 127, 155102 (2007). For details, see Hamelberg et al., J. Chem. Phys. 127, 155102 (2007).
""" """
def __init__(self, dt, group, alphaTotal, ETotal, alphaGroup, EGroup): def __init__(self, dt, group, alphaTotal, ETotal, alphaGroup, EGroup):
"""Create a DualAMDIntegrator. """Create a DualAMDIntegrator.
Parameters: Parameters
- dt (time) The integration time step to use ----------
- group (int) The force group to apply the second boost to dt : time
- alphaTotal (energy) The alpha parameter to use for the total energy The integration time step to use
- ETotal (energy) The energy cutoff to use for the total energy group : int
- alphaGroup (energy) The alpha parameter to use for the boosted force group The force group to apply the second boost to
- EGroup (energy) The energy cutoff to use for the boosted force group alphaTotal : energy
The alpha parameter to use for the total energy
ETotal : energy
The energy cutoff to use for the total energy
alphaGroup : energy
The alpha parameter to use for the boosted force group
EGroup : energy
The energy cutoff to use for the boosted force group
""" """
CustomIntegrator.__init__(self, dt) CustomIntegrator.__init__(self, dt)
self.addGlobalVariable("alphaTotal", alphaTotal) self.addGlobalVariable("alphaTotal", alphaTotal)
...@@ -201,46 +223,53 @@ class DualAMDIntegrator(CustomIntegrator): ...@@ -201,46 +223,53 @@ class DualAMDIntegrator(CustomIntegrator):
self.addComputePerDof("x", "x+dt*v") self.addComputePerDof("x", "x+dt*v")
self.addConstrainPositions() self.addConstrainPositions()
self.addComputePerDof("v", "(x-oldx)/dt") self.addComputePerDof("v", "(x-oldx)/dt")
def getAlphaTotal(self): def getAlphaTotal(self):
"""Get the value of alpha for the total energy.""" """Get the value of alpha for the total energy."""
return self.getGlobalVariable(0)*kilojoules_per_mole return self.getGlobalVariable(0)*kilojoules_per_mole
def setAlphaTotal(self, alpha): def setAlphaTotal(self, alpha):
"""Set the value of alpha for the total energy.""" """Set the value of alpha for the total energy."""
self.setGlobalVariable(0, alpha) self.setGlobalVariable(0, alpha)
def getETotal(self): def getETotal(self):
"""Get the energy threshold E for the total energy.""" """Get the energy threshold E for the total energy."""
return self.getGlobalVariable(1)*kilojoules_per_mole return self.getGlobalVariable(1)*kilojoules_per_mole
def setETotal(self, E): def setETotal(self, E):
"""Set the energy threshold E for the total energy.""" """Set the energy threshold E for the total energy."""
self.setGlobalVariable(1, E) self.setGlobalVariable(1, E)
def getAlphaGroup(self): def getAlphaGroup(self):
"""Get the value of alpha for the boosted force group.""" """Get the value of alpha for the boosted force group."""
return self.getGlobalVariable(2)*kilojoules_per_mole return self.getGlobalVariable(2)*kilojoules_per_mole
def setAlphaGroup(self, alpha): def setAlphaGroup(self, alpha):
"""Set the value of alpha for the boosted force group.""" """Set the value of alpha for the boosted force group."""
self.setGlobalVariable(2, alpha) self.setGlobalVariable(2, alpha)
def getEGroup(self): def getEGroup(self):
"""Get the energy threshold E for the boosted force group.""" """Get the energy threshold E for the boosted force group."""
return self.getGlobalVariable(3)*kilojoules_per_mole return self.getGlobalVariable(3)*kilojoules_per_mole
def setEGroup(self, E): def setEGroup(self, E):
"""Set the energy threshold E for the boosted force group.""" """Set the energy threshold E for the boosted force group."""
self.setGlobalVariable(3, E) self.setGlobalVariable(3, E)
def getEffectiveEnergy(self, totalEnergy, groupEnergy): def getEffectiveEnergy(self, totalEnergy, groupEnergy):
"""Given the actual potential energy of the system, return the value of the effective potential. """Given the actual potential energy of the system, return the value of the effective potential.
Parameters: Parameters
- totalEnergy (energy): the actual potential energy of the whole system ----------
- groupEnergy (energy): the actual potential energy of the boosted force group totalEnergy : energy
Returns: the value of the effective potential the actual potential energy of the whole system
groupEnergy : energy
the actual potential energy of the boosted force group
Returns
-------
energy
the value of the effective potential
""" """
alphaTotal = self.getAlphaTotal() alphaTotal = self.getAlphaTotal()
ETotal = self.getETotal() ETotal = self.getETotal()
......
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