Created CustomVolumeForce (#4902)

* Created CustomVolumeForce

* Serialization for CustomVolumeForce

* Documentation for CustomVolumeForce

* Code simplification

* Removed unused code
This commit is contained in:
Peter Eastman
2025-04-28 11:43:40 -07:00
committed by GitHub
parent bce0c133e0
commit baf7942c74
12 changed files with 742 additions and 0 deletions

View File

@@ -99,3 +99,4 @@ expression.
generated/CustomManyParticleForce
generated/CustomNonbondedForce
generated/CustomTorsionForce
generated/CustomVolumeForce

View File

@@ -413,6 +413,21 @@ be used as a collective variable. The energy is then computed as
where *f*\ (...) is a user supplied mathematical expression of the collective
variables. It also may depend on user defined global parameters.
CustomVolumeForce
*****************
CustomVolumeForce computes an energy that depends only on the box vectors
defining the periodic box (see Section :numref:`periodic-boundary-conditions`).
.. math::
E = f(\mathbf{a}, \mathbf{b}, \mathbf{c})
Because the energy does not depend on particle positions, it does not apply any
forces to particles. It is primarily useful for constant pressure simulations,
where the volume-dependent energy can influence the behavior of the barostat.
Energy terms of this sort are often used for pressure matching in coarse grained
force fields.
ATMForce
********

View File

@@ -49,6 +49,7 @@
#include "openmm/CustomIntegrator.h"
#include "openmm/CustomManyParticleForce.h"
#include "openmm/CustomNonbondedForce.h"
#include "openmm/CustomVolumeForce.h"
#include "openmm/DPDIntegrator.h"
#include "openmm/Force.h"
#include "openmm/GayBerneForce.h"

View File

@@ -0,0 +1,160 @@
#ifndef OPENMM_CUSTOMVOLUMEFORCE_H_
#define OPENMM_CUSTOMVOLUMEFORCE_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) 2025 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 "internal/windowsExport.h"
#include <vector>
namespace OpenMM {
/**
* This class computes an energy that depends only on the volume of the periodic box, or more generally
* on the box shape as specified by the elements of the box vectors. Because the energy does not
* depend on particle positions, it does not apply any forces to particles. It is primarily useful
* for constant pressure simulations, where the volume-dependent energy can influence the behavior
* of the barostat. Energy terms of this sort are often used for pressure matching in coarse grained
* force fields.
*
* To use this class, create a CustomVolumeForce object, passing an algebraic expression to the constructor
* that defines the energy. The expression may depend on the following variables.
*
* <ul>
* <li>v: The volume of the periodic box in nm^3.</li>
* <li>ax: The x component of the first box vector in nm. (The y and z components are always zero.)</li>
* <li>bx, by: The x and y components of the second box vector in nm. (The z component is always zero.)</li>
* <li>cx, cy, cz: The x, y and z components of the third box vector in nm.</li>
* <li>Global parameters that you define by calling addGlobalParameter().</li>
* </ul>
*
* The initial value of a global parameter is specified in the call to addGlobalParameter(). Theire values
* can be modified during a simulation by calling Context::setParameter().
*
* 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, atan2, 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.
*/
class OPENMM_EXPORT CustomVolumeForce : public Force {
public:
/**
* Create a CustomVolumeForce.
*
* @param energy an algebraic expression giving the energy as a function of the box shape
*/
explicit CustomVolumeForce(const std::string& energy);
/**
* Get the number of global parameters that the energy depends on.
*/
int getNumGlobalParameters() const {
return globalParameters.size();
}
/**
* Get the algebraic expression that defines the energy.
*/
const std::string& getEnergyFunction() const;
/**
* Set the algebraic expression that defines the energy.
*/
void setEnergyFunction(const std::string& energy);
/**
* Add a new global parameter that the interaction may depend on. The default value provided to
* this method is the initial value of the parameter in newly created Contexts. You can change
* the value at any time by calling setParameter() on the Context.
*
* @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);
/**
* Returns whether or not this force makes use of periodic boundary conditions. Because this
* class is only applicable to periodic systems, this always returns true.
*/
bool usesPeriodicBoundaryConditions() const {
return true;
}
protected:
ForceImpl* createImpl() const;
private:
class GlobalParameterInfo;
std::string energyExpression;
std::vector<GlobalParameterInfo> globalParameters;
};
/**
* This is an internal class used to record information about a global parameter.
* @private
*/
class CustomVolumeForce::GlobalParameterInfo {
public:
std::string name;
double defaultValue;
GlobalParameterInfo() {
}
GlobalParameterInfo(const std::string& name, double defaultValue) : name(name), defaultValue(defaultValue) {
}
};
} // namespace OpenMM
#endif /*OPENMM_CUSTOMVOLUMEFORCE_H_*/

View File

@@ -0,0 +1,67 @@
#ifndef OPENMM_CUSTOMVOLUMEFORCEIMPL_H_
#define OPENMM_CUSTOMVOLUMEFORCEIMPL_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) 2025 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 "CustomCPPForceImpl.h"
#include "openmm/CustomVolumeForce.h"
#include "lepton/CompiledExpression.h"
#include <string>
namespace OpenMM {
/**
* This is the internal implementation of CustomVolumeForce.
*/
class CustomVolumeForceImpl : public CustomCPPForceImpl {
public:
CustomVolumeForceImpl(const CustomVolumeForce& owner);
void initialize(ContextImpl& context);
const CustomVolumeForce& getOwner() const {
return owner;
}
double computeForce(ContextImpl& context, const std::vector<Vec3>& positions, std::vector<Vec3>& forces);
std::map<std::string, double> getDefaultParameters();
private:
const CustomVolumeForce& owner;
std::map<std::string, double> defaultParameters;
Lepton::CompiledExpression energyExpression;
std::vector<std::string> globalParameterNames;
std::vector<double> globalValues;
Vec3 a, b, c;
double volume;
};
} // namespace OpenMM
#endif /*OPENMM_CUSTOMVOLUMEFORCEIMPL_H_*/

View File

@@ -0,0 +1,77 @@
/* -------------------------------------------------------------------------- *
* 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) 2025 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/CustomVolumeForce.h"
#include "openmm/internal/AssertionUtilities.h"
#include "openmm/internal/CustomVolumeForceImpl.h"
using namespace OpenMM;
using namespace std;
CustomVolumeForce::CustomVolumeForce(const string& energy) : energyExpression(energy) {
}
const string& CustomVolumeForce::getEnergyFunction() const {
return energyExpression;
}
void CustomVolumeForce::setEnergyFunction(const std::string& energy) {
energyExpression = energy;
}
int CustomVolumeForce::addGlobalParameter(const string& name, double defaultValue) {
globalParameters.push_back(GlobalParameterInfo(name, defaultValue));
return globalParameters.size()-1;
}
const string& CustomVolumeForce::getGlobalParameterName(int index) const {
ASSERT_VALID_INDEX(index, globalParameters);
return globalParameters[index].name;
}
void CustomVolumeForce::setGlobalParameterName(int index, const string& name) {
ASSERT_VALID_INDEX(index, globalParameters);
globalParameters[index].name = name;
}
double CustomVolumeForce::getGlobalParameterDefaultValue(int index) const {
ASSERT_VALID_INDEX(index, globalParameters);
return globalParameters[index].defaultValue;
}
void CustomVolumeForce::setGlobalParameterDefaultValue(int index, double defaultValue) {
ASSERT_VALID_INDEX(index, globalParameters);
globalParameters[index].defaultValue = defaultValue;
}
ForceImpl* CustomVolumeForce::createImpl() const {
return new CustomVolumeForceImpl(*this);
}

View File

@@ -0,0 +1,76 @@
/* -------------------------------------------------------------------------- *
* 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) 2025 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/internal/CustomVolumeForceImpl.h"
#include "openmm/internal/ContextImpl.h"
#include "lepton/ParsedExpression.h"
#include "lepton/Parser.h"
using namespace OpenMM;
using namespace std;
CustomVolumeForceImpl::CustomVolumeForceImpl(const CustomVolumeForce& owner) : CustomCPPForceImpl(owner), owner(owner) {
Lepton::ParsedExpression expression = Lepton::Parser::parse(owner.getEnergyFunction());
energyExpression = expression.createCompiledExpression();
map<string, double*> variableLocations;
globalParameterNames.resize(owner.getNumGlobalParameters());
globalValues.resize(owner.getNumGlobalParameters());
for (int i = 0; i < owner.getNumGlobalParameters(); i++) {
string name = owner.getGlobalParameterName(i);
defaultParameters[name] = owner.getGlobalParameterDefaultValue(i);
globalParameterNames[i] = name;
variableLocations[name] = &globalValues[i];
}
variableLocations["v"] = &volume;
variableLocations["ax"] = &a[0];
variableLocations["bx"] = &b[0];
variableLocations["by"] = &b[1];
variableLocations["cx"] = &c[0];
variableLocations["cy"] = &c[1];
variableLocations["cz"] = &c[2];
energyExpression.setVariableLocations(variableLocations);
}
void CustomVolumeForceImpl::initialize(ContextImpl& context) {
CustomCPPForceImpl::initialize(context);
}
double CustomVolumeForceImpl::computeForce(ContextImpl& context, const vector<Vec3>& positions, vector<Vec3>& forces) {
for (int i = 0; i < globalParameterNames.size(); i++)
globalValues[i] = context.getParameter(globalParameterNames[i]);
context.getPeriodicBoxVectors(a, b, c);
volume = a[0]*b[1]*c[2];
return energyExpression.evaluate();
}
map<string, double> CustomVolumeForceImpl::getDefaultParameters() {
return defaultParameters;
}

View File

@@ -0,0 +1,53 @@
#ifndef OPENMM_CUSTOMVOLUMEFORCE_PROXY_H_
#define OPENMM_CUSTOMVOLUMEFORCE_PROXY_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) 2025 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/internal/windowsExport.h"
#include "openmm/serialization/SerializationProxy.h"
namespace OpenMM {
/**
* This is a proxy for serializing CustomVolumeForce objects.
*/
class OPENMM_EXPORT CustomVolumeForceProxy : public SerializationProxy {
public:
CustomVolumeForceProxy();
void serialize(const void* object, SerializationNode& node) const;
void* deserialize(const SerializationNode& node) const;
};
} // namespace OpenMM
#endif /*OPENMM_CUSTOMVOLUMEFORCE_PROXY_H_*/

