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
9a50e488
Commit
9a50e488
authored
Sep 02, 2014
by
peastman
Browse files
ForceField allows defining CustomManyParticleForces in XML files
parent
b11c8061
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
129 additions
and
26 deletions
+129
-26
wrappers/python/simtk/openmm/app/forcefield.py
wrappers/python/simtk/openmm/app/forcefield.py
+129
-26
No files found.
wrappers/python/simtk/openmm/app/forcefield.py
View file @
9a50e488
...
...
@@ -1620,7 +1620,6 @@ class CustomNonbondedGenerator:
for
atom
in
data
.
atoms
:
t
=
data
.
atomType
[
atom
]
if
t
in
self
.
typeMap
:
values
=
self
.
typeMap
[
t
]
force
.
addParticle
(
self
.
typeMap
[
t
])
else
:
raise
ValueError
(
'No CustomNonbonded parameters defined for atom type '
+
t
)
...
...
@@ -1629,35 +1628,33 @@ class CustomNonbondedGenerator:
sys
.
addForce
(
force
)
def
postprocessSystem
(
self
,
sys
,
data
,
args
):
# Create exceptions based on bonds, virtual sites, and Drude particles.
if
self
.
bondCutoff
==
0
:
return
# Create exclusions based on bonds.
bondIndices
=
[]
for
bond
in
data
.
bonds
:
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 atom.
for
i
in
range
(
sys
.
getNumParticles
()):
if
sys
.
isVirtualSite
(
i
):
site
=
sys
.
getVirtualSite
(
i
)
for
j
in
range
(
site
.
getNumParticles
()):
bondIndices
.
append
((
i
,
site
.
getParticle
(
j
)))
drude
=
[
f
for
f
in
sys
.
getForces
()
if
isinstance
(
f
,
mm
.
DrudeForce
)]
if
len
(
drude
)
>
0
:
drude
=
drude
[
0
]
# For purposes of creating exceptions, a Drude particle is "bonded" to anything
# its parent atom is bonded to.
drudeMap
=
{}
for
i
in
range
(
drude
.
getNumParticles
()):
params
=
drude
.
getParticleParameters
(
i
)
drudeMap
[
params
[
1
]]
=
params
[
0
]
for
atom1
,
atom2
in
bondIndices
:
drude1
=
drudeMap
[
atom1
]
if
atom1
in
drudeMap
else
None
drude2
=
drudeMap
[
atom2
]
if
atom2
in
drudeMap
else
None
if
drude1
is
not
None
:
bondIndices
.
append
((
drude1
,
atom2
))
if
drude2
is
not
None
:
bondIndices
.
append
((
drude1
,
drude2
))
if
drude2
is
not
None
:
bondIndices
.
append
((
atom1
,
drude2
))
(
site
,
atoms
,
excludeWith
)
=
data
.
virtualSites
[
data
.
atoms
[
i
]]
if
excludeWith
is
None
:
bondIndices
.
append
((
i
,
site
.
getParticle
(
0
)))
# Certain particles, such as lone pairs and Drude particles, share exclusions with a parent atom.
# If the parent atom does not interact with an atom, the child particle does not either.
for
atom1
,
atom2
in
bondIndices
:
for
child1
in
data
.
excludeAtomWith
[
atom1
]:
bondIndices
.
append
((
child1
,
atom2
))
for
child2
in
data
.
excludeAtomWith
[
atom2
]:
bondIndices
.
append
((
child1
,
child2
))
for
child2
in
data
.
excludeAtomWith
[
atom2
]:
bondIndices
.
append
((
atom1
,
child2
))
# Create the exclusions.
nonbonded
=
[
f
for
f
in
sys
.
getForces
()
if
isinstance
(
f
,
mm
.
CustomNonbondedForce
)][
0
]
nonbonded
.
createExclusionsFromBonds
(
bondIndices
,
self
.
bondCutoff
)
...
...
@@ -1743,7 +1740,6 @@ class CustomGBGenerator:
for
atom
in
data
.
atoms
:
t
=
data
.
atomType
[
atom
]
if
t
in
self
.
typeMap
:
values
=
self
.
typeMap
[
t
]
force
.
addParticle
(
self
.
typeMap
[
t
])
else
:
raise
ValueError
(
'No CustomGB parameters defined for atom type '
+
t
)
...
...
@@ -1753,6 +1749,113 @@ class CustomGBGenerator:
parsers
[
"CustomGBForce"
]
=
CustomGBGenerator
.
parseElement
## @private
class
CustomManyParticleGenerator
:
"""A CustomManyParticleGenerator constructs a CustomManyParticleForce."""
def
__init__
(
self
,
forcefield
,
particlesPerSet
,
energy
,
permutationMode
,
bondCutoff
):
self
.
ff
=
forcefield
self
.
particlesPerSet
=
particlesPerSet
self
.
energy
=
energy
self
.
permutationMode
=
permutationMode
self
.
bondCutoff
=
bondCutoff
self
.
typeMap
=
{}
self
.
globalParams
=
{}
self
.
perParticleParams
=
[]
self
.
functions
=
[]
self
.
typeFilters
=
[]
@
staticmethod
def
parseElement
(
element
,
ff
):
permutationMap
=
{
"SinglePermutation"
:
mm
.
CustomManyParticleForce
.
SinglePermutation
,
"UniqueCentralParticle"
:
mm
.
CustomManyParticleForce
.
UniqueCentralParticle
}
generator
=
CustomManyParticleGenerator
(
ff
,
int
(
element
.
attrib
[
'particlesPerSet'
]),
element
.
attrib
[
'energy'
],
permutationMap
[
element
.
attrib
[
'permutationMode'
]],
int
(
element
.
attrib
[
'bondCutoff'
]))
ff
.
registerGenerator
(
generator
)
for
param
in
element
.
findall
(
'GlobalParameter'
):
generator
.
globalParams
[
param
.
attrib
[
'name'
]]
=
float
(
param
.
attrib
[
'defaultValue'
])
for
param
in
element
.
findall
(
'PerParticleParameter'
):
generator
.
perParticleParams
.
append
(
param
.
attrib
[
'name'
])
for
param
in
element
.
findall
(
'TypeFilter'
):
generator
.
typeFilters
.
append
((
int
(
param
.
attrib
[
'index'
]),
[
int
(
x
)
for
x
in
param
.
attrib
[
'types'
].
split
(
','
)]))
for
atom
in
element
.
findall
(
'Atom'
):
types
=
ff
.
_findAtomTypes
(
atom
.
attrib
,
1
)
if
None
not
in
types
:
values
=
[
float
(
atom
.
attrib
[
param
])
for
param
in
generator
.
perParticleParams
]
for
t
in
types
[
0
]:
generator
.
typeMap
[
t
]
=
(
values
,
int
(
atom
.
attrib
[
'filterType'
]))
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
methodMap
=
{
NoCutoff
:
mm
.
CustomManyParticleForce
.
NoCutoff
,
CutoffNonPeriodic
:
mm
.
CustomManyParticleForce
.
CutoffNonPeriodic
,
CutoffPeriodic
:
mm
.
CustomManyParticleForce
.
CutoffPeriodic
}
if
nonbondedMethod
not
in
methodMap
:
raise
ValueError
(
'Illegal nonbonded method for CustomManyParticleForce'
)
force
=
mm
.
CustomManyParticleForce
(
self
.
particlesPerSet
,
self
.
energy
)
force
.
setPermutationMode
(
self
.
permutationMode
)
for
param
in
self
.
globalParams
:
force
.
addGlobalParameter
(
param
,
self
.
globalParams
[
param
])
for
param
in
self
.
perParticleParams
:
force
.
addPerParticleParameter
(
param
)
for
index
,
types
in
self
.
typeFilters
:
force
.
setTypeFilter
(
index
,
types
)
for
(
name
,
type
,
values
,
params
)
in
self
.
functions
:
if
type
==
'Continuous1D'
:
force
.
addTabulatedFunction
(
name
,
mm
.
Continuous1DFunction
(
values
,
params
[
'min'
],
params
[
'max'
]))
elif
type
==
'Continuous2D'
:
force
.
addTabulatedFunction
(
name
,
mm
.
Continuous2DFunction
(
params
[
'xsize'
],
params
[
'ysize'
],
values
,
params
[
'xmin'
],
params
[
'xmax'
],
params
[
'ymin'
],
params
[
'ymax'
]))
elif
type
==
'Continuous3D'
:
force
.
addTabulatedFunction
(
name
,
mm
.
Continuous2DFunction
(
params
[
'xsize'
],
params
[
'ysize'
],
params
[
'zsize'
],
values
,
params
[
'xmin'
],
params
[
'xmax'
],
params
[
'ymin'
],
params
[
'ymax'
],
params
[
'zmin'
],
params
[
'zmax'
]))
elif
type
==
'Discrete1D'
:
force
.
addTabulatedFunction
(
name
,
mm
.
Discrete1DFunction
(
values
))
elif
type
==
'Discrete2D'
:
force
.
addTabulatedFunction
(
name
,
mm
.
Discrete2DFunction
(
params
[
'xsize'
],
params
[
'ysize'
],
values
))
elif
type
==
'Discrete3D'
:
force
.
addTabulatedFunction
(
name
,
mm
.
Discrete2DFunction
(
params
[
'xsize'
],
params
[
'ysize'
],
params
[
'zsize'
],
values
))
for
atom
in
data
.
atoms
:
t
=
data
.
atomType
[
atom
]
if
t
in
self
.
typeMap
:
values
=
self
.
typeMap
[
t
]
force
.
addParticle
(
values
[
0
],
values
[
1
])
else
:
raise
ValueError
(
'No CustomManyParticle parameters defined for atom type '
+
t
)
force
.
setNonbondedMethod
(
methodMap
[
nonbondedMethod
])
force
.
setCutoffDistance
(
nonbondedCutoff
)
sys
.
addForce
(
force
)
def
postprocessSystem
(
self
,
sys
,
data
,
args
):
# Create exclusions based on bonds.
bondIndices
=
[]
for
bond
in
data
.
bonds
:
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 atom.
for
i
in
range
(
sys
.
getNumParticles
()):
if
sys
.
isVirtualSite
(
i
):
(
site
,
atoms
,
excludeWith
)
=
data
.
virtualSites
[
data
.
atoms
[
i
]]
if
excludeWith
is
None
:
bondIndices
.
append
((
i
,
site
.
getParticle
(
0
)))
# Certain particles, such as lone pairs and Drude particles, share exclusions with a parent atom.
# If the parent atom does not interact with an atom, the child particle does not either.
for
atom1
,
atom2
in
bondIndices
:
for
child1
in
data
.
excludeAtomWith
[
atom1
]:
bondIndices
.
append
((
child1
,
atom2
))
for
child2
in
data
.
excludeAtomWith
[
atom2
]:
bondIndices
.
append
((
child1
,
child2
))
for
child2
in
data
.
excludeAtomWith
[
atom2
]:
bondIndices
.
append
((
atom1
,
child2
))
# Create the exclusions.
nonbonded
=
[
f
for
f
in
sys
.
getForces
()
if
isinstance
(
f
,
mm
.
CustomManyParticleForce
)][
0
]
nonbonded
.
createExclusionsFromBonds
(
bondIndices
,
self
.
bondCutoff
)
parsers
[
"CustomManyParticleForce"
]
=
CustomManyParticleGenerator
.
parseElement
def
getAtomPrint
(
data
,
atomIndex
):
if
(
atomIndex
<
len
(
data
.
atoms
)):
...
...
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