Unverified Commit 1e42b8be authored by Peter Eastman's avatar Peter Eastman Committed by GitHub
Browse files

Replaced several AMOEBA bonded forces with custom forces (#3046)

* Replaced several AMOEBA bonded forces with custom forces

* Deleted obsolete AMOEBA forces

* Replaced AmoebaPiTorsionForce with custom force
parent 014797f4
/* -------------------------------------------------------------------------- *
* OpenMMAmoeba *
* -------------------------------------------------------------------------- *
* 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-2016 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/Platform.h"
#include "openmm/internal/AssertionUtilities.h"
#include "openmm/AmoebaPiTorsionForce.h"
#include "openmm/serialization/XmlSerializer.h"
#include <iostream>
#include <sstream>
using namespace OpenMM;
using namespace std;
extern "C" void registerAmoebaSerializationProxies();
void testSerialization() {
// Create a Force.
AmoebaPiTorsionForce force1;
force1.setForceGroup(3);
force1.addPiTorsion(0, 1, 3, 4, 5, 6, 2.0);
force1.addPiTorsion(0, 2, 3, 5, 12, 13, 2.1);
force1.addPiTorsion(2, 3, 5, 6, 81, 91, 2.2);
force1.addPiTorsion(5, 1, 8, 8, 101, 102, 2.3);
force1.setUsesPeriodicBoundaryConditions(true);
// Serialize and then deserialize it.
stringstream buffer;
XmlSerializer::serialize<AmoebaPiTorsionForce>(&force1, "Force", buffer);
AmoebaPiTorsionForce* copy = XmlSerializer::deserialize<AmoebaPiTorsionForce>(buffer);
// Compare the two forces to see if they are identical.
AmoebaPiTorsionForce& force2 = *copy;
ASSERT_EQUAL(force1.getForceGroup(), force2.getForceGroup());
ASSERT_EQUAL(force1.usesPeriodicBoundaryConditions(), force2.usesPeriodicBoundaryConditions());
ASSERT_EQUAL(force1.getNumPiTorsions(), force2.getNumPiTorsions());
for (unsigned int ii = 0; ii < static_cast<unsigned int>(force1.getNumPiTorsions()); ii++) {
int a1, a2, a3, a4, a5, a6, b1, b2, b3, b4, b5, b6;
double ka, kb;
force1.getPiTorsionParameters(ii, a1, a2, a3, a4, a5, a6, ka);
force2.getPiTorsionParameters(ii, b1, b2, b3, b4, b5, b6, kb);
ASSERT_EQUAL(a1, b1);
ASSERT_EQUAL(a2, b2);
ASSERT_EQUAL(a3, b3);
ASSERT_EQUAL(a4, b4);
ASSERT_EQUAL(a5, b5);
ASSERT_EQUAL(a6, b6);
ASSERT_EQUAL(ka, kb);
}
}
int main() {
try {
registerAmoebaSerializationProxies();
testSerialization();
}
catch(const exception& e) {
cout << "exception: " << e.what() << endl;
return 1;
}
cout << "Done" << endl;
return 0;
}
/* -------------------------------------------------------------------------- *
* OpenMMAmoeba *
* -------------------------------------------------------------------------- *
* 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-2016 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/Platform.h"
#include "openmm/internal/AssertionUtilities.h"
#include "openmm/AmoebaStretchBendForce.h"
#include "openmm/serialization/XmlSerializer.h"
#include <iostream>
#include <sstream>
using namespace OpenMM;
using namespace std;
extern "C" void registerAmoebaSerializationProxies();
void testSerialization() {
// Create a Force.
AmoebaStretchBendForce force1;
force1.setForceGroup(3);
force1.addStretchBend(0, 1, 3, 1.0, 1.2, 150.1, 83.2, 100.);
force1.addStretchBend(2, 4, 4, 1.1, 2.2, 180.1, 89.2, 100.);
force1.addStretchBend(5, 0, 1, 3.1, 8.2, 140.1, 98.2, 100.);
force1.setUsesPeriodicBoundaryConditions(true);
// Serialize and then deserialize it.
stringstream buffer;
XmlSerializer::serialize<AmoebaStretchBendForce>(&force1, "Force", buffer);
AmoebaStretchBendForce* copy = XmlSerializer::deserialize<AmoebaStretchBendForce>(buffer);
// Compare the two forces to see if they are identical.
AmoebaStretchBendForce& force2 = *copy;
ASSERT_EQUAL(force1.getForceGroup(), force2.getForceGroup());
ASSERT_EQUAL(force1.usesPeriodicBoundaryConditions(), force2.usesPeriodicBoundaryConditions());
ASSERT_EQUAL(force1.getNumStretchBends(), force2.getNumStretchBends());
for (unsigned int ii = 0; ii < static_cast<unsigned int>(force1.getNumStretchBends()); ii++) {
int p11, p12, p13;
int p21, p22, p23;
double dAB1, dAB2;
double dCB1, dCB2;
double angle1, angle2;
double k11, k12, k21, k22;
force1.getStretchBendParameters(ii, p11, p12, p13, dAB1, dCB1, angle1, k11, k12);
force2.getStretchBendParameters(ii, p21, p22, p23, dAB2, dCB2, angle2, k21, k22);
ASSERT_EQUAL(p11, p21);
ASSERT_EQUAL(p12, p22);
ASSERT_EQUAL(p13, p23);
ASSERT_EQUAL(dAB1, dAB2);
ASSERT_EQUAL(dCB1, dCB2);
ASSERT_EQUAL(angle1, angle2);
ASSERT_EQUAL(k11, k21);
ASSERT_EQUAL(k12, k22);
}
}
int main() {
try {
registerAmoebaSerializationProxies();
testSerialization();
}
catch(const exception& e) {
cout << "exception: " << e.what() << endl;
return 1;
}
cout << "Done" << endl;
return 0;
}
......@@ -6,7 +6,7 @@ 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) 2012-2019 Stanford University and the Authors.
Portions copyright (c) 2012-2021 Stanford University and the Authors.
Authors: Peter Eastman, Mark Friedrichs
Contributors:
......@@ -1958,8 +1958,7 @@ class HarmonicBondGenerator(object):
generator.registerBond(bond.attrib)
def createForce(self, sys, data, nonbondedMethod, nonbondedCutoff, args):
existing = [sys.getForce(i) for i in range(sys.getNumForces())]
existing = [f for f in existing if type(f) == mm.HarmonicBondForce]
existing = [f for f in sys.getForces() if type(f) == mm.HarmonicBondForce]
if len(existing) == 0:
force = mm.HarmonicBondForce()
sys.addForce(force)
......@@ -2022,8 +2021,7 @@ class HarmonicAngleGenerator(object):
generator.registerAngle(angle.attrib)
def createForce(self, sys, data, nonbondedMethod, nonbondedCutoff, args):
existing = [sys.getForce(i) for i in range(sys.getNumForces())]
existing = [f for f in existing if type(f) == mm.HarmonicAngleForce]
existing = [f for f in sys.getForces() if type(f) == mm.HarmonicAngleForce]
if len(existing) == 0:
force = mm.HarmonicAngleForce()
sys.addForce(force)
......@@ -2127,8 +2125,7 @@ class PeriodicTorsionGenerator(object):
generator.registerImproperTorsion(torsion.attrib)
def createForce(self, sys, data, nonbondedMethod, nonbondedCutoff, args):
existing = [sys.getForce(i) for i in range(sys.getNumForces())]
existing = [f for f in existing if type(f) == mm.PeriodicTorsionForce]
existing = [f for f in sys.getForces() if type(f) == mm.PeriodicTorsionForce]
if len(existing) == 0:
force = mm.PeriodicTorsionForce()
sys.addForce(force)
......@@ -2243,8 +2240,7 @@ class RBTorsionGenerator(object):
generator.improper.append(RBTorsion(types, [float(torsion.attrib['c'+str(i)]) for i in range(6)]))
def createForce(self, sys, data, nonbondedMethod, nonbondedCutoff, args):
existing = [sys.getForce(i) for i in range(sys.getNumForces())]
existing = [f for f in existing if type(f) == mm.RBTorsionForce]
existing = [f for f in sys.getForces() if type(f) == mm.RBTorsionForce]
if len(existing) == 0:
force = mm.RBTorsionForce()
sys.addForce(force)
......@@ -2320,8 +2316,7 @@ class CMAPTorsionGenerator(object):
generator.torsions.append(CMAPTorsion(types, int(torsion.attrib['map'])))
def createForce(self, sys, data, nonbondedMethod, nonbondedCutoff, args):
existing = [sys.getForce(i) for i in range(sys.getNumForces())]
existing = [f for f in existing if type(f) == mm.CMAPTorsionForce]
existing = [f for f in sys.getForces() if type(f) == mm.CMAPTorsionForce]
if len(existing) == 0:
force = mm.CMAPTorsionForce()
sys.addForce(force)
......@@ -3320,7 +3315,7 @@ class AmoebaBondGenerator(object):
# <AmoebaBondForce bond-cubic="-25.5" bond-quartic="379.3125">
# <Bond class1="1" class2="2" length="0.1437" k="156900.0"/>
generator = AmoebaBondGenerator(float(element.attrib['bond-cubic']), float(element.attrib['bond-quartic']))
generator = AmoebaBondGenerator(element.attrib['bond-cubic'], element.attrib['bond-quartic'])
forceField._forces.append(generator)
for bond in element.findall('Bond'):
types = forceField._findAtomTypes(bond.attrib, 2)
......@@ -3339,19 +3334,16 @@ class AmoebaBondGenerator(object):
def createForce(self, sys, data, nonbondedMethod, nonbondedCutoff, args):
#countConstraint(data)
existing = [sys.getForce(i) for i in range(sys.getNumForces())]
existing = [f for f in existing if type(f) == mm.AmoebaBondForce]
energy = "k*(d^2 + %s*d^3 + %s*d^4); d=r-r0" % (self.cubic, self.quartic)
existing = [f for f in sys.getForces() if type(f) == mm.CustomBondForce and f.getEnergyFunction() == energy]
if len(existing) == 0:
force = mm.AmoebaBondForce()
force = mm.CustomBondForce(energy)
force.addPerBondParameter('r0')
force.addPerBondParameter('k')
sys.addForce(force)
else:
force = existing[0]
force.setAmoebaGlobalBondCubic(self.cubic)
force.setAmoebaGlobalBondQuartic(self.quartic)
for bond in data.bonds:
type1 = data.atomType[data.atoms[bond.atom1]]
type2 = data.atomType[data.atoms[bond.atom2]]
......@@ -3364,7 +3356,7 @@ class AmoebaBondGenerator(object):
data.addConstraint(sys, bond.atom1, bond.atom2, self.length[i])
if self.k[i] != 0:
if not bond.isConstrained or args.get('flexibleConstraints', False):
force.addBond(bond.atom1, bond.atom2, self.length[i], self.k[i])
force.addBond(bond.atom1, bond.atom2, [self.length[i], self.k[i]])
break
parsers["AmoebaBondForce"] = AmoebaBondGenerator.parseElement
......@@ -3428,7 +3420,7 @@ class AmoebaAngleGenerator(object):
# <AmoebaAngleForce angle-cubic="-0.014" angle-quartic="5.6e-05" angle-pentic="-7e-07" angle-sextic="2.2e-08">
# <Angle class1="2" class2="1" class3="3" k="0.0637259642196" angle1="122.00" />
generator = AmoebaAngleGenerator(forceField, float(element.attrib['angle-cubic']), float(element.attrib['angle-quartic']), float(element.attrib['angle-pentic']), float(element.attrib['angle-sextic']))
generator = AmoebaAngleGenerator(forceField, element.attrib['angle-cubic'], element.attrib['angle-quartic'], element.attrib['angle-pentic'], element.attrib['angle-sextic'])
forceField._forces.append(generator)
for angle in element.findall('Angle'):
types = forceField._findAtomTypes(angle.attrib, 3)
......@@ -3475,22 +3467,17 @@ class AmoebaAngleGenerator(object):
# get force
existing = [sys.getForce(i) for i in range(sys.getNumForces())]
existing = [f for f in existing if type(f) == mm.AmoebaAngleForce]
energy = "k*(d^2 + %s*d^3 + %s*d^4 + %s*d^5 + %s*d^6); d=%.15g*theta-theta0" % (self.cubic, self.quartic, self.pentic, self.sextic, 180/math.pi)
existing = [f for f in sys.getForces() if type(f) == mm.CustomAngleForce and f.getEnergyFunction() == energy]
if len(existing) == 0:
force = mm.AmoebaAngleForce()
force = mm.CustomAngleForce(energy)
force.addPerAngleParameter('theta0')
force.addPerAngleParameter('k')
sys.addForce(force)
else:
force = existing[0]
# set scalars
force.setAmoebaGlobalAngleCubic(self.cubic)
force.setAmoebaGlobalAngleQuartic(self.quartic)
force.setAmoebaGlobalAnglePentic(self.pentic)
force.setAmoebaGlobalAngleSextic(self.sextic)
DEG_TO_RAD = math.pi / 180
for angleDict in angleList:
......@@ -3530,7 +3517,7 @@ class AmoebaAngleGenerator(object):
angleValue = self.angle[i][0]
angleDict['idealAngle'] = angleValue
force.addAngle(angle[0], angle[1], angle[2], angleValue, self.k[i])
force.addAngle(angle[0], angle[1], angle[2], [angleValue, self.k[i]])
break
#=============================================================================================
......@@ -3542,22 +3529,24 @@ class AmoebaAngleGenerator(object):
# get force
existing = [sys.getForce(i) for i in range(sys.getNumForces())]
existing = [f for f in existing if type(f) == mm.AmoebaInPlaneAngleForce]
energy = """k*(d^2 + %s*d^3 + %s*d^4 + %s*d^5 + %s*d^6); d=theta-theta0;
theta = %.15g*pointangle(x1, y1, z1, projx, projy, projz, x3, y3, z3);
projx = x2-nx*dot; projy = y2-ny*dot; projz = z2-nz*dot;
dot = nx*(x2-x3) + ny*(y2-y3) + nz*(z2-z3);
nx = px/norm; ny = py/norm; nz = pz/norm;
norm = sqrt(px*px + py*py + pz*pz);
px = (d1y*d2z-d1z*d2y); py = (d1z*d2x-d1x*d2z); pz = (d1x*d2y-d1y*d2x);
d1x = x1-x4; d1y = y1-y4; d1z = z1-z4;
d2x = x3-x4; d2y = y3-y4; d2z = z3-z4""" % (self.cubic, self.quartic, self.pentic, self.sextic, 180/math.pi)
existing = [f for f in sys.getForces() if type(f) == mm.CustomCompoundBondForce and f.getEnergyFunction() == energy]
if len(existing) == 0:
force = mm.AmoebaInPlaneAngleForce()
force = mm.CustomCompoundBondForce(4, energy)
force.addPerBondParameter("theta0")
force.addPerBondParameter("k")
sys.addForce(force)
else:
force = existing[0]
# scalars
force.setAmoebaGlobalInPlaneAngleCubic(self.cubic)
force.setAmoebaGlobalInPlaneAngleQuartic(self.quartic)
force.setAmoebaGlobalInPlaneAnglePentic(self.pentic)
force.setAmoebaGlobalInPlaneAngleSextic(self.sextic)
for angleDict in angleList:
angle = angleDict['angle']
......@@ -3578,7 +3567,7 @@ class AmoebaAngleGenerator(object):
if (isConstrained and self.k[i] != 0.0):
addAngleConstraint(angle, self.angle[i][0]*math.pi/180.0, data, sys)
if self.k[i] != 0.0 and (not isConstrained or args.get('flexibleConstraints', False)):
force.addAngle(angle[0], angle[1], angle[2], angle[3], self.angle[i][0], self.k[i])
force.addBond((angle[0], angle[1], angle[2], angle[3]), (self.angle[i][0], self.k[i]))
break
parsers["AmoebaAngleForce"] = AmoebaAngleGenerator.parseElement
......@@ -3704,21 +3693,23 @@ class AmoebaOutOfPlaneBendGenerator(object):
# get force
existing = [sys.getForce(i) for i in range(sys.getNumForces())]
existing = [f for f in existing if type(f) == mm.AmoebaOutOfPlaneBendForce]
energy = """k*(theta^2 + %s*theta^3 + %s*theta^4 + %s*theta^5 + %s*theta^6);
theta = %.15g*pointangle(x2, y2, z2, x4, y4, z4, projx, projy, projz);
projx = x2-nx*dot; projy = y2-ny*dot; projz = z2-nz*dot;
dot = nx*(x2-x3) + ny*(y2-y3) + nz*(z2-z3);
nx = px/norm; ny = py/norm; nz = pz/norm;
norm = sqrt(px*px + py*py + pz*pz);
px = (d1y*d2z-d1z*d2y); py = (d1z*d2x-d1x*d2z); pz = (d1x*d2y-d1y*d2x);
d1x = x1-x4; d1y = y1-y4; d1z = z1-z4;
d2x = x3-x4; d2y = y3-y4; d2z = z3-z4""" % (self.cubic, self.quartic, self.pentic, self.sextic, 180/math.pi)
existing = [f for f in sys.getForces() if type(f) == mm.CustomCompoundBondForce and f.getEnergyFunction() == energy]
if len(existing) == 0:
force = mm.AmoebaOutOfPlaneBendForce()
force = mm.CustomCompoundBondForce(4, energy)
force.addPerBondParameter("k")
sys.addForce(force)
else:
force = existing[0]
# set scalars
force.setAmoebaGlobalOutOfPlaneBendCubic( self.cubic)
force.setAmoebaGlobalOutOfPlaneBendQuartic(self.quartic)
force.setAmoebaGlobalOutOfPlaneBendPentic( self.pentic)
force.setAmoebaGlobalOutOfPlaneBendSextic( self.sextic)
# this hash is used to insure the out-of-plane-bend bonds
# are only added once
......@@ -3773,9 +3764,9 @@ class AmoebaOutOfPlaneBendGenerator(object):
if (len(partners) == 3):
force.addOutOfPlaneBend(partners[0], middleAtom, partners[1], partners[2], partnerK[2])
force.addOutOfPlaneBend(partners[0], middleAtom, partners[2], partners[1], partnerK[1])
force.addOutOfPlaneBend(partners[1], middleAtom, partners[2], partners[0], partnerK[0])
force.addBond([partners[0], middleAtom, partners[1], partners[2]], [partnerK[2]])
force.addBond([partners[0], middleAtom, partners[2], partners[1]], [partnerK[1]])
force.addBond([partners[1], middleAtom, partners[2], partners[0]], [partnerK[0]])
# skipAtoms is used to insure angles are only included once
......@@ -3932,8 +3923,7 @@ class AmoebaTorsionGenerator(object):
def createForce(self, sys, data, nontorsionedMethod, nontorsionedCutoff, args):
existing = [sys.getForce(i) for i in range(sys.getNumForces())]
existing = [f for f in existing if type(f) == mm.PeriodicTorsionForce]
existing = [f for f in sys.getForces() if type(f) == mm.PeriodicTorsionForce]
if len(existing) == 0:
force = mm.PeriodicTorsionForce()
sys.addForce(force)
......@@ -4011,11 +4001,19 @@ class AmoebaPiTorsionGenerator(object):
def createForce(self, sys, data, nonpiTorsionedMethod, nonpiTorsionedCutoff, args):
existing = [sys.getForce(i) for i in range(sys.getNumForces())]
existing = [f for f in existing if type(f) == mm.AmoebaPiTorsionForce]
energy = """2*k*sin(phi)^2;
phi = pointdihedral(x3+c1x, y3+c1y, z3+c1z, x3, y3, z3, x4, y4, z4, x4+c2x, y4+c2y, z4+c2z);
c1x = (d14y*d24z-d14z*d24y); c1y = (d14z*d24x-d14x*d24z); c1z = (d14x*d24y-d14y*d24x);
c2x = (d53y*d63z-d53z*d63y); c2y = (d53z*d63x-d53x*d63z); c2z = (d53x*d63y-d53y*d63x);
d14x = x1-x4; d14y = y1-y4; d14z = z1-z4;
d24x = x2-x4; d24y = y2-y4; d24z = z2-z4;
d53x = x5-x3; d53y = y5-y3; d53z = z5-z3;
d63x = x6-x3; d63y = y6-y3; d63z = z6-z3"""
existing = [f for f in sys.getForces() if type(f) == mm.CustomCompoundBondForce and f.getEnergyFunction() == energy]
if len(existing) == 0:
force = mm.AmoebaPiTorsionForce()
force = mm.CustomCompoundBondForce(6, energy)
force.addPerBondParameter('k')
sys.addForce(force)
else:
force = existing[0]
......@@ -4077,7 +4075,7 @@ class AmoebaPiTorsionGenerator(object):
else:
piTorsionAtom6 = b1
force.addPiTorsion(piTorsionAtom1, piTorsionAtom2, piTorsionAtom3, piTorsionAtom4, piTorsionAtom5, piTorsionAtom6, self.k[i])
force.addBond([piTorsionAtom1, piTorsionAtom2, piTorsionAtom3, piTorsionAtom4, piTorsionAtom5, piTorsionAtom6], [self.k[i]])
parsers["AmoebaPiTorsionForce"] = AmoebaPiTorsionGenerator.parseElement
......@@ -4251,8 +4249,7 @@ class AmoebaTorsionTorsionGenerator(object):
def createForce(self, sys, data, nonpiTorsionedMethod, nonpiTorsionedCutoff, args):
existing = [sys.getForce(i) for i in range(sys.getNumForces())]
existing = [f for f in existing if type(f) == mm.AmoebaTorsionTorsionForce]
existing = [f for f in sys.getForces() if type(f) == mm.AmoebaTorsionTorsionForce]
if len(existing) == 0:
force = mm.AmoebaTorsionTorsionForce()
......@@ -4392,10 +4389,15 @@ class AmoebaStretchBendGenerator(object):
def createForcePostAmoebaBondForce(self, sys, data, nonbondedMethod, nonbondedCutoff, angleList, args):
existing = [sys.getForce(i) for i in range(sys.getNumForces())]
existing = [f for f in existing if type(f) == mm.AmoebaStretchBendForce]
energy = "(k1*(distance(p1,p2)-r12) + k2*(distance(p2,p3)-r23))*(%.15g*(angle(p1,p2,p3)-theta0))" % (180/math.pi)
existing = [f for f in sys.getForces() if type(f) == mm.CustomCompoundBondForce and f.getEnergyFunction() == energy]
if len(existing) == 0:
force = mm.AmoebaStretchBendForce()
force = mm.CustomCompoundBondForce(3, energy)
force.addPerBondParameter("r12")
force.addPerBondParameter("r23")
force.addPerBondParameter("theta0")
force.addPerBondParameter("k1")
force.addPerBondParameter("k2")
sys.addForce(force)
else:
force = existing[0]
......@@ -4457,7 +4459,7 @@ class AmoebaStretchBendGenerator(object):
raise ValueError(outputString)
else:
force.addStretchBend(angle[0], angle[1], angle[2], bondAB, bondCB, angleDict['idealAngle']/radian, self.k1[i], self.k2[i])
force.addBond((angle[0], angle[1], angle[2]), (bondAB, bondCB, angleDict['idealAngle']/radian, self.k1[i], self.k2[i]))
break
......@@ -5289,8 +5291,7 @@ class AmoebaWcaDispersionGenerator(object):
# get or create force depending on whether it has already been added to the system
existing = [sys.getForce(i) for i in range(sys.getNumForces())]
existing = [f for f in existing if type(f) == mm.AmoebaWcaDispersionForce]
existing = [f for f in sys.getForces() if type(f) == mm.AmoebaWcaDispersionForce]
if len(existing) == 0:
force = mm.AmoebaWcaDispersionForce()
sys.addForce(force)
......@@ -5519,8 +5520,7 @@ class AmoebaGeneralizedKirkwoodGenerator(object):
# check if AmoebaMultipoleForce exists since charges needed
# if it has not been created, raise an error
existing = [sys.getForce(i) for i in range(sys.getNumForces())]
amoebaMultipoleForceList = [f for f in existing if type(f) == mm.AmoebaMultipoleForce]
amoebaMultipoleForceList = [f for f in sys.getForces() if type(f) == mm.AmoebaMultipoleForce]
if (len(amoebaMultipoleForceList) > 0):
amoebaMultipoleForce = amoebaMultipoleForceList[0]
else:
......@@ -5532,7 +5532,7 @@ class AmoebaGeneralizedKirkwoodGenerator(object):
# get or create force depending on whether it has already been added to the system
existing = [f for f in existing if type(f) == mm.AmoebaGeneralizedKirkwoodForce]
existing = [f for f in sys.getForces() if type(f) == mm.AmoebaGeneralizedKirkwoodForce]
if len(existing) == 0:
force = mm.AmoebaGeneralizedKirkwoodForce()
......@@ -5624,8 +5624,7 @@ class AmoebaUreyBradleyGenerator(object):
def createForce(self, sys, data, nonbondedMethod, nonbondedCutoff, args):
existing = [sys.getForce(i) for i in range(sys.getNumForces())]
existing = [f for f in existing if type(f) == mm.HarmonicBondForce]
existing = [f for f in sys.getForces() if type(f) == mm.HarmonicBondForce]
if len(existing) == 0:
force = mm.HarmonicBondForce()
......
......@@ -26,13 +26,7 @@ SKIP_METHODS = [('State', 'getPositions'),
('BondInfo',),
('BondParameterInfo',),
('CalcAmoebaGeneralizedKirkwoodForceKernel',),
('CalcAmoebaAngleForceKernel',),
('CalcAmoebaBondForceKernel',),
('CalcAmoebaInPlaneAngleForceKernel',),
('CalcAmoebaMultipoleForceKernel',),
('CalcAmoebaOutOfPlaneBendForceKernel',),
('CalcAmoebaPiTorsionForceKernel',),
('CalcAmoebaStretchBendForceKernel',),
('CalcAmoebaTorsionTorsionForceKernel',),
('CalcAmoebaVdwForceKernel',),
('CalcAmoebaWcaDispersionForceKernel',),
......@@ -73,18 +67,15 @@ SKIP_METHODS = [('State', 'getPositions'),
('KernelFactory',),
('KernelImpl',),
('MultipoleInfo',),
('OutOfPlaneBendInfo',),
('ParameterInfo',),
('ParticleInfo',),
('PeriodicTorsionInfo',),
('PerParticleParameterInfo',),
('PiTorsionInfo',),
('PlatformData',),
('RBTorsionInfo',),
('RemoveCMMotionKernel',),
('SplineFitter',),
('StreamFactory',),
('StretchBendInfo',),
('TorsionInfo',),
('TorsionTorsionGridInfo',),
('TorsionTorsionInfo',),
......@@ -199,7 +190,6 @@ UNITS = {
("*", "getName") : (None, ()),
("*", "getNumAngles") : (None, ()),
("*", "getNumBonds") : (None, ()),
("*", "getNumPiTorsions") : (None, ()),
("*", "getNumConstraints") : (None, ()),
("*", "getNumExceptions") : (None, ()),
("*", "getNumForces") : (None, ()),
......@@ -255,22 +245,6 @@ UNITS = {
("AmoebaGeneralizedKirkwoodForce", "getProbeRadius") : ( 'unit.nanometer', ()),
("AmoebaGeneralizedKirkwoodForce", "getSurfaceAreaFactor") : ( 'unit.kilojoule_per_mole/(unit.nanometer*unit.nanometer)',()),
("AmoebaAngleForce", "getAmoebaGlobalAngleCubic") : ( '1/unit.radian',()),
("AmoebaAngleForce", "getAmoebaGlobalAngleQuartic") : ( '1/unit.radian**2',()),
("AmoebaAngleForce", "getAmoebaGlobalAnglePentic") : ( '1/unit.radian**3',()),
("AmoebaAngleForce", "getAmoebaGlobalAngleSextic") : ( '1/unit.radian**4',()),
("AmoebaAngleForce", "getAngleParameters") : ( None, (None, None, None, 'unit.degree', 'unit.kilojoule_per_mole/(unit.radian*unit.radian)')),
("AmoebaBondForce", "getAmoebaGlobalBondCubic") : ( '1/unit.nanometer',()),
("AmoebaBondForce", "getAmoebaGlobalBondQuartic") : ( '1/unit.nanometer**2',()),
("AmoebaBondForce", "getBondParameters") : ( None, (None, None, 'unit.nanometer', 'unit.kilojoule_per_mole/(unit.nanometer*unit.nanometer)')),
("AmoebaInPlaneAngleForce", "getAmoebaGlobalInPlaneAngleCubic") : ( '1/unit.radian',()),
("AmoebaInPlaneAngleForce", "getAmoebaGlobalInPlaneAngleQuartic") : ( '1/unit.radian**2',()),
("AmoebaInPlaneAngleForce", "getAmoebaGlobalInPlaneAnglePentic") : ( '1/unit.radian**3',()),
("AmoebaInPlaneAngleForce", "getAmoebaGlobalInPlaneAngleSextic") : ( '1/unit.radian**4',()),
("AmoebaInPlaneAngleForce", "getAngleParameters") : ( None, (None, None, None, None, 'unit.radian', 'unit.kilojoule_per_mole/(unit.radian*unit.radian)')),
("AmoebaMultipoleForce", "getNumMultipoles") : ( None,()),
("AmoebaMultipoleForce", "getPolarizationType") : ( None,()),
("AmoebaMultipoleForce", "getCutoffDistance") : ( 'unit.nanometer',()),
......@@ -309,19 +283,6 @@ UNITS = {
("AmoebaMultipoleForce", "getTotalDipoles") : ( None, ()),
("AmoebaMultipoleForce", "getSystemMultipoleMoments") : ( None, ()),
("AmoebaOutOfPlaneBendForce", "getNumOutOfPlaneBends") : ( None, ()),
("AmoebaOutOfPlaneBendForce", "getAmoebaGlobalOutOfPlaneBendCubic") : ( '1/unit.radian',()),
("AmoebaOutOfPlaneBendForce", "getAmoebaGlobalOutOfPlaneBendQuartic") : ( '1/unit.radian**2',()),
("AmoebaOutOfPlaneBendForce", "getAmoebaGlobalOutOfPlaneBendPentic") : ( '1/unit.radian**3',()),
("AmoebaOutOfPlaneBendForce", "getAmoebaGlobalOutOfPlaneBendSextic") : ( '1/unit.radian**4',()),
("AmoebaOutOfPlaneBendForce", "getOutOfPlaneBendParameters") : ( None, (None, None, None, None, 'unit.kilojoule_per_mole/unit.radians**2')),
("AmoebaPiTorsionForce", "getNumPiTorsions") : ( None, ()),
("AmoebaPiTorsionForce", "getPiTorsionParameters") : ( None, (None, None, None, None, None, None, 'unit.kilojoule_per_mole')),
("AmoebaStretchBendForce", "getNumStretchBends") : ( None, ()),
("AmoebaStretchBendForce", "getStretchBendParameters") : ( None, (None, None, None, 'unit.nanometer', 'unit.nanometer', 'unit.radian', 'unit.kilojoule_per_mole/unit.nanometer/unit.radian', 'unit.kilojoule_per_mole/unit.nanometer/unit.radian')),
("AmoebaTorsionTorsionForce", "getNumTorsionTorsions") : ( None, ()),
("AmoebaTorsionTorsionForce", "getNumTorsionTorsionGrids") : ( None, ()),
("AmoebaTorsionTorsionForce", "getTorsionTorsionParameters") : ( None, ()),
......
......@@ -588,80 +588,6 @@ class TestAPIUnits(unittest.TestCase):
self.assertEqual(j, 2)
self.assertEqual(thole, 0.125)
def testAmoebaBondForce(self):
""" Tests the AmoebaBondForce API features """
force1 = AmoebaBondForce()
force2 = AmoebaBondForce()
force1.setAmoebaGlobalBondCubic(1.5)
force2.setAmoebaGlobalBondCubic(1.5/angstrom)
force1.setAmoebaGlobalBondQuartic(1.5)
force2.setAmoebaGlobalBondQuartic(1.5/angstrom**2)
self.assertEqual(force1.getAmoebaGlobalBondCubic(), 1.5/nanometer)
self.assertEqual(force2.getAmoebaGlobalBondCubic(), 1.5/angstrom)
self.assertEqual(force1.getAmoebaGlobalBondQuartic(), 1.5/nanometer**2)
self.assertAlmostEqualUnit(force2.getAmoebaGlobalBondQuartic(), 1.5/angstrom**2)
force1.addBond(0, 1, 0.15, 10.0)
force1.addBond(1, 2, 1.5*angstroms, 10.0*kilocalories_per_mole/angstroms**2)
self.assertEqual(force1.getNumBonds(), 2)
self.assertEqual(force2.getNumBonds(), 0)
i, j, req, k = force1.getBondParameters(0)
self.assertEqual(req, 0.15*nanometers)
self.assertEqual(k, 10.0*kilojoules_per_mole/nanometers**2)
i, j, req, k = force1.getBondParameters(1)
self.assertAlmostEqualUnit(req, 1.5*angstroms)
self.assertAlmostEqualUnit(k, 10.0*kilocalories_per_mole/angstroms**2)
def testAmoebaAngleForce(self):
""" Tests the AmoebaAngleForce API features """
force = AmoebaAngleForce()
force.setAmoebaGlobalAngleCubic(1.0)
force.setAmoebaGlobalAngleQuartic(2.0/radians**2)
force.setAmoebaGlobalAnglePentic(3.0/degrees**3)
force.setAmoebaGlobalAngleSextic(4.0)
self.assertEqual(force.getAmoebaGlobalAngleCubic(), 1.0/radians)
self.assertEqual(force.getAmoebaGlobalAngleQuartic(), 2.0/radians**2)
self.assertAlmostEqualUnit(force.getAmoebaGlobalAnglePentic(), 3.0/degrees**3)
self.assertEqual(force.getAmoebaGlobalAngleSextic(), 4.0/radians**4)
force.addAngle(0, 1, 2, math.pi*radians, 1.5*kilocalories_per_mole/radians**2)
force.addAngle(1, 2, 3, 180*degrees, 1.5*kilocalories_per_mole/radians**2)
force.addAngle(2, 3, 4, 109.4, 1.5)
self.assertEqual(force.getNumAngles(), 3)
i, j, k, t, tk = force.getAngleParameters(0)
self.assertEqual(i, 0)
self.assertEqual(j, 1)
self.assertEqual(k, 2)
self.assertAlmostEqualUnit(t, math.pi*radians)
self.assertIs(t.unit, degree)
self.assertAlmostEqualUnit(tk, 1.5*kilocalories_per_mole/radians**2)
self.assertIs(tk.unit, kilojoules_per_mole/radians**2)
i, j, k, t, tk = force.getAngleParameters(1)
self.assertEqual(i, 1)
self.assertEqual(j, 2)
self.assertEqual(k, 3)
self.assertAlmostEqualUnit(t, 180*degrees)
self.assertIs(t.unit, degree)
self.assertAlmostEqualUnit(tk, 1.5*kilocalories_per_mole/radians**2)
self.assertIs(tk.unit, kilojoules_per_mole/radians**2)
i, j, k, t, tk = force.getAngleParameters(2)
self.assertEqual(i, 2)
self.assertEqual(j, 3)
self.assertEqual(k, 4)
self.assertAlmostEqualUnit(t, 109.4*degrees)
self.assertIs(t.unit, degree)
self.assertAlmostEqualUnit(tk, 1.5*kilojoules_per_mole/radians**2)
self.assertIs(tk.unit, kilojoules_per_mole/radians**2)
def testGeneralizedKirkwood(self):
""" Tests the AmoebaGeneralizedKirkwoodForce API features """
force = AmoebaGeneralizedKirkwoodForce()
......@@ -707,162 +633,6 @@ class TestAPIUnits(unittest.TestCase):
self.assertIs(r.unit, nanometer)
self.assertEqual(s, 0.4)
def testAmoebaInPlaneAngleForce(self):
""" Tests the AmoebaInPlaneAngleForce API features """
force = AmoebaInPlaneAngleForce()
force.setAmoebaGlobalInPlaneAngleCubic(1.0)
self.assertEqual(force.getAmoebaGlobalInPlaneAngleCubic(), 1/radian)
self.assertEqual(str(force.getAmoebaGlobalInPlaneAngleCubic().unit), '/radian')
force.setAmoebaGlobalInPlaneAngleQuartic(1.0/degrees**2)
self.assertAlmostEqualUnit(force.getAmoebaGlobalInPlaneAngleQuartic(), 1/degrees**2)
self.assertEqual(str(force.getAmoebaGlobalInPlaneAngleQuartic().unit), '/(radian**2)')
force.setAmoebaGlobalInPlaneAnglePentic(1.0/radians**3)
self.assertEqual(force.getAmoebaGlobalInPlaneAnglePentic(), 1/radian**3)
self.assertEqual(str(force.getAmoebaGlobalInPlaneAnglePentic().unit), '/(radian**3)')
force.setAmoebaGlobalInPlaneAngleSextic(1.0/radians**4)
self.assertEqual(force.getAmoebaGlobalInPlaneAngleSextic(), 1/radian**4)
self.assertEqual(str(force.getAmoebaGlobalInPlaneAngleSextic().unit), '/(radian**4)')
force.addAngle(0, 1, 2, 3, math.pi, 1.0)
force.addAngle(1, 2, 3, 4, 180*degrees, 1.0*kilocalories_per_mole/radians**2)
self.assertEqual(force.getNumAngles(), 2)
i, j, k, l, t, tk = force.getAngleParameters(0)
self.assertEqual(i, 0)
self.assertEqual(j, 1)
self.assertEqual(k, 2)
self.assertEqual(l, 3)
self.assertEqual(t, math.pi*radians)
self.assertIs(t.unit, radians)
self.assertEqual(tk, 1.0*kilojoules_per_mole/radians**2)
self.assertIs(tk.unit, kilojoules_per_mole/radians**2)
i, j, k, l, t, tk = force.getAngleParameters(1)
self.assertEqual(i, 1)
self.assertEqual(j, 2)
self.assertEqual(k, 3)
self.assertEqual(l, 4)
self.assertEqual(t, 180*degrees)
self.assertIs(t.unit, radians)
self.assertEqual(tk, 1.0*kilocalorie_per_mole/radians**2)
self.assertIs(tk.unit, kilojoules_per_mole/radians**2)
def testAmoebaOutOfPlaneBendForce(self):
""" Tests the AmoebaOutOfPlaneBendForce API features """
force = AmoebaOutOfPlaneBendForce()
force.setAmoebaGlobalOutOfPlaneBendCubic(1.0)
self.assertEqual(force.getAmoebaGlobalOutOfPlaneBendCubic(), 1/radian)
self.assertEqual(str(force.getAmoebaGlobalOutOfPlaneBendCubic().unit), '/radian')
force.setAmoebaGlobalOutOfPlaneBendQuartic(1.0/degrees**2)
self.assertAlmostEqualUnit(force.getAmoebaGlobalOutOfPlaneBendQuartic(), 1/degrees**2)
self.assertEqual(str(force.getAmoebaGlobalOutOfPlaneBendQuartic().unit), '/(radian**2)')
force.setAmoebaGlobalOutOfPlaneBendPentic(1.0/radians**3)
self.assertEqual(force.getAmoebaGlobalOutOfPlaneBendPentic(), 1/radian**3)
self.assertEqual(str(force.getAmoebaGlobalOutOfPlaneBendPentic().unit), '/(radian**3)')
force.setAmoebaGlobalOutOfPlaneBendSextic(1.0/radians**4)
self.assertEqual(force.getAmoebaGlobalOutOfPlaneBendSextic(), 1/radian**4)
self.assertEqual(str(force.getAmoebaGlobalOutOfPlaneBendSextic().unit), '/(radian**4)')
force.addOutOfPlaneBend(0, 1, 2, 3, 1.0)
force.addOutOfPlaneBend(1, 2, 3, 4, 1.0*kilocalories_per_mole/radians**2)
self.assertEqual(force.getNumOutOfPlaneBends(), 2)
i, j, k, l, tk = force.getOutOfPlaneBendParameters(0)
self.assertEqual(i, 0)
self.assertEqual(j, 1)
self.assertEqual(k, 2)
self.assertEqual(l, 3)
self.assertEqual(tk, 1.0*kilojoules_per_mole/radians**2)
self.assertIs(tk.unit, kilojoules_per_mole/radians**2)
i, j, k, l, tk = force.getOutOfPlaneBendParameters(1)
self.assertEqual(i, 1)
self.assertEqual(j, 2)
self.assertEqual(k, 3)
self.assertEqual(l, 4)
self.assertEqual(tk, 1.0*kilocalorie_per_mole/radians**2)
self.assertIs(tk.unit, kilojoules_per_mole/radians**2)
def testAmoebaPiTorsionForce(self):
""" Tests the AmoebaPiTorsionForce API features """
force = AmoebaPiTorsionForce()
force.addPiTorsion(0, 1, 2, 3, 4, 5, 1.0)
force.addPiTorsion(1, 2, 3, 4, 5, 6, 1.0*kilocalories_per_mole)
self.assertEqual(force.getNumPiTorsions(), 2)
i, j, k, l, m, n, tk = force.getPiTorsionParameters(0)
self.assertEqual(i, 0)
self.assertEqual(j, 1)
self.assertEqual(k, 2)
self.assertEqual(l, 3)
self.assertEqual(m, 4)
self.assertEqual(n, 5)
self.assertEqual(tk, 1.0*kilojoules_per_mole)
self.assertIs(tk.unit, kilojoule_per_mole)
i, j, k, l, m, n, tk = force.getPiTorsionParameters(1)
self.assertEqual(i, 1)
self.assertEqual(j, 2)
self.assertEqual(k, 3)
self.assertEqual(l, 4)
self.assertEqual(m, 5)
self.assertEqual(n, 6)
self.assertEqual(tk, 1.0*kilocalories_per_mole)
self.assertIs(tk.unit, kilojoule_per_mole)
def testAmoebaStretchBendForce(self):
""" Tests the AmoebaStretchBendForce API features """
force = AmoebaStretchBendForce()
force.addStretchBend(0, 1, 2, 0.10, 0.12, math.pi/2, 10.0, 12.0)
force.addStretchBend(1, 2, 3, 1.0*angstroms, 1.2*angstroms, 60*degrees,
10.0*kilocalories_per_mole/angstroms/radians,
12.0*kilocalories_per_mole/angstroms/radians)
self.assertEqual(force.getNumStretchBends(), 2)
i, j, k, r1, r2, t, k1, k2 = force.getStretchBendParameters(0)
self.assertEqual(i, 0)
self.assertEqual(j, 1)
self.assertEqual(k, 2)
self.assertEqual(r1, 0.1*nanometers)
self.assertIs(r1.unit, nanometers)
self.assertEqual(r2, 0.12*nanometers)
self.assertIs(r2.unit, nanometers)
self.assertEqual(t, math.pi/2*radians)
self.assertIs(t.unit, radians)
self.assertEqual(k1, 10*kilojoules_per_mole/nanometers/radians)
self.assertIs(k1.unit, kilojoules_per_mole/nanometers/radians)
self.assertEqual(k2, 12*kilojoules_per_mole/nanometers/radians)
self.assertIs(k2.unit, kilojoules_per_mole/nanometers/radians)
i, j, k, r1, r2, t, k1, k2 = force.getStretchBendParameters(1)
self.assertEqual(i, 1)
self.assertEqual(j, 2)
self.assertEqual(k, 3)
self.assertEqual(r1, 1.0*angstroms)
self.assertIs(r1.unit, nanometers)
self.assertEqual(r2, 1.2*angstroms)
self.assertIs(r2.unit, nanometers)
self.assertAlmostEqualUnit(t, 60*degrees)
self.assertIs(t.unit, radians)
self.assertEqual(k1, 10*kilocalories_per_mole/angstroms/radians)
self.assertIs(k1.unit, kilojoules_per_mole/nanometers/radians)
self.assertEqual(k2, 12*kilocalories_per_mole/angstroms/radians)
self.assertIs(k2.unit, kilojoules_per_mole/nanometers/radians)
def testAmoebaTorsionTorsionForce(self):
""" Tests the AmoebaTorsionTorsionForce API features """
force = AmoebaTorsionTorsionForce()
......
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