View File

@@ -0,0 +1,75 @@
/* -------------------------------------------------------------------------- *
* 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) 2025 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/CustomVolumeForceProxy.h"
#include "openmm/serialization/SerializationNode.h"
#include "openmm/Force.h"
#include "openmm/CustomVolumeForce.h"
#include <sstream>
using namespace OpenMM;
using namespace std;
CustomVolumeForceProxy::CustomVolumeForceProxy() : SerializationProxy("CustomVolumeForce") {
}
void CustomVolumeForceProxy::serialize(const void* object, SerializationNode& node) const {
node.setIntProperty("version", 0);
const CustomVolumeForce& force = *reinterpret_cast<const CustomVolumeForce*>(object);
node.setIntProperty("forceGroup", force.getForceGroup());
node.setStringProperty("name", force.getName());
node.setStringProperty("energy", force.getEnergyFunction());
SerializationNode& globalParams = node.createChildNode("GlobalParameters");
for (int i = 0; i < force.getNumGlobalParameters(); i++) {
globalParams.createChildNode("Parameter").setStringProperty("name", force.getGlobalParameterName(i)).setDoubleProperty("default", force.getGlobalParameterDefaultValue(i));
}
}
void* CustomVolumeForceProxy::deserialize(const SerializationNode& node) const {
int version = node.getIntProperty("version");
if (version != 0)
throw OpenMMException("Unsupported version number");
CustomVolumeForce* force = NULL;
try {
CustomVolumeForce* force = new CustomVolumeForce(node.getStringProperty("energy"));
force->setForceGroup(node.getIntProperty("forceGroup", 0));
force->setName(node.getStringProperty("name", force->getName()));
const SerializationNode& globalParams = node.getChildNode("GlobalParameters");
for (auto& parameter : globalParams.getChildren())
force->addGlobalParameter(parameter.getStringProperty("name"), parameter.getDoubleProperty("default"));
return force;
}
catch (...) {
if (force != NULL)
delete force;
throw;
}
}

View File

@@ -47,6 +47,7 @@
#include "openmm/CustomManyParticleForce.h"
#include "openmm/CustomNonbondedForce.h"
#include "openmm/CustomTorsionForce.h"
#include "openmm/CustomVolumeForce.h"
#include "openmm/DPDIntegrator.h"
#include "openmm/GayBerneForce.h"
#include "openmm/GBSAOBCForce.h"
@@ -88,6 +89,7 @@
#include "openmm/serialization/CustomManyParticleForceProxy.h"
#include "openmm/serialization/CustomNonbondedForceProxy.h"
#include "openmm/serialization/CustomTorsionForceProxy.h"
#include "openmm/serialization/CustomVolumeForceProxy.h"
#include "openmm/serialization/DPDIntegratorProxy.h"
#include "openmm/serialization/GayBerneForceProxy.h"
#include "openmm/serialization/GBSAOBCForceProxy.h"
@@ -147,6 +149,7 @@ extern "C" void registerSerializationProxies() {
SerializationProxy::registerProxy(typeid(CustomManyParticleForce), new CustomManyParticleForceProxy());
SerializationProxy::registerProxy(typeid(CustomNonbondedForce), new CustomNonbondedForceProxy());
SerializationProxy::registerProxy(typeid(CustomTorsionForce), new CustomTorsionForceProxy());
SerializationProxy::registerProxy(typeid(CustomVolumeForce), new CustomVolumeForceProxy());
SerializationProxy::registerProxy(typeid(Discrete1DFunction), new Discrete1DFunctionProxy());
SerializationProxy::registerProxy(typeid(Discrete2DFunction), new Discrete2DFunctionProxy());
SerializationProxy::registerProxy(typeid(Discrete3DFunction), new Discrete3DFunctionProxy());

View File

@@ -0,0 +1,79 @@
/* -------------------------------------------------------------------------- *
* 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) 2025 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/internal/AssertionUtilities.h"
#include "openmm/CustomVolumeForce.h"
#include "openmm/serialization/XmlSerializer.h"
#include <iostream>
#include <sstream>
using namespace OpenMM;
using namespace std;
void testSerialization() {
// Create a Force.
CustomVolumeForce force("2*v-by");
force.setForceGroup(3);
force.setName("custom name");
force.addGlobalParameter("x", 1.3);
force.addGlobalParameter("y", 2.221);
// Serialize and then deserialize it.
stringstream buffer;
XmlSerializer::serialize<CustomVolumeForce>(&force, "Force", buffer);
CustomVolumeForce* copy = XmlSerializer::deserialize<CustomVolumeForce>(buffer);
// Compare the two forces to see if they are identical.
CustomVolumeForce& force2 = *copy;
ASSERT_EQUAL(force.getForceGroup(), force2.getForceGroup());
ASSERT_EQUAL(force.getName(), force2.getName());
ASSERT_EQUAL(force.getEnergyFunction(), force2.getEnergyFunction());
ASSERT_EQUAL(force.getNumGlobalParameters(), force2.getNumGlobalParameters());
for (int i = 0; i < force.getNumGlobalParameters(); i++) {
ASSERT_EQUAL(force.getGlobalParameterName(i), force2.getGlobalParameterName(i));
ASSERT_EQUAL(force.getGlobalParameterDefaultValue(i), force2.getGlobalParameterDefaultValue(i));
}
}
int main() {
try {
testSerialization();
}
catch(const exception& e) {
cout << "exception: " << e.what() << endl;
return 1;
}
cout << "Done" << endl;
return 0;
}

View File

@@ -0,0 +1,135 @@
/* -------------------------------------------------------------------------- *
* 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) 2025 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/internal/AssertionUtilities.h"
#include "openmm/Context.h"
#include "openmm/CustomVolumeForce.h"
#include "openmm/Platform.h"
#include "openmm/VerletIntegrator.h"
#include "sfmt/SFMT.h"
#include <iostream>
using namespace OpenMM;
using namespace std;
void testVolume() {
System system;
Vec3 a(2, 0, 0);
Vec3 b(0.1, 2, 0);
Vec3 c(0.1, 0.1, 2);
system.setDefaultPeriodicBoxVectors(a, b, c);
system.addParticle(1.0);
CustomVolumeForce* force = new CustomVolumeForce("2*v");
system.addForce(force);
VerletIntegrator integrator(0.01);
Context context(system, integrator, Platform::getPlatform("Reference"));
context.setPositions({Vec3()});
OpenMM_SFMT::SFMT sfmt;
init_gen_rand(0, sfmt);
for (int i = 0; i < 10; i++) {
a[0] = 2.0 + 0.1*genrand_real2(sfmt);
b[1] = 2.0 + 0.1*genrand_real2(sfmt);
c[2] = 2.0 + 0.1*genrand_real2(sfmt);
b[0] = 0.1*genrand_real2(sfmt);
c[0] = 0.1*genrand_real2(sfmt);
c[1] = 0.1*genrand_real2(sfmt);
context.setPeriodicBoxVectors(a, b, c);
double energy = context.getState(State::Energy).getPotentialEnergy();
ASSERT_EQUAL_TOL(2*a[0]*b[1]*c[2], energy, 1e-6);
}
}
void testBoxVectors() {
System system;
Vec3 a(2, 0, 0);
Vec3 b(0.1, 2, 0);
Vec3 c(0.1, 0.1, 2);
system.setDefaultPeriodicBoxVectors(a, b, c);
system.addParticle(1.0);
CustomVolumeForce* force = new CustomVolumeForce("1 + ax + 2*bx + 3*by + 4*cx + 5*cy + 6*cz");
system.addForce(force);
VerletIntegrator integrator(0.01);
Context context(system, integrator, Platform::getPlatform("Reference"));
context.setPositions({Vec3()});
OpenMM_SFMT::SFMT sfmt;
init_gen_rand(0, sfmt);
for (int i = 0; i < 10; i++) {
a[0] = 2.0 + 0.1*genrand_real2(sfmt);
b[1] = 2.0 + 0.1*genrand_real2(sfmt);
c[2] = 2.0 + 0.1*genrand_real2(sfmt);
b[0] = 0.1*genrand_real2(sfmt);
c[0] = 0.1*genrand_real2(sfmt);
c[1] = 0.1*genrand_real2(sfmt);
context.setPeriodicBoxVectors(a, b, c);
double energy = context.getState(State::Energy).getPotentialEnergy();
ASSERT_EQUAL_TOL(1+a[0]+2*b[0]+3*b[1]+4*c[0]+5*c[1]+6*c[2], energy, 1e-6);
}
}
void testGlobalParameters() {
System system;
Vec3 a(2, 0, 0);
Vec3 b(0, 2, 0);
Vec3 c(0, 0, 3);
system.setDefaultPeriodicBoxVectors(a, b, c);
system.addParticle(1.0);
CustomVolumeForce* force = new CustomVolumeForce("p1*ax + p2*cz");
force->addGlobalParameter("p1", 1.0);
force->addGlobalParameter("p2", 1.0);
system.addForce(force);
VerletIntegrator integrator(0.01);
Context context(system, integrator, Platform::getPlatform("Reference"));
context.setPositions({Vec3()});
OpenMM_SFMT::SFMT sfmt;
init_gen_rand(0, sfmt);
for (int i = 0; i < 10; i++) {
double p1 = genrand_real2(sfmt);
double p2 = genrand_real2(sfmt);
context.setParameter("p1", p1);
context.setParameter("p2", p2);
double energy = context.getState(State::Energy).getPotentialEnergy();
ASSERT_EQUAL_TOL(2*p1+3*p2, energy, 1e-6);
}
}
int main(int argc, char* argv[]) {
try {
testVolume();
testBoxVectors();
testGlobalParameters();
}
catch(const exception& e) {
cout << "exception: " << e.what() << endl;
return 1;
}
cout << "Done" << endl;
return 0;
}