Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
tsoc
openmm
Commits
861387aa
Commit
861387aa
authored
Jun 22, 2016
by
peastman
Browse files
Bug fixes and cleanup to LennardJonesGenerator
parent
2523d0cd
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
209 additions
and
121 deletions
+209
-121
wrappers/python/simtk/openmm/app/forcefield.py
wrappers/python/simtk/openmm/app/forcefield.py
+87
-60
wrappers/python/tests/TestForceField.py
wrappers/python/tests/TestForceField.py
+122
-61
No files found.
wrappers/python/simtk/openmm/app/forcefield.py
View file @
861387aa
...
@@ -2157,14 +2157,16 @@ class NonbondedGenerator(object):
...
@@ -2157,14 +2157,16 @@ class NonbondedGenerator(object):
parsers
[
"NonbondedForce"
]
=
NonbondedGenerator
.
parseElement
parsers
[
"NonbondedForce"
]
=
NonbondedGenerator
.
parseElement
## @private
class
LennardJonesGenerator
(
object
):
class
LennardJonesGenerator
(
object
):
"""A NBFix generator to construct the L-J force with NBFIX implemented as a lookup table"""
"""A NBFix generator to construct the L-J force with NBFIX implemented as a lookup table"""
def
__init__
(
self
,
forcefield
,
lj14scale
):
def
__init__
(
self
,
forcefield
,
lj14scale
):
self
.
ff
=
forcefield
self
.
ff
=
forcefield
self
.
nbfix
_t
ypes
=
{}
self
.
nbfix
T
ypes
=
{}
self
.
lj14scale
=
lj14scale
self
.
lj14scale
=
lj14scale
self
.
lj
_t
ypes
=
ForceField
.
_AtomTypeParameters
(
forcefield
,
'LennardJonesForce'
,
'Atom'
,
(
'sigma'
,
'epsilon'
))
self
.
lj
T
ypes
=
ForceField
.
_AtomTypeParameters
(
forcefield
,
'LennardJonesForce'
,
'Atom'
,
(
'sigma'
,
'epsilon'
))
def
registerNBFIX
(
self
,
parameters
):
def
registerNBFIX
(
self
,
parameters
):
types
=
self
.
ff
.
_findAtomTypes
(
parameters
,
2
)
types
=
self
.
ff
.
_findAtomTypes
(
parameters
,
2
)
...
@@ -2173,12 +2175,11 @@ class LennardJonesGenerator(object):
...
@@ -2173,12 +2175,11 @@ class LennardJonesGenerator(object):
type2
=
types
[
1
][
0
]
type2
=
types
[
1
][
0
]
epsilon
=
_convertParameterToNumber
(
parameters
[
'epsilon'
])
epsilon
=
_convertParameterToNumber
(
parameters
[
'epsilon'
])
sigma
=
_convertParameterToNumber
(
parameters
[
'sigma'
])
sigma
=
_convertParameterToNumber
(
parameters
[
'sigma'
])
self
.
nbfix
_t
ypes
[(
type1
,
type2
)]
=
[
sigma
,
epsilon
]
self
.
nbfix
T
ypes
[(
type1
,
type2
)]
=
[
sigma
,
epsilon
]
self
.
nbfix
_t
ypes
[(
type2
,
type1
)]
=
[
sigma
,
epsilon
]
self
.
nbfix
T
ypes
[(
type2
,
type1
)]
=
[
sigma
,
epsilon
]
def
registerLennardJones
(
self
,
parameters
):
def
registerLennardJones
(
self
,
parameters
):
self
.
lj_types
.
registerAtom
(
parameters
)
self
.
ljTypes
.
registerAtom
(
parameters
)
@
staticmethod
@
staticmethod
def
parseElement
(
element
,
ff
):
def
parseElement
(
element
,
ff
):
...
@@ -2189,93 +2190,87 @@ class LennardJonesGenerator(object):
...
@@ -2189,93 +2190,87 @@ class LennardJonesGenerator(object):
else
:
else
:
# Multiple <LennardJonesForce> tags were found, probably in different files
# Multiple <LennardJonesForce> tags were found, probably in different files
generator
=
existing
[
0
]
generator
=
existing
[
0
]
if
abs
(
generator
.
lj14scale
-
float
(
element
.
attrib
[
'lj14scale'
]))
>
NonbondedGenerator
.
SCALETOL
:
raise
ValueError
(
'Found multiple LennardJonesForce tags with different 1-4 scales'
)
for
LJ
in
element
.
findall
(
'Atom'
):
for
LJ
in
element
.
findall
(
'Atom'
):
generator
.
registerLennardJones
(
LJ
.
attrib
)
generator
.
registerLennardJones
(
LJ
.
attrib
)
for
Nbfix
in
element
.
findall
(
'NBFixPair'
):
for
Nbfix
in
element
.
findall
(
'NBFixPair'
):
generator
.
registerNBFIX
(
Nbfix
.
attrib
)
generator
.
registerNBFIX
(
Nbfix
.
attrib
)
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
# Ewald and PME will be interpreted as CutoffPeriodic for the CustomNonbondedForce
# We need a CustomNonbondedForce to implement the NBFIX functionality.
nbfix_type_set
=
set
().
union
(
*
self
.
nbfix_types
)
# First derive the lookup tables
# First derive the lookup tables
lj_indx_list
=
[
None
for
atom
in
data
.
atoms
]
num_lj_types
=
0
nbfixTypeSet
=
set
().
union
(
*
self
.
nbfixTypes
)
lj_type_list
=
[]
ljIndexList
=
[
None
]
*
len
(
data
.
atoms
)
type_map
=
{}
numLjTypes
=
0
ljTypeList
=
[]
typeMap
=
{}
for
i
,
atom
in
enumerate
(
data
.
atoms
):
for
i
,
atom
in
enumerate
(
data
.
atoms
):
atype
=
data
.
atomType
[
atom
]
atype
=
data
.
atomType
[
atom
]
values
=
(
self
.
lj_types
.
paramsForType
[
atype
][
'sigma'
],
self
.
lj_types
.
paramsForType
[
atype
][
'epsilon'
])
values
=
tuple
(
self
.
ljTypes
.
getAtomParameters
(
atom
,
data
))
if
lj_indx_list
[
i
]
is
not
None
:
continue
# ljtype has been assigned an index
if
values
in
typeMap
and
atype
not
in
nbfixTypeSet
:
if
values
in
type_map
and
atype
not
in
nbfix_type_set
:
# Only non-NBFIX types can be compressed
# only non NBFIX types can be compressed
ljIndexList
[
i
]
=
typeMap
[
values
]
lj_indx_list
[
i
]
=
type_map
[
values
]
else
:
else
:
type
_m
ap
[
values
]
=
num
_lj_t
ypes
type
M
ap
[
values
]
=
num
LjT
ypes
lj
_indx_l
ist
[
i
]
=
num
_lj_t
ypes
lj
IndexL
ist
[
i
]
=
num
LjT
ypes
num
_lj_t
ypes
+=
1
num
LjT
ypes
+=
1
lj
_t
ype
_l
ist
.
append
(
atype
)
lj
T
ype
L
ist
.
append
(
atype
)
reverse
_m
ap
=
[
0
for
type_values
in
range
(
len
(
type
_m
ap
)
)]
reverse
M
ap
=
[
0
]
*
len
(
type
M
ap
)
for
type
_v
alue
in
type
_m
ap
:
for
type
V
alue
in
type
M
ap
:
reverse
_m
ap
[
type
_m
ap
[
type
_v
alue
]]
=
type
_v
alue
reverse
M
ap
[
type
M
ap
[
type
V
alue
]]
=
type
V
alue
# Now everything is assigned. Create the A- and B-coefficient arrays
# Now everything is assigned. Create the A- and B-coefficient arrays
acoef
=
[
0
for
i
in
range
(
num_lj_types
*
num_lj_types
)]
acoef
=
[
0
]
*
(
numLjTypes
*
numLjTypes
)
bcoef
=
acoef
[:]
bcoef
=
acoef
[:]
for
m
in
range
(
num
_lj_t
ypes
):
for
m
in
range
(
num
LjT
ypes
):
for
n
in
range
(
num
_lj_t
ypes
):
for
n
in
range
(
num
LjT
ypes
):
pair
=
(
lj
_t
ype
_l
ist
[
m
],
lj
_t
ype
_l
ist
[
n
])
pair
=
(
lj
T
ype
L
ist
[
m
],
lj
T
ype
L
ist
[
n
])
if
pair
in
self
.
nbfix
_t
ypes
:
if
pair
in
self
.
nbfix
T
ypes
:
wdij
=
self
.
nbfix
_t
ypes
[
pair
][
1
]
epsilon
=
self
.
nbfix
T
ypes
[
pair
][
1
]
rij
=
self
.
nbfix
_t
ypes
[
pair
][
0
]
*
2
**
(
1.0
/
6
)
/
2
sigma
=
self
.
nbfix
T
ypes
[
pair
][
0
]
rij6
=
rij
**
6
sigma6
=
sigma
**
6
acoef
[
m
+
num
_lj_t
ypes
*
n
]
=
wdij
*
rij6
**
2
acoef
[
m
+
num
LjT
ypes
*
n
]
=
4
*
epsilon
*
sigma6
*
sigma6
bcoef
[
m
+
num
_lj_t
ypes
*
n
]
=
2
*
wdij
*
rij
6
bcoef
[
m
+
num
LjT
ypes
*
n
]
=
4
*
epsilon
*
sigma
6
continue
continue
else
:
else
:
rij
=
(
reverse_map
[
m
][
0
]
+
reverse_map
[
n
][
0
])
*
2
**
(
1.0
/
6
)
/
2
sigma
=
0.5
*
(
reverseMap
[
m
][
0
]
+
reverseMap
[
n
][
0
])
rij6
=
rij
**
6
sigma6
=
sigma
**
6
wdij
=
math
.
sqrt
(
reverse_map
[
m
][
-
1
]
*
reverse_map
[
n
][
-
1
])
epsilon
=
math
.
sqrt
(
reverseMap
[
m
][
-
1
]
*
reverseMap
[
n
][
-
1
])
acoef
[
m
+
num_lj_types
*
n
]
=
wdij
*
rij6
**
2
acoef
[
m
+
numLjTypes
*
n
]
=
4
*
epsilon
*
sigma6
*
sigma6
bcoef
[
m
+
num_lj_types
*
n
]
=
2
*
wdij
*
rij6
bcoef
[
m
+
numLjTypes
*
n
]
=
4
*
epsilon
*
sigma6
self
.
force
=
mm
.
CustomNonbondedForce
(
'a/r^12-b/r^6;'
self
.
force
=
mm
.
CustomNonbondedForce
(
'acoef(type1, type2)/r^12 - bcoef(type1, type2)/r^6;'
)
'a=acoef(type1, type2);'
self
.
force
.
addTabulatedFunction
(
'acoef'
,
mm
.
Discrete2DFunction
(
numLjTypes
,
numLjTypes
,
acoef
))
'b=bcoef(type1, type2)'
)
self
.
force
.
addTabulatedFunction
(
'bcoef'
,
mm
.
Discrete2DFunction
(
numLjTypes
,
numLjTypes
,
bcoef
))
self
.
force
.
addTabulatedFunction
(
'acoef'
,
mm
.
Discrete2DFunction
(
num_lj_types
,
num_lj_types
,
acoef
))
self
.
force
.
addTabulatedFunction
(
'bcoef'
,
mm
.
Discrete2DFunction
(
num_lj_types
,
num_lj_types
,
bcoef
))
self
.
force
.
addPerParticleParameter
(
'type'
)
self
.
force
.
addPerParticleParameter
(
'type'
)
if
(
nonbondedMethod
is
PME
or
nonbondedMethod
is
Ewald
or
if
nonbondedMethod
in
[
CutoffPeriodic
,
Ewald
,
PME
]:
nonbondedMethod
is
CutoffPeriodic
):
self
.
force
.
setNonbondedMethod
(
mm
.
CustomNonbondedForce
.
CutoffPeriodic
)
self
.
force
.
setNonbondedMethod
(
mm
.
CustomNonbondedForce
.
CutoffPeriodic
)
elif
nonbondedMethod
is
NoCutoff
:
elif
nonbondedMethod
is
NoCutoff
:
self
.
force
.
setNonbondedMethod
(
mm
.
CustomNonbondedForce
.
NoCutoff
)
self
.
force
.
setNonbondedMethod
(
mm
.
CustomNonbondedForce
.
NoCutoff
)
elif
nonbondedMethod
is
CutoffNonPeriodic
:
elif
nonbondedMethod
is
CutoffNonPeriodic
:
self
.
force
.
setNonbondedMethod
(
mm
.
CustomNonbondedForce
.
CutoffNonPeriodic
)
self
.
force
.
setNonbondedMethod
(
mm
.
CustomNonbondedForce
.
CutoffNonPeriodic
)
else
:
else
:
raise
AssertionError
(
'Unrecognized nonbonded method [%s]'
%
raise
AssertionError
(
'Unrecognized nonbonded method [%s]'
%
nonbondedMethod
)
nonbondedMethod
)
# Add the particles
# Add the particles
for
i
in
lj_indx_list
:
for
i
in
ljIndexList
:
self
.
force
.
addParticle
((
i
,))
self
.
force
.
addParticle
((
i
,))
self
.
force
.
setUseLongRangeCorrection
(
True
)
self
.
force
.
setUseLongRangeCorrection
(
True
)
self
.
force
.
setCutoffDistance
(
nonbondedCutoff
)
self
.
force
.
setCutoffDistance
(
nonbondedCutoff
)
sys
.
addForce
(
self
.
force
)
sys
.
addForce
(
self
.
force
)
def
postprocessSystem
(
self
,
sys
,
data
,
args
):
def
postprocessSystem
(
self
,
sys
,
data
,
args
):
# Create exceptions based on bonds.
bondIndices
=
[]
bondIndices
=
[]
for
bond
in
data
.
bonds
:
for
bond
in
data
.
bonds
:
bondIndices
.
append
((
bond
.
atom1
,
bond
.
atom2
))
bondIndices
.
append
((
bond
.
atom1
,
bond
.
atom2
))
# If a virtual site does *not* share exclusions with another atom, add a bond between it and its first parent
# If a virtual site does *not* share exclusions with another atom, add a bond between it and its first parent
atom.
# atom.
for
i
in
range
(
sys
.
getNumParticles
()):
for
i
in
range
(
sys
.
getNumParticles
()):
if
sys
.
isVirtualSite
(
i
):
if
sys
.
isVirtualSite
(
i
):
(
site
,
atoms
,
excludeWith
)
=
data
.
virtualSites
[
data
.
atoms
[
i
]]
(
site
,
atoms
,
excludeWith
)
=
data
.
virtualSites
[
data
.
atoms
[
i
]]
...
@@ -2294,10 +2289,42 @@ class LennardJonesGenerator(object):
...
@@ -2294,10 +2289,42 @@ class LennardJonesGenerator(object):
bondIndices
.
append
((
atom1
,
child2
))
bondIndices
.
append
((
atom1
,
child2
))
# Create the exceptions.
# Create the exceptions.
self
.
force
.
createExclusionsFromBonds
(
bondIndices
,
3
)
if
self
.
lj14scale
==
1
:
# Just exclude the 1-2 and 1-3 interactions.
self
.
force
.
createExclusionsFromBonds
(
bondIndices
,
3
)
else
:
forceCopy
=
deepcopy
(
self
.
force
)
forceCopy
.
createExclusionsFromBonds
(
bondIndices
,
2
)
self
.
force
.
createExclusionsFromBonds
(
bondIndices
,
3
)
if
self
.
force
.
getNumExclusions
()
>
forceCopy
.
getNumExclusions
()
and
self
.
lj14scale
!=
0
:
# We need to create a CustomBondForce and use it to implement the scaled 1-4 interactions.
bonded
=
mm
.
CustomBondForce
(
'%g*epsilon*((sigma/r)^12-(sigma/r)^6)'
%
(
4
*
self
.
lj14scale
))
bonded
.
addPerBondParameter
(
'sigma'
)
bonded
.
addPerBondParameter
(
'epsilon'
)
sys
.
addForce
(
bonded
)
skip
=
set
(
tuple
(
forceCopy
.
getExclusionParticles
(
i
))
for
i
in
range
(
forceCopy
.
getNumExclusions
()))
for
i
in
range
(
self
.
force
.
getNumExclusions
()):
p1
,
p2
=
self
.
force
.
getExclusionParticles
(
i
)
a1
=
data
.
atoms
[
p1
]
a2
=
data
.
atoms
[
p2
]
if
(
p1
,
p2
)
not
in
skip
and
(
p2
,
p1
)
not
in
skip
:
type1
=
data
.
atomType
[
a1
]
type2
=
data
.
atomType
[
a2
]
if
(
type1
,
type2
)
in
self
.
nbfixTypes
:
sigma
,
epsilon
=
self
.
nbfixTypes
[(
type1
,
type2
)]
else
:
values1
=
self
.
ljTypes
.
getAtomParameters
(
a1
,
data
)
values2
=
self
.
ljTypes
.
getAtomParameters
(
a2
,
data
)
sigma
=
0.5
*
(
values1
[
0
]
+
values2
[
0
])
epsilon
=
sqrt
(
values1
[
1
]
*
values2
[
1
])
bonded
.
addBond
(
p1
,
p2
,
(
sigma
,
epsilon
))
parsers
[
"LennardJonesForce"
]
=
LennardJonesGenerator
.
parseElement
parsers
[
"LennardJonesForce"
]
=
LennardJonesGenerator
.
parseElement
## @private
## @private
class
GBSAOBCGenerator
(
object
):
class
GBSAOBCGenerator
(
object
):
"""A GBSAOBCGenerator constructs a GBSAOBCForce."""
"""A GBSAOBCGenerator constructs a GBSAOBCForce."""
...
...
wrappers/python/tests/TestForceField.py
View file @
861387aa
...
@@ -626,6 +626,128 @@ class TestForceField(unittest.TestCase):
...
@@ -626,6 +626,128 @@ class TestForceField(unittest.TestCase):
self
.
assertEqual
(
ff
.
_templates
[
'FE2'
].
atoms
[
0
].
type
,
'Fe2+_tip3p_standard'
)
self
.
assertEqual
(
ff
.
_templates
[
'FE2'
].
atoms
[
0
].
type
,
'Fe2+_tip3p_standard'
)
ff
.
createSystem
(
pdb
.
topology
)
ff
.
createSystem
(
pdb
.
topology
)
def
test_LennardJonesGenerator
(
self
):
""" Test the LennardJones generator"""
warnings
.
filterwarnings
(
'ignore'
,
category
=
CharmmPSFWarning
)
psf
=
CharmmPsfFile
(
'systems/ions.psf'
)
pdb
=
PDBFile
(
'systems/ions.pdb'
)
params
=
CharmmParameterSet
(
'systems/toppar_water_ions.str'
)
# Box dimensions (found from bounding box)
psf
.
setBox
(
12.009
*
angstroms
,
12.338
*
angstroms
,
11.510
*
angstroms
)
# Turn off charges so we only test the Lennard-Jones energies
for
a
in
psf
.
atom_list
:
a
.
charge
=
0.0
# Now compute the full energy
plat
=
Platform
.
getPlatformByName
(
'Reference'
)
system
=
psf
.
createSystem
(
params
,
nonbondedMethod
=
PME
,
nonbondedCutoff
=
5
*
angstroms
)
con
=
Context
(
system
,
VerletIntegrator
(
2
*
femtoseconds
),
plat
)
con
.
setPositions
(
pdb
.
positions
)
# Now set up system from ffxml.
xml
=
"""
<ForceField>
<AtomTypes>
<Type name="SOD" class="SOD" element="Na" mass="22.98977"/>
<Type name="CLA" class="CLA" element="Cl" mass="35.45"/>
</AtomTypes>
<Residues>
<Residue name="CLA">
<Atom name="CLA" type="CLA"/>
</Residue>
<Residue name="SOD">
<Atom name="SOD" type="SOD"/>
</Residue>
</Residues>
<LennardJonesForce lj14scale="1.0">
<Atom type="CLA" sigma="0.404468018036" epsilon="0.6276"/>
<Atom type="SOD" sigma="0.251367073323" epsilon="0.1962296"/>
<NBFixPair type1="CLA" type2="SOD" sigma="0.33239431" epsilon="0.350933"/>
</LennardJonesForce>
</ForceField> """
ff
=
ForceField
(
StringIO
(
xml
))
system2
=
ff
.
createSystem
(
pdb
.
topology
,
nonbondedMethod
=
PME
,
nonbondedCutoff
=
5
*
angstroms
)
con2
=
Context
(
system2
,
VerletIntegrator
(
2
*
femtoseconds
),
plat
)
con2
.
setPositions
(
pdb
.
positions
)
state
=
con
.
getState
(
getEnergy
=
True
,
enforcePeriodicBox
=
True
)
ene
=
state
.
getPotentialEnergy
().
value_in_unit
(
kilocalories_per_mole
)
state2
=
con2
.
getState
(
getEnergy
=
True
,
enforcePeriodicBox
=
True
)
ene2
=
state2
.
getPotentialEnergy
().
value_in_unit
(
kilocalories_per_mole
)
self
.
assertAlmostEqual
(
ene
,
ene2
)
def
test_NBFix
(
self
):
"""Test using LennardJonesGenerator to implement NBFix terms."""
# Create a chain of five atoms.
top
=
Topology
()
chain
=
top
.
addChain
()
res
=
top
.
addResidue
(
'RES'
,
chain
)
top
.
addAtom
(
'A'
,
elem
.
oxygen
,
res
)
top
.
addAtom
(
'B'
,
elem
.
carbon
,
res
)
top
.
addAtom
(
'C'
,
elem
.
carbon
,
res
)
top
.
addAtom
(
'D'
,
elem
.
carbon
,
res
)
top
.
addAtom
(
'E'
,
elem
.
nitrogen
,
res
)
atoms
=
list
(
top
.
atoms
())
top
.
addBond
(
atoms
[
0
],
atoms
[
1
])
top
.
addBond
(
atoms
[
1
],
atoms
[
2
])
top
.
addBond
(
atoms
[
2
],
atoms
[
3
])
top
.
addBond
(
atoms
[
3
],
atoms
[
4
])
# Create the force field and system.
xml
=
"""
<ForceField>
<AtomTypes>
<Type name="A" class="A" element="O" mass="1"/>
<Type name="B" class="B" element="C" mass="1"/>
<Type name="C" class="C" element="C" mass="1"/>
<Type name="D" class="D" element="C" mass="1"/>
<Type name="E" class="E" element="N" mass="1"/>
</AtomTypes>
<Residues>
<Residue name="RES">
<Atom name="A" type="A"/>
<Atom name="B" type="B"/>
<Atom name="C" type="C"/>
<Atom name="D" type="D"/>
<Atom name="E" type="E"/>
<Bond atomName1="A" atomName2="B"/>
<Bond atomName1="B" atomName2="C"/>
<Bond atomName1="C" atomName2="D"/>
<Bond atomName1="D" atomName2="E"/>
</Residue>
</Residues>
<LennardJonesForce lj14scale="0.3">
<Atom type="A" sigma="1" epsilon="0.1"/>
<Atom type="B" sigma="2" epsilon="0.2"/>
<Atom type="C" sigma="3" epsilon="0.3"/>
<Atom type="D" sigma="4" epsilon="0.4"/>
<Atom type="E" sigma="5" epsilon="0.5"/>
<NBFixPair type1="A" type2="D" sigma="2.5" epsilon="1.1"/>
<NBFixPair type1="A" type2="E" sigma="3.5" epsilon="1.5"/>
</LennardJonesForce>
</ForceField> """
ff
=
ForceField
(
StringIO
(
xml
))
system
=
ff
.
createSystem
(
top
)
# Check that it produces the correct energy.
integrator
=
VerletIntegrator
(
0.001
)
context
=
Context
(
system
,
integrator
,
Platform
.
getPlatform
(
0
))
positions
=
[
Vec3
(
i
,
0
,
0
)
for
i
in
range
(
5
)]
*
nanometers
context
.
setPositions
(
positions
)
def
ljEnergy
(
sigma
,
epsilon
,
r
):
return
4
*
epsilon
*
((
sigma
/
r
)
**
12
-
(
sigma
/
r
)
**
6
)
expected
=
0.3
*
ljEnergy
(
2.5
,
1.1
,
3
)
+
0.3
*
ljEnergy
(
3.5
,
sqrt
(
0.1
),
3
)
+
ljEnergy
(
3.5
,
1.5
,
4
)
self
.
assertAlmostEqual
(
expected
,
context
.
getState
(
getEnergy
=
True
).
getPotentialEnergy
().
value_in_unit
(
kilojoules_per_mole
))
class
AmoebaTestForceField
(
unittest
.
TestCase
):
class
AmoebaTestForceField
(
unittest
.
TestCase
):
"""Test the ForceField.createSystem() method with the AMOEBA forcefield."""
"""Test the ForceField.createSystem() method with the AMOEBA forcefield."""
...
@@ -713,66 +835,5 @@ class AmoebaTestForceField(unittest.TestCase):
...
@@ -713,66 +835,5 @@ class AmoebaTestForceField(unittest.TestCase):
diff
=
norm
(
f1
-
f2
)
diff
=
norm
(
f1
-
f2
)
self
.
assertTrue
(
diff
<
0.1
or
diff
/
norm
(
f1
)
<
1e-3
)
self
.
assertTrue
(
diff
<
0.1
or
diff
/
norm
(
f1
)
<
1e-3
)
def
test_LennardJones_generator
(
self
):
""" Test the LennardJones generator"""
warnings
.
filterwarnings
(
'ignore'
,
category
=
CharmmPSFWarning
)
psf
=
CharmmPsfFile
(
'systems/ions.psf'
)
pdb
=
PDBFile
(
'systems/ions.pdb'
)
params
=
CharmmParameterSet
(
'systems/toppar_water_ions.str'
)
# Box dimensions (found from bounding box)
psf
.
setBox
(
12.009
*
angstroms
,
12.338
*
angstroms
,
11.510
*
angstroms
)
# Turn off charges so we only test the Lennard-Jones energies
for
a
in
psf
.
atom_list
:
a
.
charge
=
0.0
# Now compute the full energy
plat
=
Platform
.
getPlatformByName
(
'Reference'
)
system
=
psf
.
createSystem
(
params
,
nonbondedMethod
=
PME
,
nonbondedCutoff
=
5
*
angstroms
)
con
=
Context
(
system
,
VerletIntegrator
(
2
*
femtoseconds
),
plat
)
con
.
setPositions
(
pdb
.
positions
)
# Now set up stystem from ffxml. Setting chareges to 0 so we only test the Lennard-Jones energies
xml
=
"""
<ForceField>
<AtomTypes>
<Type name="SOD" class="SOD" element="Na" mass="22.98977"/>
<Type name="CLA" class="CLA" element="Cl" mass="35.45"/>
</AtomTypes>
<Residues>
<Residue name="CLA">
<Atom name="CLA" type="CLA" charge="0.0"/>
</Residue>
<Residue name="SOD">
<Atom name="SOD" type="SOD" charge="0.0"/>
</Residue>
</Residues>
<NonbondedForce coulomb14scale="1.0" lj14scale="1.0">
<UseAttributeFromResidue name="charge"/>
<Atom type="SOD" sigma="1.0" epsilon="0.0"/>
<Atom type="CLA" sigma="1.0" epsilon="0.0"/>
</NonbondedForce>
<LennardJonesForce lj14scale="1.0">
<Atom type="CLA" sigma="0.404468018036" epsilon="0.6276"/>
<Atom type="SOD" sigma="0.251367073323" epsilon="0.1962296"/>
<NBFixPair type1="CLA" type2="SOD" sigma="0.664788623476" epsilon="0.350933"/>
</LennardJonesForce>
</ForceField> """
ff
=
ForceField
(
StringIO
(
xml
))
system2
=
ff
.
createSystem
(
pdb
.
topology
,
nonbondedMethod
=
PME
,
nonbondedCutoff
=
5
*
angstroms
)
con2
=
Context
(
system2
,
VerletIntegrator
(
2
*
femtoseconds
),
plat
)
con2
.
setPositions
(
pdb
.
positions
)
state
=
con
.
getState
(
getEnergy
=
True
,
enforcePeriodicBox
=
True
)
ene
=
state
.
getPotentialEnergy
().
value_in_unit
(
kilocalories_per_mole
)
state2
=
con2
.
getState
(
getEnergy
=
True
,
enforcePeriodicBox
=
True
)
ene2
=
state2
.
getPotentialEnergy
().
value_in_unit
(
kilocalories_per_mole
)
self
.
assertAlmostEqual
(
ene
,
ene2
)
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
unittest
.
main
()
unittest
.
main
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment