Unverified Commit 61a908cd authored by Michael J. Schnieders's avatar Michael J. Schnieders Committed by GitHub
Browse files

Updates to AmoebaVdwForce, AmoebaGeneralizedKirkwoodForce and AmoebaWcaDispersionForce (#4647)

* Update the AMOEBA OpenMM API for vdW, GK and WCA

* Changes needed for the Corrigan et al Generalized Kirkwood model and minor changes to the vdW force to support CpHMD

* Add casts to real for uses of POW in GK; Pass force by reference within the WCA kernel

* Update swigInputConfig for Amoeba vdW and GK forces

* Update TestAPIUnits.testAmoebaVdwForce

* Set the units for getSolventDielectric and getSoluteDielectric to None

* Update default dispersion offset parameter for the AmoebaWcaDispersionForce

* Remove overloaded getParticleParameters and setParticleParameters from AmoebaGeneralizedKirkwoodForce

* Update the AmoebaWcaDispersionForce TestAPIUnits tests to reflect using the correct units for the C++ parameter default values; Update the alanine-dipeptide-amoeba-forces to reflect the updated GK model

* Move neck descreening constants into AmoebaGeneralizedKirkwoodForceImpl; set the default GK dielecticOffset to 0.09; set the default WCA shctd parameter to 0.82

* Fix Python test cases for WCA and GK

* Load AMOEBA/GK parameters into an array of float4

* Cleaned up the AmoebaGeneralizedKirkwoodForce based on feedback from Peter; the one case where backwards compatibility remains a challenge is application of the dielectric offset parameter - in the prior code this was only applied to the nonpolar cavity term, but not to calculation of Born radii; in this revision the dielectric offset is applied to BOTH the nonpolar cavity term and to calculation of Born radii. At this point I can't think of elegant way to maintain backwards compatibility that isn't confusing, nor does it make sense (at least to me) to only apply the concept of the dieletric offset to one aspect (i.e. only to nonpolar cavity or only to Born radii calculation) but not to both.

* Remove 'using std::vector' from AmoebaGeneralizedKirkwoodForceImpl.h; divide by 10 instead of multiplying by 0.1f in amoebaGk.cc

* Added a parameter called descreenOffset, which is applied during calculation of effective Born radii for GK. The parameter dielectricOffset is only used for the nonpolar cavity term consistent with its prior use. All tests in TestAmoebaGeneralizedKirkwoodForce.h are now backwards compatible with their behavior prior to this PR.

* Change two constants in amoebaGk.cc to single precision; Improved the documentation for getNeckConstants in AmoebaGeneralizedKirkwoodForceImpl.h

* Fix comment for setTanhRescaling in AmoebaGeneralizedKirkwoodForce.h, Fix comment for setTanhParameters in AmoebaReferenceGeneralizedKirkwoodForce.h; set the type of parameter GeneralizedKirkwoodTanhRescaling to bool in AmoebaGeneralizedKirkwoodForceProxy.cpp; In ReferenceCalcAmoebaGeneralizedKirkwoodForceKernel return references of per particle parameters instead of copies; update AmoebaReferenceKernels.h method signatures for per particle parameters to return const vector references

* Minor tweaks to the documentation for the tanh rescaling flag

* Improve the comments for the get and setTanhParameters in AmoebaGeneralizedKirkwoodForce.h and AmoebaReferenceGeneralizedKirkwoodForce.h
parent 78c15368
...@@ -49,6 +49,7 @@ void AmoebaReferenceVdwForce::initialize(const AmoebaVdwForce& force) { ...@@ -49,6 +49,7 @@ void AmoebaReferenceVdwForce::initialize(const AmoebaVdwForce& force) {
int numParticles = force.getNumParticles(); int numParticles = force.getNumParticles();
indexIVs.resize(numParticles); indexIVs.resize(numParticles);
reductions.resize(numParticles); reductions.resize(numParticles);
scaleFactors.resize(numParticles);
isAlchemical.resize(numParticles); isAlchemical.resize(numParticles);
allExclusions.clear(); allExclusions.clear();
allExclusions.resize(numParticles); allExclusions.resize(numParticles);
...@@ -57,7 +58,7 @@ void AmoebaReferenceVdwForce::initialize(const AmoebaVdwForce& force) { ...@@ -57,7 +58,7 @@ void AmoebaReferenceVdwForce::initialize(const AmoebaVdwForce& force) {
double sigma, epsilon; double sigma, epsilon;
bool alchemical; bool alchemical;
vector<int> exclusions; vector<int> exclusions;
force.getParticleParameters(i, indexIVs[i], sigma, epsilon, reductions[i], alchemical, type); force.getParticleParameters(i, indexIVs[i], sigma, epsilon, reductions[i], alchemical, type, scaleFactors[i]);
isAlchemical[i] = alchemical; isAlchemical[i] = alchemical;
force.getParticleExclusions(i, exclusions); force.getParticleExclusions(i, exclusions);
for (unsigned int j = 0; j < exclusions.size(); j++) for (unsigned int j = 0; j < exclusions.size(); j++)
...@@ -224,6 +225,9 @@ double AmoebaReferenceVdwForce::calculateForceAndEnergy(int numParticles, double ...@@ -224,6 +225,9 @@ double AmoebaReferenceVdwForce::calculateForceAndEnergy(int numParticles, double
double combinedEpsilon = epsilonMatrix[particleType[ii]][particleType[jj]]; double combinedEpsilon = epsilonMatrix[particleType[ii]][particleType[jj]];
double softcore = 0.0; double softcore = 0.0;
// Apply per particle scale factors (for CpHMD).
combinedEpsilon *= scaleFactors[ii] * scaleFactors[jj];
if (this->_alchemicalMethod == AmoebaVdwForce::Decouple && (isAlchemicalI != isAlchemical[jj])) { if (this->_alchemicalMethod == AmoebaVdwForce::Decouple && (isAlchemicalI != isAlchemical[jj])) {
combinedEpsilon *= pow(lambda, this->_n); combinedEpsilon *= pow(lambda, this->_n);
softcore = this->_alpha * pow(1.0 - lambda, 2); softcore = this->_alpha * pow(1.0 - lambda, 2);
...@@ -287,6 +291,9 @@ double AmoebaReferenceVdwForce::calculateForceAndEnergy(int numParticles, double ...@@ -287,6 +291,9 @@ double AmoebaReferenceVdwForce::calculateForceAndEnergy(int numParticles, double
double combinedSigma = sigmaMatrix[particleType[siteI]][particleType[siteJ]]; double combinedSigma = sigmaMatrix[particleType[siteI]][particleType[siteJ]];
double combinedEpsilon = epsilonMatrix[particleType[siteI]][particleType[siteJ]]; double combinedEpsilon = epsilonMatrix[particleType[siteI]][particleType[siteJ]];
// Apply per particle scale factors (for CpHMD).
combinedEpsilon *= scaleFactors[siteI] * scaleFactors[siteJ];
double softcore = 0.0; double softcore = 0.0;
int isAlchemicalI = isAlchemical[siteI]; int isAlchemicalI = isAlchemical[siteI];
int isAlchemicalJ = isAlchemical[siteJ]; int isAlchemicalJ = isAlchemical[siteJ];
......
...@@ -135,6 +135,7 @@ private: ...@@ -135,6 +135,7 @@ private:
std::vector<std::vector<double> > epsilonMatrix; std::vector<std::vector<double> > epsilonMatrix;
std::vector<int> indexIVs; std::vector<int> indexIVs;
std::vector<double> reductions; std::vector<double> reductions;
std::vector<double> scaleFactors;
std::vector<bool> isAlchemical; std::vector<bool> isAlchemical;
std::vector<std::set<int> > allExclusions; std::vector<std::set<int> > allExclusions;
Vec3 _periodicBoxVectors[3]; Vec3 _periodicBoxVectors[3];
......
...@@ -91,13 +91,12 @@ private: ...@@ -91,13 +91,12 @@ private:
double _dispoff; double _dispoff;
double _slevy; double _slevy;
enum { EMIXO, RMIXO, RMIXO7, AO, EMIXH, RMIXH, RMIXH7, AH, LastIntermediateValueIndex }; enum { EMIXO, RMIXO, EMIXH, RMIXH, LastIntermediateValueIndex };
/**--------------------------------------------------------------------------------------- /**---------------------------------------------------------------------------------------
Calculate pair ixn Calculate pair ixn
@param radiusI radius of particle I
@param radiusJ radius of particle J @param radiusJ radius of particle J
@param particleIPosition particle I position @param particleIPosition particle I position
@param particleJPosition particle J position @param particleJPosition particle J position
...@@ -108,7 +107,7 @@ private: ...@@ -108,7 +107,7 @@ private:
--------------------------------------------------------------------------------------- */ --------------------------------------------------------------------------------------- */
double calculatePairIxn(double radiusI, double radiusJ, double calculatePairIxn(double radiusJ,
const OpenMM::Vec3& particleIPosition, const OpenMM::Vec3& particleJPosition, const OpenMM::Vec3& particleIPosition, const OpenMM::Vec3& particleJPosition,
const double* const intermediateValues, const double* const intermediateValues,
Vec3& force) const; Vec3& force) const;
......
...@@ -42,46 +42,70 @@ AmoebaGeneralizedKirkwoodForceProxy::AmoebaGeneralizedKirkwoodForceProxy() : Ser ...@@ -42,46 +42,70 @@ AmoebaGeneralizedKirkwoodForceProxy::AmoebaGeneralizedKirkwoodForceProxy() : Ser
} }
void AmoebaGeneralizedKirkwoodForceProxy::serialize(const void* object, SerializationNode& node) const { void AmoebaGeneralizedKirkwoodForceProxy::serialize(const void* object, SerializationNode& node) const {
node.setIntProperty("version", 2); node.setIntProperty("version", 3);
const AmoebaGeneralizedKirkwoodForce& force = *reinterpret_cast<const AmoebaGeneralizedKirkwoodForce*>(object); const AmoebaGeneralizedKirkwoodForce& force = *reinterpret_cast<const AmoebaGeneralizedKirkwoodForce*>(object);
node.setIntProperty("forceGroup", force.getForceGroup()); node.setIntProperty("forceGroup", force.getForceGroup());
node.setStringProperty("name", force.getName()); node.setStringProperty("name", force.getName());
node.setDoubleProperty("GeneralizedKirkwoodSolventDielectric", force.getSolventDielectric()); node.setDoubleProperty("GeneralizedKirkwoodSolventDielectric", force.getSolventDielectric());
node.setDoubleProperty("GeneralizedKirkwoodSoluteDielectric", force.getSoluteDielectric()); node.setDoubleProperty("GeneralizedKirkwoodSoluteDielectric", force.getSoluteDielectric());
//node.setDoubleProperty("GeneralizedKirkwoodDielectricOffset", force.getDielectricOffset()); node.setDoubleProperty("GeneralizedKirkwoodDielectricOffset", force.getDielectricOffset());
node.setDoubleProperty("GeneralizedKirkwoodProbeRadius", force.getProbeRadius()); node.setDoubleProperty("GeneralizedKirkwoodProbeRadius", force.getProbeRadius());
node.setDoubleProperty("GeneralizedKirkwoodSurfaceAreaFactor", force.getSurfaceAreaFactor()); node.setDoubleProperty("GeneralizedKirkwoodSurfaceAreaFactor", force.getSurfaceAreaFactor());
node.setIntProperty( "GeneralizedKirkwoodIncludeCavityTerm", force.getIncludeCavityTerm()); node.setIntProperty( "GeneralizedKirkwoodIncludeCavityTerm", force.getIncludeCavityTerm());
node.setBoolProperty("GeneralizedKirkwoodTanhRescaling", force.getTanhRescaling());
double b0, b1, b2;
force.getTanhParameters(b0, b1, b2);
node.setDoubleProperty("GeneralizedKirkwoodTanhB0", b0);
node.setDoubleProperty("GeneralizedKirkwoodTanhB1", b1);
node.setDoubleProperty("GeneralizedKirkwoodTanhB2", b2);
node.setDoubleProperty("GeneralizedKirkwoodDescreenOffset", force.getDescreenOffset());
SerializationNode& particles = node.createChildNode("GeneralizedKirkwoodParticles"); SerializationNode& particles = node.createChildNode("GeneralizedKirkwoodParticles");
for (unsigned int ii = 0; ii < static_cast<unsigned int>(force.getNumParticles()); ii++) { for (unsigned int ii = 0; ii < static_cast<unsigned int>(force.getNumParticles()); ii++) {
double radius, charge, scalingFactor; double radius, charge, scalingFactor, descreenRadius, neckFactor;
force.getParticleParameters(ii, charge, radius, scalingFactor); force.getParticleParameters(ii, charge, radius, scalingFactor, descreenRadius, neckFactor);
particles.createChildNode("Particle").setDoubleProperty("charge", charge).setDoubleProperty("radius", radius).setDoubleProperty("scaleFactor", scalingFactor); particles.createChildNode("Particle").setDoubleProperty("charge", charge).setDoubleProperty("radius", radius).setDoubleProperty("scaleFactor", scalingFactor).setDoubleProperty("descreenRadius", descreenRadius).setDoubleProperty("neckFactor", neckFactor);
} }
} }
void* AmoebaGeneralizedKirkwoodForceProxy::deserialize(const SerializationNode& node) const { void* AmoebaGeneralizedKirkwoodForceProxy::deserialize(const SerializationNode& node) const {
int version = node.getIntProperty("version"); int version = node.getIntProperty("version");
if (version < 1 || version > 2) if (version < 1 || version > 3)
throw OpenMMException("Unsupported version number"); throw OpenMMException("Unsupported version number");
AmoebaGeneralizedKirkwoodForce* force = new AmoebaGeneralizedKirkwoodForce(); AmoebaGeneralizedKirkwoodForce* force = new AmoebaGeneralizedKirkwoodForce();
try { try {
force->setForceGroup(node.getIntProperty("forceGroup", 0)); force->setForceGroup(node.getIntProperty("forceGroup", 0));
force->setName(node.getStringProperty("name", force->getName())); force->setName(node.getStringProperty("name", force->getName()));
force->setSolventDielectric( node.getDoubleProperty("GeneralizedKirkwoodSolventDielectric")); force->setSolventDielectric(node.getDoubleProperty("GeneralizedKirkwoodSolventDielectric"));
force->setSoluteDielectric( node.getDoubleProperty("GeneralizedKirkwoodSoluteDielectric")); force->setSoluteDielectric(node.getDoubleProperty("GeneralizedKirkwoodSoluteDielectric"));
//force->setDielectricOffset( node.getDoubleProperty("GeneralizedKirkwoodDielectricOffset")); force->setProbeRadius(node.getDoubleProperty("GeneralizedKirkwoodProbeRadius"));
force->setProbeRadius( node.getDoubleProperty("GeneralizedKirkwoodProbeRadius")); force->setSurfaceAreaFactor(node.getDoubleProperty("GeneralizedKirkwoodSurfaceAreaFactor"));
force->setSurfaceAreaFactor( node.getDoubleProperty("GeneralizedKirkwoodSurfaceAreaFactor")); force->setIncludeCavityTerm(node.getIntProperty("GeneralizedKirkwoodIncludeCavityTerm"));
force->setIncludeCavityTerm( node.getIntProperty( "GeneralizedKirkwoodIncludeCavityTerm")); if (version > 2) {
force->setDielectricOffset(node.getDoubleProperty("GeneralizedKirkwoodDielectricOffset"));
force->setTanhRescaling(node.getBoolProperty("GeneralizedKirkwoodTanhRescaling"));
double b0 = node.getDoubleProperty("GeneralizedKirkwoodTanhB0");
double b1 = node.getDoubleProperty("GeneralizedKirkwoodTanhB1");
double b2 = node.getDoubleProperty("GeneralizedKirkwoodTanhB2");
force->setTanhParameters(b0, b1, b2);
force->setDescreenOffset(node.getDoubleProperty("GeneralizedKirkwoodDescreenOffset"));
}
const SerializationNode& particles = node.getChildNode("GeneralizedKirkwoodParticles"); const SerializationNode& particles = node.getChildNode("GeneralizedKirkwoodParticles");
for (unsigned int ii = 0; ii < particles.getChildren().size(); ii++) { for (unsigned int ii = 0; ii < particles.getChildren().size(); ii++) {
const SerializationNode& particle = particles.getChildren()[ii]; const SerializationNode& particle = particles.getChildren()[ii];
force->addParticle(particle.getDoubleProperty("charge"), particle.getDoubleProperty("radius"), particle.getDoubleProperty("scaleFactor")); double charge = particle.getDoubleProperty("charge");
double radius = particle.getDoubleProperty("radius");
double scaleFactor = particle.getDoubleProperty("scaleFactor");
double descreenRadius = radius;
double neckFactor = 0.0;
if (version > 2) {
descreenRadius = particle.getDoubleProperty("descreenRadius");
neckFactor = particle.getDoubleProperty("neckFactor");
}
force->addParticle(charge, radius, scaleFactor, descreenRadius, neckFactor);
} }
} }
catch (...) { catch (...) {
......
...@@ -42,7 +42,7 @@ AmoebaVdwForceProxy::AmoebaVdwForceProxy() : SerializationProxy("AmoebaVdwForce" ...@@ -42,7 +42,7 @@ AmoebaVdwForceProxy::AmoebaVdwForceProxy() : SerializationProxy("AmoebaVdwForce"
} }
void AmoebaVdwForceProxy::serialize(const void* object, SerializationNode& node) const { void AmoebaVdwForceProxy::serialize(const void* object, SerializationNode& node) const {
node.setIntProperty("version", 4); node.setIntProperty("version", 5);
const AmoebaVdwForce& force = *reinterpret_cast<const AmoebaVdwForce*>(object); const AmoebaVdwForce& force = *reinterpret_cast<const AmoebaVdwForce*>(object);
bool useTypes = force.getUseParticleTypes(); bool useTypes = force.getUseParticleTypes();
...@@ -62,14 +62,14 @@ void AmoebaVdwForceProxy::serialize(const void* object, SerializationNode& node) ...@@ -62,14 +62,14 @@ void AmoebaVdwForceProxy::serialize(const void* object, SerializationNode& node)
SerializationNode& particles = node.createChildNode("VdwParticles"); SerializationNode& particles = node.createChildNode("VdwParticles");
for (int i = 0; i < force.getNumParticles(); i++) { for (int i = 0; i < force.getNumParticles(); i++) {
int ivIndex, typeIndex; int ivIndex, typeIndex;
double sigma, epsilon, reductionFactor; double sigma, epsilon, reductionFactor, scaleFactor;
bool isAlchemical; bool isAlchemical;
force.getParticleParameters(i, ivIndex, sigma, epsilon, reductionFactor, isAlchemical, typeIndex); force.getParticleParameters(i, ivIndex, sigma, epsilon, reductionFactor, isAlchemical, typeIndex, scaleFactor);
SerializationNode& particle = particles.createChildNode("Particle"); SerializationNode& particle = particles.createChildNode("Particle");
if (useTypes) if (useTypes)
particle.setIntProperty("ivIndex", ivIndex).setIntProperty("type", typeIndex).setDoubleProperty("reductionFactor", reductionFactor).setBoolProperty("isAlchemical", isAlchemical); particle.setIntProperty("ivIndex", ivIndex).setIntProperty("type", typeIndex).setDoubleProperty("reductionFactor", reductionFactor).setBoolProperty("isAlchemical", isAlchemical).setDoubleProperty("scaleFactor", scaleFactor);
else else
particle.setIntProperty("ivIndex", ivIndex).setDoubleProperty("sigma", sigma).setDoubleProperty("epsilon", epsilon).setDoubleProperty("reductionFactor", reductionFactor).setBoolProperty("isAlchemical", isAlchemical); particle.setIntProperty("ivIndex", ivIndex).setDoubleProperty("sigma", sigma).setDoubleProperty("epsilon", epsilon).setDoubleProperty("reductionFactor", reductionFactor).setBoolProperty("isAlchemical", isAlchemical).setDoubleProperty("scaleFactor", scaleFactor);
std::vector< int > exclusions; std::vector< int > exclusions;
force.getParticleExclusions(i, exclusions); force.getParticleExclusions(i, exclusions);
...@@ -98,7 +98,7 @@ void AmoebaVdwForceProxy::serialize(const void* object, SerializationNode& node) ...@@ -98,7 +98,7 @@ void AmoebaVdwForceProxy::serialize(const void* object, SerializationNode& node)
void* AmoebaVdwForceProxy::deserialize(const SerializationNode& node) const { void* AmoebaVdwForceProxy::deserialize(const SerializationNode& node) const {
int version = node.getIntProperty("version"); int version = node.getIntProperty("version");
if (version < 1 || version > 4) if (version < 1 || version > 5)
throw OpenMMException("Unsupported version number"); throw OpenMMException("Unsupported version number");
AmoebaVdwForce* force = new AmoebaVdwForce(); AmoebaVdwForce* force = new AmoebaVdwForce();
try { try {
...@@ -128,16 +128,30 @@ void* AmoebaVdwForceProxy::deserialize(const SerializationNode& node) const { ...@@ -128,16 +128,30 @@ void* AmoebaVdwForceProxy::deserialize(const SerializationNode& node) const {
if (version < 3) if (version < 3)
force->addParticle(particle.getIntProperty("ivIndex"), particle.getDoubleProperty("sigma"), force->addParticle(particle.getIntProperty("ivIndex"), particle.getDoubleProperty("sigma"),
particle.getDoubleProperty("epsilon"), particle.getDoubleProperty("reductionFactor")); particle.getDoubleProperty("epsilon"), particle.getDoubleProperty("reductionFactor"));
else if (useTypes) else if (version == 4) {
force->addParticle(particle.getIntProperty("ivIndex"), particle.getIntProperty("type"), if (useTypes)
particle.getDoubleProperty("reductionFactor"), particle.getBoolProperty("isAlchemical")); force->addParticle(particle.getIntProperty("ivIndex"), particle.getIntProperty("type"),
else particle.getDoubleProperty("reductionFactor"),
force->addParticle(particle.getIntProperty("ivIndex"), particle.getDoubleProperty("sigma"), particle.getBoolProperty("isAlchemical"));
particle.getDoubleProperty("epsilon"), particle.getDoubleProperty("reductionFactor"), else
particle.getBoolProperty("isAlchemical")); force->addParticle(particle.getIntProperty("ivIndex"), particle.getDoubleProperty("sigma"),
particle.getDoubleProperty("epsilon"),
particle.getDoubleProperty("reductionFactor"),
particle.getBoolProperty("isAlchemical"));
} else {
// Version 5 includes per particle scale factor for CpHMD.
if (useTypes)
force->addParticle(particle.getIntProperty("ivIndex"), particle.getIntProperty("type"),
particle.getDoubleProperty("reductionFactor"),
particle.getBoolProperty("isAlchemical"), particle.getDoubleProperty("scaleFactor"));
else
force->addParticle(particle.getIntProperty("ivIndex"), particle.getDoubleProperty("sigma"),
particle.getDoubleProperty("epsilon"),
particle.getDoubleProperty("reductionFactor"),
particle.getBoolProperty("isAlchemical"), particle.getDoubleProperty("scaleFactor"));
}
// exclusions // exclusions
const SerializationNode& particleExclusions = particle.getChildNode("ParticleExclusions"); const SerializationNode& particleExclusions = particle.getChildNode("ParticleExclusions");
std::vector<int> exclusions; std::vector<int> exclusions;
for (int j = 0; j < particleExclusions.getChildren().size(); j++) for (int j = 0; j < particleExclusions.getChildren().size(); j++)
......
...@@ -47,46 +47,48 @@ void testSerialization() { ...@@ -47,46 +47,48 @@ void testSerialization() {
AmoebaGeneralizedKirkwoodForce force1; AmoebaGeneralizedKirkwoodForce force1;
force1.setForceGroup(3); force1.setForceGroup(3);
force1.setName("custom name"); force1.setName("custom name");
force1.setSolventDielectric( 80.0); force1.setSolventDielectric(80.0);
force1.setSoluteDielectric( 1.0); force1.setSoluteDielectric(1.0);
//force1.setDielectricOffset( 0.09); force1.setDielectricOffset( 0.09);
force1.setProbeRadius( 1.40); force1.setProbeRadius(1.40);
force1.setSurfaceAreaFactor( 0.888); force1.setSurfaceAreaFactor(0.888);
force1.setIncludeCavityTerm( 1); force1.setIncludeCavityTerm(1);
force1.setTanhRescaling(0);
force1.addParticle(1.0, 2.0, 0.9); force1.addParticle(1.0, 2.0, 0.9, 2.0, 0.0);
force1.addParticle(-1.1,2.1, 0.8); force1.addParticle(-1.1, 2.1, 0.8, 2.1, 0.0);
force1.addParticle(0.1, 2.2, 0.7); force1.addParticle(0.1, 2.2, 0.7, 2.2, 0.0);
// Serialize and then deserialize it. // Serialize and then deserialize it.
stringstream buffer; stringstream buffer;
XmlSerializer::serialize<AmoebaGeneralizedKirkwoodForce>(&force1, "Force", buffer); XmlSerializer::serialize<AmoebaGeneralizedKirkwoodForce>(&force1, "Force", buffer);
AmoebaGeneralizedKirkwoodForce* copy = XmlSerializer::deserialize<AmoebaGeneralizedKirkwoodForce>(buffer); AmoebaGeneralizedKirkwoodForce *copy = XmlSerializer::deserialize<AmoebaGeneralizedKirkwoodForce>(buffer);
// Compare the two forces to see if they are identical. // Compare the two forces to see if they are identical.
AmoebaGeneralizedKirkwoodForce& force2 = *copy; AmoebaGeneralizedKirkwoodForce &force2 = *copy;
ASSERT_EQUAL(force1.getForceGroup(), force2.getForceGroup()); ASSERT_EQUAL(force1.getForceGroup(), force2.getForceGroup());
ASSERT_EQUAL(force1.getName(), force2.getName()); ASSERT_EQUAL(force1.getName(), force2.getName());
ASSERT_EQUAL(force1.getSolventDielectric(), force2.getSolventDielectric()); ASSERT_EQUAL(force1.getSolventDielectric(), force2.getSolventDielectric());
ASSERT_EQUAL(force1.getSoluteDielectric(), force2.getSoluteDielectric()); ASSERT_EQUAL(force1.getSoluteDielectric(), force2.getSoluteDielectric());
//ASSERT_EQUAL(force1.getDielectricOffset(), force2.getDielectricOffset()); ASSERT_EQUAL(force1.getDielectricOffset(), force2.getDielectricOffset());
ASSERT_EQUAL(force1.getProbeRadius(), force2.getProbeRadius()); ASSERT_EQUAL(force1.getProbeRadius(), force2.getProbeRadius());
ASSERT_EQUAL(force1.getSurfaceAreaFactor(), force2.getSurfaceAreaFactor()); ASSERT_EQUAL(force1.getSurfaceAreaFactor(), force2.getSurfaceAreaFactor());
ASSERT_EQUAL(force1.getIncludeCavityTerm(), force2.getIncludeCavityTerm()); ASSERT_EQUAL(force1.getIncludeCavityTerm(), force2.getIncludeCavityTerm());
ASSERT_EQUAL(force1.getNumParticles(), force2.getNumParticles()); ASSERT_EQUAL(force1.getNumParticles(), force2.getNumParticles());
for (unsigned int ii = 0; ii < static_cast<unsigned int>(force1.getNumParticles()); ii++) { for (unsigned int ii = 0; ii < static_cast<unsigned int>(force1.getNumParticles()); ii++) {
double radius1, charge1, scaleFactor1; double radius1, charge1, scaleFactor1, descreen1, neckFactor1;
double radius2, charge2, scaleFactor2; double radius2, charge2, scaleFactor2, descreen2, neckFactor2;
force1.getParticleParameters(ii, charge1, radius1, scaleFactor1); force1.getParticleParameters(ii, charge1, radius1, scaleFactor1, descreen1, neckFactor1);
force2.getParticleParameters(ii, charge2, radius2, scaleFactor2); force2.getParticleParameters(ii, charge2, radius2, scaleFactor2, descreen2, neckFactor2);
ASSERT_EQUAL(charge1, charge2); ASSERT_EQUAL(charge1, charge2)
ASSERT_EQUAL(radius1, radius2); ASSERT_EQUAL(radius1, radius2)
ASSERT_EQUAL(scaleFactor1, scaleFactor2); ASSERT_EQUAL(scaleFactor1, scaleFactor2)
ASSERT_EQUAL(descreen1, descreen2)
} }
} }
...@@ -95,7 +97,7 @@ int main() { ...@@ -95,7 +97,7 @@ int main() {
registerAmoebaSerializationProxies(); registerAmoebaSerializationProxies();
testSerialization(); testSerialization();
} }
catch(const exception& e) { catch (const exception &e) {
cout << "exception: " << e.what() << endl; cout << "exception: " << e.what() << endl;
return 1; return 1;
} }
......
...@@ -54,9 +54,9 @@ void testSerialization() { ...@@ -54,9 +54,9 @@ void testSerialization() {
force1.setAlchemicalMethod(AmoebaVdwForce::None); force1.setAlchemicalMethod(AmoebaVdwForce::None);
force1.setPotentialFunction(AmoebaVdwForce::Buffered147); force1.setPotentialFunction(AmoebaVdwForce::Buffered147);
force1.addParticle(0, 1.0, 2.0, 0.9, false); force1.addParticle(0, 1.0, 2.0, 0.9, false, 1.0);
force1.addParticle(1, 1.1, 2.1, 0.9, true); force1.addParticle(1, 1.1, 2.1, 0.9, true, 0.9);
force1.addParticle(2, 1.3, 4.1, 0.9, false); force1.addParticle(2, 1.3, 4.1, 0.9, false, 1.0);
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
std::vector< int > exclusions; std::vector< int > exclusions;
exclusions.push_back(i); exclusions.push_back(i);
...@@ -90,14 +90,14 @@ void testSerialization() { ...@@ -90,14 +90,14 @@ void testSerialization() {
int ivIndex1, type1; int ivIndex1, type1;
int ivIndex2, type2; int ivIndex2, type2;
double sigma1, epsilon1, reductionFactor1; double sigma1, epsilon1, reductionFactor1, scaleFactor1;
double sigma2, epsilon2, reductionFactor2; double sigma2, epsilon2, reductionFactor2, scaleFactor2;
bool isAlchemical1; bool isAlchemical1;
bool isAlchemical2; bool isAlchemical2;
force1.getParticleParameters(i, ivIndex1, sigma1, epsilon1, reductionFactor1, isAlchemical1, type1); force1.getParticleParameters(i, ivIndex1, sigma1, epsilon1, reductionFactor1, isAlchemical1, type1, scaleFactor1);
force2.getParticleParameters(i, ivIndex2, sigma2, epsilon2, reductionFactor2, isAlchemical2, type2); force2.getParticleParameters(i, ivIndex2, sigma2, epsilon2, reductionFactor2, isAlchemical2, type2, scaleFactor2);
ASSERT_EQUAL(ivIndex1, ivIndex2); ASSERT_EQUAL(ivIndex1, ivIndex2);
ASSERT_EQUAL(sigma1, sigma2); ASSERT_EQUAL(sigma1, sigma2);
...@@ -105,6 +105,7 @@ void testSerialization() { ...@@ -105,6 +105,7 @@ void testSerialization() {
ASSERT_EQUAL(reductionFactor1, reductionFactor2); ASSERT_EQUAL(reductionFactor1, reductionFactor2);
ASSERT_EQUAL(isAlchemical1, isAlchemical2); ASSERT_EQUAL(isAlchemical1, isAlchemical2);
ASSERT_EQUAL(type1, type2); ASSERT_EQUAL(type1, type2);
ASSERT_EQUAL(scaleFactor1, scaleFactor2);
} }
for (int i = 0; i < force1.getNumParticles(); i++) { for (int i = 0; i < force1.getNumParticles(); i++) {
...@@ -131,10 +132,10 @@ void testSerializeTypes() { ...@@ -131,10 +132,10 @@ void testSerializeTypes() {
AmoebaVdwForce force1; AmoebaVdwForce force1;
force1.setPotentialFunction(AmoebaVdwForce::LennardJones); force1.setPotentialFunction(AmoebaVdwForce::LennardJones);
force1.addParticle(0, 2, 1.0, false); force1.addParticle(0, 2, 1.0, false, 1.0);
force1.addParticle(1, 2, 0.9, true); force1.addParticle(1, 2, 0.9, true, 0.0);
force1.addParticle(2, 0, 1.0, false); force1.addParticle(2, 0, 1.0, false, 0.5);
force1.addParticle(3, 1, 0.9, false); force1.addParticle(3, 1, 0.9, false, 0.9);
force1.addParticleType(1.1, 2.0); force1.addParticleType(1.1, 2.0);
force1.addParticleType(1.2, 2.1); force1.addParticleType(1.2, 2.1);
force1.addParticleType(1.3, 2.2); force1.addParticleType(1.3, 2.2);
...@@ -158,14 +159,14 @@ void testSerializeTypes() { ...@@ -158,14 +159,14 @@ void testSerializeTypes() {
int ivIndex1, type1; int ivIndex1, type1;
int ivIndex2, type2; int ivIndex2, type2;
double sigma1, epsilon1, reductionFactor1; double sigma1, epsilon1, reductionFactor1, scaleFactor1;
double sigma2, epsilon2, reductionFactor2; double sigma2, epsilon2, reductionFactor2, scaleFactor2;
bool isAlchemical1; bool isAlchemical1;
bool isAlchemical2; bool isAlchemical2;
force1.getParticleParameters(i, ivIndex1, sigma1, epsilon1, reductionFactor1, isAlchemical1, type1); force1.getParticleParameters(i, ivIndex1, sigma1, epsilon1, reductionFactor1, isAlchemical1, type1, scaleFactor1);
force2.getParticleParameters(i, ivIndex2, sigma2, epsilon2, reductionFactor2, isAlchemical2, type2); force2.getParticleParameters(i, ivIndex2, sigma2, epsilon2, reductionFactor2, isAlchemical2, type2, scaleFactor2);
ASSERT_EQUAL(ivIndex1, ivIndex2); ASSERT_EQUAL(ivIndex1, ivIndex2);
ASSERT_EQUAL(sigma1, sigma2); ASSERT_EQUAL(sigma1, sigma2);
...@@ -173,6 +174,7 @@ void testSerializeTypes() { ...@@ -173,6 +174,7 @@ void testSerializeTypes() {
ASSERT_EQUAL(reductionFactor1, reductionFactor2); ASSERT_EQUAL(reductionFactor1, reductionFactor2);
ASSERT_EQUAL(isAlchemical1, isAlchemical2); ASSERT_EQUAL(isAlchemical1, isAlchemical2);
ASSERT_EQUAL(type1, type2); ASSERT_EQUAL(type1, type2);
ASSERT_EQUAL(scaleFactor1, scaleFactor2);
} }
for (int i = 0; i < force1.getNumParticleTypes(); i++) { for (int i = 0; i < force1.getNumParticleTypes(); i++) {
double sigma1, epsilon1; double sigma1, epsilon1;
......
...@@ -289,10 +289,10 @@ static void setupMultipoleAmmonia(System& system, AmoebaGeneralizedKirkwoodForce ...@@ -289,10 +289,10 @@ static void setupMultipoleAmmonia(System& system, AmoebaGeneralizedKirkwoodForce
// addParticle: charge, radius, scalingFactor // addParticle: charge, radius, scalingFactor
   
for (unsigned int ii = 0; ii < 2; ii++) { for (unsigned int ii = 0; ii < 2; ii++) {
amoebaGeneralizedKirkwoodForce->addParticle( -5.7960000e-01, 1.5965000e-01, 6.9000000e-01); amoebaGeneralizedKirkwoodForce->addParticle( -5.7960000e-01, 1.5965000e-01, 6.9000000e-01, 1.5965000e-01, 0.0f);
amoebaGeneralizedKirkwoodForce->addParticle( 1.9320000e-01, 1.2360000e-01, 6.9000000e-01); amoebaGeneralizedKirkwoodForce->addParticle( 1.9320000e-01, 1.2360000e-01, 6.9000000e-01, 1.2360000e-01, 0.0f);
amoebaGeneralizedKirkwoodForce->addParticle( 1.9320000e-01, 1.2360000e-01, 6.9000000e-01); amoebaGeneralizedKirkwoodForce->addParticle( 1.9320000e-01, 1.2360000e-01, 6.9000000e-01, 1.2360000e-01, 0.0f);
amoebaGeneralizedKirkwoodForce->addParticle( 1.9320000e-01, 1.2360000e-01, 6.9000000e-01); amoebaGeneralizedKirkwoodForce->addParticle( 1.9320000e-01, 1.2360000e-01, 6.9000000e-01, 1.2360000e-01, 0.0f);
} }
system.addForce(amoebaGeneralizedKirkwoodForce); system.addForce(amoebaGeneralizedKirkwoodForce);
} }
...@@ -7167,9 +7167,9 @@ static void testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm() { ...@@ -7167,9 +7167,9 @@ static void testGeneralizedKirkwoodAmmoniaMutualPolarizationWithCavityTerm() {
// Try changing the particle parameters and make sure it's still correct. // Try changing the particle parameters and make sure it's still correct.
for (int i = 0; i < numberOfParticles; i++) { for (int i = 0; i < numberOfParticles; i++) {
double charge, radius, scale; double charge, radius, scale, descreenRadius, neckscale;
amoebaGeneralizedKirkwoodForce->getParticleParameters(i, charge, radius, scale); amoebaGeneralizedKirkwoodForce->getParticleParameters(i, charge, radius, scale, descreenRadius, neckscale);
amoebaGeneralizedKirkwoodForce->setParticleParameters(i, charge, 0.9*radius, 1.1*scale); amoebaGeneralizedKirkwoodForce->setParticleParameters(i, charge, 0.9*radius, 1.1*scale, 1.2*descreenRadius, 1.3*neckscale);
} }
LangevinIntegrator integrator2(0.0, 0.1, 0.01); LangevinIntegrator integrator2(0.0, 0.1, 0.01);
Context context2(system, integrator2, context.getPlatform()); Context context2(system, integrator2, context.getPlatform());
......
...@@ -133,12 +133,12 @@ void testVdw() { ...@@ -133,12 +133,12 @@ void testVdw() {
} }
for (int ii = 0; ii < amoebaVdwForce->getNumParticles(); ii++) { for (int ii = 0; ii < amoebaVdwForce->getNumParticles(); ii++) {
int indexIV, type; int indexIV, type;
double sigma, epsilon, reduction; double sigma, epsilon, reduction, scaleFactor;
bool isAlchemical; bool isAlchemical;
amoebaVdwForce->getParticleParameters(ii, indexIV, sigma, epsilon, reduction, isAlchemical, type); amoebaVdwForce->getParticleParameters(ii, indexIV, sigma, epsilon, reduction, isAlchemical, type, scaleFactor);
sigma *= AngstromToNm; sigma *= AngstromToNm;
epsilon *= CalToJoule; epsilon *= CalToJoule;
amoebaVdwForce->setParticleParameters(ii, indexIV, sigma, epsilon, reduction, isAlchemical, type); amoebaVdwForce->setParticleParameters(ii, indexIV, sigma, epsilon, reduction, isAlchemical, type, scaleFactor);
} }
Context context(system, integrator, platform); Context context(system, integrator, platform);
...@@ -163,10 +163,10 @@ void testVdw() { ...@@ -163,10 +163,10 @@ void testVdw() {
for (int i = 0; i < numberOfParticles; i++) { for (int i = 0; i < numberOfParticles; i++) {
int indexIV, type; int indexIV, type;
double mass, sigma, epsilon, reduction; double mass, sigma, epsilon, reduction, scaleFactor;
bool isAlchemical; bool isAlchemical;
amoebaVdwForce->getParticleParameters(i, indexIV, sigma, epsilon, reduction, isAlchemical, type); amoebaVdwForce->getParticleParameters(i, indexIV, sigma, epsilon, reduction, isAlchemical, type, scaleFactor);
amoebaVdwForce->setParticleParameters(i, indexIV, 0.9*sigma, 2.0*epsilon, 0.95*reduction, isAlchemical, type); amoebaVdwForce->setParticleParameters(i, indexIV, 0.9*sigma, 2.0*epsilon, 0.95*reduction, isAlchemical, type, scaleFactor);
} }
LangevinIntegrator integrator2(0.0, 0.1, 0.01); LangevinIntegrator integrator2(0.0, 0.1, 0.01);
Context context2(system, integrator2, platform); Context context2(system, integrator2, platform);
......
...@@ -42,103 +42,122 @@ ...@@ -42,103 +42,122 @@
#define ASSERT_EQUAL_TOL_MOD(expected, found, tol, testname) {double _scale_ = std::abs(expected) > 1.0 ? std::abs(expected) : 1.0; if (!(std::abs((expected)-(found))/_scale_ <= (tol))) {std::stringstream details; details << testname << " Expected "<<(expected)<<", found "<<(found); throwException(__FILE__, __LINE__, details.str());}}; #define ASSERT_EQUAL_TOL_MOD(expected, found, tol, testname) {double _scale_ = std::abs(expected) > 1.0 ? std::abs(expected) : 1.0; if (!(std::abs((expected)-(found))/_scale_ <= (tol))) {std::stringstream details; details << testname << " Expected "<<(expected)<<", found "<<(found); throwException(__FILE__, __LINE__, details.str());}};
#define ASSERT_EQUAL_VEC_MOD(expected, found, tol,testname) {ASSERT_EQUAL_TOL_MOD((expected)[0], (found)[0], (tol),(testname)); ASSERT_EQUAL_TOL_MOD((expected)[1], (found)[1], (tol),(testname)); ASSERT_EQUAL_TOL_MOD((expected)[2], (found)[2], (tol),(testname));}; #define ASSERT_EQUAL_VEC_MOD(expected, found, tol, testname) {ASSERT_EQUAL_TOL_MOD((expected)[0], (found)[0], (tol),(testname)); ASSERT_EQUAL_TOL_MOD((expected)[1], (found)[1], (tol),(testname)); ASSERT_EQUAL_TOL_MOD((expected)[2], (found)[2], (tol),(testname));};
using namespace OpenMM; using namespace OpenMM;
const double TOL = 1e-4; const double TOL = 1e-4;
void compareForcesEnergy(std::string& testName, double expectedEnergy, double energy, void compareForcesEnergy(std::string &testName, double expectedEnergy, double energy,
const std::vector<Vec3>& expectedForces, const std::vector<Vec3> &expectedForces,
const std::vector<Vec3>& forces, double tolerance) { const std::vector<Vec3> &forces, double tolerance) {
for (unsigned int ii = 0; ii < forces.size(); ii++) { for (unsigned int ii = 0; ii < forces.size(); ii++) {
ASSERT_EQUAL_VEC_MOD(expectedForces[ii], forces[ii], tolerance, testName); ASSERT_EQUAL_VEC_MOD(expectedForces[ii], forces[ii], tolerance, testName)
} }
ASSERT_EQUAL_TOL_MOD(expectedEnergy, energy, tolerance, testName); ASSERT_EQUAL_TOL_MOD(expectedEnergy, energy, tolerance, testName)
} }
// test Wca dispersion // Test Wca Dispersion
void testWcaDispersionAmmonia() { void testWcaDispersionAmmonia() {
std::string testName = "testWcaDispersionAmmonia"; std::string testName = "testWcaDispersionAmmonia";
int numberOfParticles = 8;
int numberOfParticles = 8;
// Create the system. // Create the system.
System system; System system;
AmoebaWcaDispersionForce* amoebaWcaDispersionForce = new AmoebaWcaDispersionForce();; AmoebaWcaDispersionForce *amoebaWcaDispersionForce = new AmoebaWcaDispersionForce();
// Convert kcal/mol to kJ/mol
double epso = 0.1100e0 * 4.184e0;
double epsh = 0.0135e0 * 4.184e0;
// Convert A to nm.
double rmino = 1.7025e-01;
double rminh = 1.3275e-01;
double dispoff = 1.056e-01;
// Convert water number density from water / A^3 to water / nm^3.
double awater = 0.033428e03;
// No units.
double slevy = 1.0e0;
double shctd = 0.75e0;
amoebaWcaDispersionForce->setEpso(epso);
amoebaWcaDispersionForce->setEpsh(epsh);
amoebaWcaDispersionForce->setRmino(rmino);
amoebaWcaDispersionForce->setRminh(rminh);
amoebaWcaDispersionForce->setDispoff(dispoff);
amoebaWcaDispersionForce->setAwater(awater);
amoebaWcaDispersionForce->setSlevy(slevy);
amoebaWcaDispersionForce->setShctd(shctd);
// Amoeba 2009
// vdwtype BUFFERED-14-7
// radiusrule CUBIC-MEAN
// radiustype R-MIN
// radiussize DIAMETER
// epsilonrule HHG
// vdw 45 3.710000000 0.105000000
// vdw 46 2.700000000 0.020000000 0.910
amoebaWcaDispersionForce->setEpso( 4.6024000e-01); for (unsigned int ii = 0; ii < 2; ii++) {
amoebaWcaDispersionForce->setEpsh( 5.6484000e-02); system.addParticle(1.4007000e+01);
amoebaWcaDispersionForce->setRmino( 1.7025000e-01); amoebaWcaDispersionForce->addParticle(3.71e-01 / 2.0e0, 0.105e0 * 4.184e0);
amoebaWcaDispersionForce->setRminh( 1.3275000e-01);
amoebaWcaDispersionForce->setDispoff(2.6000000e-02);
amoebaWcaDispersionForce->setAwater( 3.3428000e+01);
amoebaWcaDispersionForce->setSlevy( 1.0000000e+00);
amoebaWcaDispersionForce->setShctd( 8.1000000e-01);
// addParticle: radius, epsilon system.addParticle(1.0080000e+00);
amoebaWcaDispersionForce->addParticle(2.7e-01 / 2.0e0, 0.02e0 * 4.184e0);
for (unsigned int ii = 0; ii < 2; ii++) { system.addParticle(1.0080000e+00);
system.addParticle( 1.4007000e+01); amoebaWcaDispersionForce->addParticle(2.7e-01 / 2.0e0, 0.02e0 * 4.184e0);
amoebaWcaDispersionForce->addParticle( 1.8550000e-01, 4.3932000e-01);
system.addParticle(1.0080000e+00);
system.addParticle( 1.0080000e+00); amoebaWcaDispersionForce->addParticle(2.7e-01 / 2.0e0, 0.02e0 * 4.184e0);
amoebaWcaDispersionForce->addParticle( 1.3500000e-01, 8.3680000e-02);
system.addParticle( 1.0080000e+00);
amoebaWcaDispersionForce->addParticle( 1.3500000e-01, 8.3680000e-02);
system.addParticle( 1.0080000e+00);
amoebaWcaDispersionForce->addParticle( 1.3500000e-01, 8.3680000e-02);
} }
std::vector<Vec3> positions(numberOfParticles); std::vector<Vec3> positions(numberOfParticles);
positions[0] = Vec3( 1.5927280e-01, 1.7000000e-06, 1.6491000e-03); positions[0] = Vec3(1.57493055e-01, 0.00085545e-01, 0.12707740e-01);
positions[1] = Vec3( 2.0805540e-01, -8.1258800e-02, 3.7282500e-02); positions[1] = Vec3(1.94285651e-01, -0.81095826e-01, 0.60622179e-01);
positions[2] = Vec3( 2.0843610e-01, 8.0953200e-02, 3.7462200e-02); positions[2] = Vec3(1.95030610e-01, 0.80808023e-01, 0.60809749e-01);
positions[3] = Vec3( 1.7280780e-01, 2.0730000e-04, -9.8741700e-02); positions[3] = Vec3(1.99309092e-01, -0.00015413e-01, -0.79434283e-01);
positions[4] = Vec3( -1.6743680e-01, 1.5900000e-05, -6.6149000e-03); positions[4] = Vec3(-1.65212994e-01, 0.02174061e-01, -0.04650966e-01);
positions[5] = Vec3( -2.0428260e-01, 8.1071500e-02, 4.1343900e-02); positions[5] = Vec3(-1.97210029e-01, 0.82501943e-01, 0.47898953e-01);
positions[6] = Vec3( -6.7308300e-02, 1.2800000e-05, 1.0623300e-02); positions[6] = Vec3(-0.64164714e-01, 0.01492667e-01, 0.03495515e-01);
positions[7] = Vec3( -2.0426290e-01, -8.1231400e-02, 4.1033500e-02); positions[7] = Vec3(-1.98070588e-01, -0.79434787e-01, 0.45336787e-01);
system.addForce(amoebaWcaDispersionForce); system.addForce(amoebaWcaDispersionForce);
ASSERT(!amoebaWcaDispersionForce->usesPeriodicBoundaryConditions());
ASSERT(!system.usesPeriodicBoundaryConditions());
LangevinIntegrator integrator(0.0, 0.1, 0.01); LangevinIntegrator integrator(0.0, 0.1, 0.01);
Context context(system, integrator, platform); Context context(system, integrator, platform);
context.setPositions(positions); context.setPositions(positions);
State state = context.getState(State::Forces | State::Energy); State state = context.getState(State::Forces | State::Energy);
std::vector<Vec3> forces = state.getForces(); const std::vector<Vec3> &forces = state.getForces();
double energy = state.getPotentialEnergy(); double energy = state.getPotentialEnergy();
// TINKER-computed values // Force Field X / Tinker expected energy -5.55412658 * 4.184 and forces.
double expectedEnergy = -5.55412658 * 4.184;
std::vector<Vec3> expectedForces(numberOfParticles); std::vector<Vec3> expectedForces(numberOfParticles);
double expectedEnergy = -2.6981209e+01;
expectedForces[0] = Vec3(-0.33370779, 0.00478895, -0.18780836);
expectedForces[0] = Vec3( 4.7839388e+00, -7.3510133e-04, -5.0382764e-01); expectedForces[1] = Vec3(1.15078615, 0.07363123, -0.04881103);
expectedForces[1] = Vec3( 1.4657758e+00, 1.2431003e+00, -6.7075886e-01); expectedForces[2] = Vec3(1.14509754, -0.08727205, -0.05086123);
expectedForces[2] = Vec3( 1.4563936e+00, -1.2399917e+00, -6.7443841e-01); expectedForces[3] = Vec3(0.97122614, -0.00473535, 0.09417216);
expectedForces[3] = Vec3( 2.1116744e+00, -2.7407512e-03, 1.3271245e+00); expectedForces[4] = Vec3(-1.64874538, 0.01074006, -0.08477238);
expectedForces[4] = Vec3( -4.7528440e+00, -1.5148066e-03, 1.2653813e+00); expectedForces[5] = Vec3(-1.28585908, 0.00494013, 0.05864744);
expectedForces[5] = Vec3( -1.1875619e+00, -1.2866678e+00, -3.9109060e-01); expectedForces[6] = Vec3(1.28677671, -0.00915430, 0.16081161);
expectedForces[6] = Vec3( -2.6885679e+00, -4.3038639e-04, 3.3763583e-02); expectedForces[7] = Vec3(-1.28557430, 0.00706132, 0.05862179);
expectedForces[7] = Vec3( -1.1888087e+00, 1.2889802e+00, -3.8615387e-01);
double tolerance = 1.0e-04;
double tolerance = 1.0e-04;
compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance); compareForcesEnergy(testName, expectedEnergy, energy, expectedForces, forces, tolerance);
// Try changing the particle parameters and make sure it's still correct. // Try changing the particle parameters and make sure it's still correct.
for (int i = 0; i < numberOfParticles; i++) { for (int i = 0; i < numberOfParticles; i++) {
double radius, epsilon; double radius, epsilon;
amoebaWcaDispersionForce->getParticleParameters(i, radius, epsilon); amoebaWcaDispersionForce->getParticleParameters(i, radius, epsilon);
amoebaWcaDispersionForce->setParticleParameters(i, 0.9*radius, 2.0*epsilon); amoebaWcaDispersionForce->setParticleParameters(i, 0.9 * radius, 2.0 * epsilon);
} }
LangevinIntegrator integrator2(0.0, 0.1, 0.01); LangevinIntegrator integrator2(0.0, 0.1, 0.01);
Context context2(system, integrator2, platform); Context context2(system, integrator2, platform);
...@@ -148,7 +167,8 @@ void testWcaDispersionAmmonia() { ...@@ -148,7 +167,8 @@ void testWcaDispersionAmmonia() {
bool exceptionThrown = false; bool exceptionThrown = false;
try { try {
// This should throw an exception. // This should throw an exception.
compareForcesEnergy(testName, state1.getPotentialEnergy(), state2.getPotentialEnergy(), state1.getForces(), state2.getForces(), tolerance); compareForcesEnergy(testName, state1.getPotentialEnergy(), state2.getPotentialEnergy(), state1.getForces(),
state2.getForces(), tolerance);
} }
catch (std::exception ex) { catch (std::exception ex) {
exceptionThrown = true; exceptionThrown = true;
...@@ -156,7 +176,8 @@ void testWcaDispersionAmmonia() { ...@@ -156,7 +176,8 @@ void testWcaDispersionAmmonia() {
ASSERT(exceptionThrown); ASSERT(exceptionThrown);
amoebaWcaDispersionForce->updateParametersInContext(context); amoebaWcaDispersionForce->updateParametersInContext(context);
state1 = context.getState(State::Forces | State::Energy); state1 = context.getState(State::Forces | State::Energy);
compareForcesEnergy(testName, state1.getPotentialEnergy(), state2.getPotentialEnergy(), state1.getForces(), state2.getForces(), tolerance); compareForcesEnergy(testName, state1.getPotentialEnergy(), state2.getPotentialEnergy(), state1.getForces(),
state2.getForces(), tolerance);
} }
void setupKernels(int argc, char* argv[]); void setupKernels(int argc, char* argv[]);
......
...@@ -240,12 +240,18 @@ UNITS = { ...@@ -240,12 +240,18 @@ UNITS = {
("SerializationProxy", "getTypeName") : (None, ()), ("SerializationProxy", "getTypeName") : (None, ()),
# check getSurfaceAreaFactor # check getSurfaceAreaFactor
("AmoebaGeneralizedKirkwoodForce", "getParticleParameters") : (None, ('unit.elementary_charge', 'unit.nanometer', None)), ("AmoebaGeneralizedKirkwoodForce", "getParticleParameters") : (None, ('unit.elementary_charge', 'unit.nanometer', None, 'unit.nanometer', None)),
("AmoebaGeneralizedKirkwoodForce", "getDielectricOffset") : ( 'unit.nanometer', ()), ("AmoebaGeneralizedKirkwoodForce", "getDielectricOffset") : ( 'unit.nanometer', ()),
("AmoebaGeneralizedKirkwoodForce", "getSolventDielectric") : (None, ()),
("AmoebaGeneralizedKirkwoodForce", "getSoluteDielectric") : (None, ()),
("AmoebaGeneralizedKirkwoodForce", "getIncludeCavityTerm") : ( None,()), ("AmoebaGeneralizedKirkwoodForce", "getIncludeCavityTerm") : ( None,()),
("AmoebaGeneralizedKirkwoodForce", "getTanhRescaling") : ( None,()),
("AmoebaGeneralizedKirkwoodForce", "getTanhParameters") : ( None,(None, None, None)),
("AmoebaGeneralizedKirkwoodForce", "getDescreenOffset") : ( 'unit.nanometer', ()),
("AmoebaGeneralizedKirkwoodForce", "getProbeRadius") : ( 'unit.nanometer', ()), ("AmoebaGeneralizedKirkwoodForce", "getProbeRadius") : ( 'unit.nanometer', ()),
("AmoebaGeneralizedKirkwoodForce", "getSurfaceAreaFactor") : ( 'unit.kilojoule_per_mole/(unit.nanometer*unit.nanometer)',()), ("AmoebaGeneralizedKirkwoodForce", "getSurfaceAreaFactor") : ( 'unit.kilojoule_per_mole/(unit.nanometer*unit.nanometer)',()),
("AmoebaMultipoleForce", "getNumMultipoles") : ( None,()), ("AmoebaMultipoleForce", "getNumMultipoles") : ( None,()),
("AmoebaMultipoleForce", "getPolarizationType") : ( None,()), ("AmoebaMultipoleForce", "getPolarizationType") : ( None,()),
("AmoebaMultipoleForce", "getCutoffDistance") : ( 'unit.nanometer',()), ("AmoebaMultipoleForce", "getCutoffDistance") : ( 'unit.nanometer',()),
...@@ -297,7 +303,7 @@ UNITS = { ...@@ -297,7 +303,7 @@ UNITS = {
("AmoebaVdwForce", "getSoftcorePower") : ( None, ()), ("AmoebaVdwForce", "getSoftcorePower") : ( None, ()),
("AmoebaVdwForce", "getSoftcoreAlpha") : ( None, ()), ("AmoebaVdwForce", "getSoftcoreAlpha") : ( None, ()),
("AmoebaVdwForce", "getCutoff") : ( 'unit.nanometer', ()), ("AmoebaVdwForce", "getCutoff") : ( 'unit.nanometer', ()),
("AmoebaVdwForce", "getParticleParameters") : ( None, (None, 'unit.nanometer', 'unit.kilojoule_per_mole', None, None, None)), ("AmoebaVdwForce", "getParticleParameters") : ( None, (None, 'unit.nanometer', 'unit.kilojoule_per_mole', None, None, None, None)),
("AmoebaVdwForce", "getParticleTypeParameters") : ( None, ('unit.nanometer', 'unit.kilojoule_per_mole')), ("AmoebaVdwForce", "getParticleTypeParameters") : ( None, ('unit.nanometer', 'unit.kilojoule_per_mole')),
("AmoebaVdwForce", "getTypePairParameters") : ( None, (None, None, 'unit.nanometer', 'unit.kilojoule_per_mole')), ("AmoebaVdwForce", "getTypePairParameters") : ( None, (None, None, 'unit.nanometer', 'unit.kilojoule_per_mole')),
......
...@@ -639,14 +639,14 @@ class TestAPIUnits(unittest.TestCase): ...@@ -639,14 +639,14 @@ class TestAPIUnits(unittest.TestCase):
self.assertEqual(force.getNumParticles(), 2) self.assertEqual(force.getNumParticles(), 2)
q, r, s = force.getParticleParameters(0) q, r, s, d, k = force.getParticleParameters(0)
self.assertAlmostEqualUnit(q, 1.0*coulomb) self.assertAlmostEqualUnit(q, 1.0*coulomb)
self.assertIs(q.unit, elementary_charge) self.assertIs(q.unit, elementary_charge)
self.assertEqual(r, 1.0*angstroms) self.assertEqual(r, 1.0*angstroms)
self.assertIs(r.unit, nanometer) self.assertIs(r.unit, nanometer)
self.assertEqual(s, 0.5) self.assertEqual(s, 0.5)
q, r, s = force.getParticleParameters(1) q, r, s, d, k = force.getParticleParameters(1)
self.assertAlmostEqualUnit(q, 1.0*elementary_charge) self.assertAlmostEqualUnit(q, 1.0*elementary_charge)
self.assertIs(q.unit, elementary_charge) self.assertIs(q.unit, elementary_charge)
self.assertEqual(r, 1.0*nanometer) self.assertEqual(r, 1.0*nanometer)
...@@ -759,44 +759,47 @@ class TestAPIUnits(unittest.TestCase): ...@@ -759,44 +759,47 @@ class TestAPIUnits(unittest.TestCase):
self.assertEqual(force.getNumParticles(), 3) self.assertEqual(force.getNumParticles(), 3)
p, sig, eps, scale, alchemical, type = force.getParticleParameters(0) p, sig, eps, reduction, alchemical, type, scale = force.getParticleParameters(0)
self.assertEqual(p, 0) self.assertEqual(p, 0)
self.assertEqual(sig, 0.1*nanometers) self.assertEqual(sig, 0.1*nanometers)
self.assertIs(sig.unit, nanometers) self.assertIs(sig.unit, nanometers)
self.assertEqual(eps, 1.0*kilojoules_per_mole) self.assertEqual(eps, 1.0*kilojoules_per_mole)
self.assertIs(eps.unit, kilojoules_per_mole) self.assertIs(eps.unit, kilojoules_per_mole)
self.assertEqual(scale, 1.0) self.assertEqual(reduction, 1.0)
self.assertEqual(type, -1) self.assertEqual(type, -1)
self.assertEqual(scale, 1.0)
p, sig, eps, scale, alchemical, type = force.getParticleParameters(1) p, sig, eps, reduction, alchemical, type, scale = force.getParticleParameters(1)
self.assertEqual(p, 1) self.assertEqual(p, 1)
self.assertEqual(sig, 1.0*angstroms) self.assertEqual(sig, 1.0*angstroms)
self.assertIs(sig.unit, nanometers) self.assertIs(sig.unit, nanometers)
self.assertEqual(eps, 1.0*kilocalories_per_mole) self.assertEqual(eps, 1.0*kilocalories_per_mole)
self.assertIs(eps.unit, kilojoules_per_mole) self.assertIs(eps.unit, kilojoules_per_mole)
self.assertEqual(scale, 0.5) self.assertEqual(reduction, 0.5)
self.assertEqual(type, -1) self.assertEqual(type, -1)
self.assertEqual(scale, 1.0)
p, sig, eps, scale, alchemical, type = force.getParticleParameters(2) p, sig, eps, reduction, alchemical, type, scale = force.getParticleParameters(2)
self.assertEqual(p, 1) self.assertEqual(p, 1)
self.assertAlmostEqualUnit(sig, 0.8*angstroms) self.assertAlmostEqualUnit(sig, 0.8*angstroms)
self.assertIs(sig.unit, nanometers) self.assertIs(sig.unit, nanometers)
self.assertEqual(eps, 2.0*kilocalories_per_mole) self.assertEqual(eps, 2.0*kilocalories_per_mole)
self.assertIs(eps.unit, kilojoules_per_mole) self.assertIs(eps.unit, kilojoules_per_mole)
self.assertEqual(scale, 0.25) self.assertEqual(reduction, 0.25)
self.assertEqual(type, -1) self.assertEqual(type, -1)
self.assertEqual(scale, 1.0)
def testAmoebaWcaDispersionForce(self): def testAmoebaWcaDispersionForce(self):
""" Tests the AmoebaWcaDispersionForce API features """ """ Tests the AmoebaWcaDispersionForce API features """
force = AmoebaWcaDispersionForce() force = AmoebaWcaDispersionForce()
self.assertEqual(force.getDispoff(), 0.26*nanometer) self.assertEqual(force.getDispoff(), 0.1056*nanometer)
self.assertEqual(force.getAwater(), 0.033428*nanometer**-3) self.assertEqual(force.getAwater(), 33.428*nanometer**-3)
self.assertEqual(force.getEpsh(), 0.0135*kilojoule_per_mole) self.assertEqual(force.getEpsh(), 0.056484*kilojoule_per_mole)
self.assertEqual(force.getEpso(), 0.11*kilojoule_per_mole) self.assertEqual(force.getEpso(), 0.46024000000000004*kilojoule_per_mole)
self.assertEqual(force.getRminh(), 1.3275*nanometer) self.assertEqual(force.getRminh(), 0.13275*nanometer)
self.assertEqual(force.getRmino(), 1.7025*nanometer) self.assertEqual(force.getRmino(), 0.17025*nanometer)
self.assertEqual(force.getShctd(), 0.81) self.assertEqual(force.getShctd(), 0.82)
self.assertEqual(force.getSlevy(), 1.0) self.assertEqual(force.getSlevy(), 1.0)
force.setDispoff(3*angstroms) force.setDispoff(3*angstroms)
......
<?xml version="1.0" ?> <?xml version="1.0" ?>
<State time="0" type="State" version="1"> <State openmmVersion="8.1" stepCount="0" time="0" type="State" version="1">
<PeriodicBoxVectors> <PeriodicBoxVectors>
<A x="2" y="0" z="0"/> <A x="2" y="0" z="0"/>
<B x="0" y="2" z="0"/> <B x="0" y="2" z="0"/>
<C x="0" y="0" z="2"/> <C x="0" y="0" z="2"/>
</PeriodicBoxVectors> </PeriodicBoxVectors>
<Forces> <Forces>
<Force x="-60.899006905648534" y="-704.8991281062977" z=".0364180169671772"/> <Force x="-60.48934767780512" y="-704.2905908945154" z=".03641801581402149"/>
<Force x="1179.7263311404506" y="629.2168542831286" z="1.563821009034657"/> <Force x="1180.5929374826017" y="629.7947038764579" z="1.563821030008981"/>
<Force x="-484.4401097634541" y="135.94210610096957" z="558.0155391926069"/> <Force x="-483.76818418432686" y="136.17122858237818" z="557.445557397338"/>
<Force x="-484.1625627429897" y="136.02915381525668" z="-557.7203977673528"/> <Force x="-483.4906371562492" y="136.2582762991838" z="-557.1504159715371"/>
<Force x="-804.8403408476064" y="-857.579131840898" z="118.43755474210333"/> <Force x="-804.7241107189593" y="-856.9162372174255" z="118.25073365873143"/>
<Force x="84.24441920455223" y="-421.86322192608037" z="120.734742628977"/> <Force x="83.81135991157873" y="-420.22160214948235" z="120.49617758444118"/>
<Force x="666.4942549112259" y="-479.03339298154526" z="19.66166555862896"/> <Force x="667.2849511622113" y="-479.3499008055406" z="19.235509803262467"/>
<Force x="-518.9062723002917" y="686.3850843706331" z=".7311137123231983"/> <Force x="-518.4733820988154" y="686.0855400714895" z=".7330333001425071"/>
<Force x="-105.62094199225953" y="710.9845370176521" z="-508.0677463920413"/> <Force x="-105.72909078977926" y="711.0668343181237" z="-508.83224725862544"/>
<Force x="285.6690654282444" y="-111.35548608152155" z="847.8096733172159"/> <Force x="285.3169350792583" y="-111.3017080984095" z="846.4662870215625"/>
<Force x="-396.4822698774795" y="24.462223992557014" z="297.9581483103431"/> <Force x="-397.35954566696427" y="24.822763038626682" z="299.33941483017065"/>
<Force x="-168.22340166944585" y="110.99779797739818" z="-824.0916382722021"/> <Force x="-168.27998965108577" y="111.03576033655848" z="-823.1461667946043"/>
<Force x="805.7023041833917" y="15.738288953519556" z="-340.2263402925698"/> <Force x="804.8766900716053" y="16.1343934366816" z="-339.5169767615949"/>
<Force x="366.3025998383222" y="-647.7535895818237" z="-273.83047817845636"/> <Force x="365.43779472611493" y="-647.3449172328129" z="-273.0689393022661"/>
<Force x="-649.7310636705703" y="-495.52797252280067" z="317.36013856851315"/> <Force x="-649.0369250626607" y="-495.932522816643" z="316.96471153570917"/>
<Force x="-480.120788018345" y="172.44477988154952" z="-16.235455767965004"/> <Force x="-479.0134208353095" y="171.79575146148863" z="-16.236401291749388"/>
<Force x="-486.20230228601736" y="982.6376366390087" z="127.20818643942287"/> <Force x="-486.9195278219171" y="982.2625867919138" z="126.98779152341059"/>
<Force x="820.5730252078641" y="-78.71234329038225" z="109.31395566365498"/> <Force x="819.7259822269968" y="-78.87846748631466" z="109.09059215425442"/>
<Force x="355.03388135028814" y="-1391.2776654673507" z=".9942543092954484"/> <Force x="354.68327095554434" y="-1392.2195705508666" z=".9942543256763656"/>
<Force x="-511.3467906691061" y="677.7717086552518" z=".008253291392112616"/> <Force x="-511.1150957463999" y="676.962020571201" z=".008253289146054499"/>
<Force x="293.66157422204157" y="452.68343054060256" z="502.83463917630775"/> <Force x="293.38125738064446" y="452.02037971976495" z="502.28873599651723"/>
<Force x="293.5683952568295" y="452.70832957117113" z="-502.49604726620026"/> <Force x="293.2880784137142" y="452.0452787481405" z="-501.95014408580874"/>
</Forces> </Forces>
</State> </State>
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