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
78d42678
Commit
78d42678
authored
Apr 16, 2019
by
Peter Eastman
Browse files
ForceField supports HippoNonbondedForce
parent
682da7b2
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
175 additions
and
4 deletions
+175
-4
plugins/amoeba/openmmapi/include/openmm/HippoNonbondedForce.h
...ins/amoeba/openmmapi/include/openmm/HippoNonbondedForce.h
+1
-1
plugins/amoeba/serialization/src/HippoNonbondedForceProxy.cpp
...ins/amoeba/serialization/src/HippoNonbondedForceProxy.cpp
+2
-2
wrappers/python/simtk/openmm/app/forcefield.py
wrappers/python/simtk/openmm/app/forcefield.py
+172
-1
No files found.
plugins/amoeba/openmmapi/include/openmm/HippoNonbondedForce.h
View file @
78d42678
...
@@ -72,7 +72,7 @@ public:
...
@@ -72,7 +72,7 @@ public:
PME
=
1
PME
=
1
};
};
enum
ParticleAxisTypes
{
ZThenX
=
0
,
Bisector
=
1
,
ZBisect
=
2
,
ThreeFold
=
3
,
ZOnly
=
4
,
NoAxisType
=
5
,
LastAxisTypeIndex
=
6
};
enum
ParticleAxisTypes
{
ZThenX
=
0
,
Bisector
=
1
,
ZBisect
=
2
,
ThreeFold
=
3
,
ZOnly
=
4
,
NoAxisType
=
5
};
/**
/**
* Create a HippoNonbondedForce.
* Create a HippoNonbondedForce.
...
...
plugins/amoeba/serialization/src/HippoNonbondedForceProxy.cpp
View file @
78d42678
...
@@ -62,7 +62,7 @@ void HippoNonbondedForceProxy::serialize(const void* object, SerializationNode&
...
@@ -62,7 +62,7 @@ void HippoNonbondedForceProxy::serialize(const void* object, SerializationNode&
node
.
setIntProperty
(
"dpmeGridX"
,
nx
);
node
.
setIntProperty
(
"dpmeGridX"
,
nx
);
node
.
setIntProperty
(
"dpmeGridY"
,
ny
);
node
.
setIntProperty
(
"dpmeGridY"
,
ny
);
node
.
setIntProperty
(
"dpmeGridZ"
,
nz
);
node
.
setIntProperty
(
"dpmeGridZ"
,
nz
);
SerializationNode
&
coefficients
=
node
.
createChildNode
(
"
e
xtrapolationCoefficients"
);
SerializationNode
&
coefficients
=
node
.
createChildNode
(
"
E
xtrapolationCoefficients"
);
vector
<
double
>
coeff
=
force
.
getExtrapolationCoefficients
();
vector
<
double
>
coeff
=
force
.
getExtrapolationCoefficients
();
for
(
int
i
=
0
;
i
<
coeff
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
coeff
.
size
();
i
++
)
{
stringstream
key
;
stringstream
key
;
...
@@ -128,7 +128,7 @@ void* HippoNonbondedForceProxy::deserialize(const SerializationNode& node) const
...
@@ -128,7 +128,7 @@ void* HippoNonbondedForceProxy::deserialize(const SerializationNode& node) const
force
->
setEwaldErrorTolerance
(
node
.
getDoubleProperty
(
"ewaldErrorTolerance"
));
force
->
setEwaldErrorTolerance
(
node
.
getDoubleProperty
(
"ewaldErrorTolerance"
));
force
->
setPMEParameters
(
node
.
getDoubleProperty
(
"pmeAlpha"
),
node
.
getIntProperty
(
"pmeGridX"
),
node
.
getIntProperty
(
"pmeGridY"
),
node
.
getIntProperty
(
"pmeGridZ"
));
force
->
setPMEParameters
(
node
.
getDoubleProperty
(
"pmeAlpha"
),
node
.
getIntProperty
(
"pmeGridX"
),
node
.
getIntProperty
(
"pmeGridY"
),
node
.
getIntProperty
(
"pmeGridZ"
));
force
->
setDPMEParameters
(
node
.
getDoubleProperty
(
"dpmeAlpha"
),
node
.
getIntProperty
(
"dpmeGridX"
),
node
.
getIntProperty
(
"dpmeGridY"
),
node
.
getIntProperty
(
"dpmeGridZ"
));
force
->
setDPMEParameters
(
node
.
getDoubleProperty
(
"dpmeAlpha"
),
node
.
getIntProperty
(
"dpmeGridX"
),
node
.
getIntProperty
(
"dpmeGridY"
),
node
.
getIntProperty
(
"dpmeGridZ"
));
const
SerializationNode
&
coefficients
=
node
.
getChildNode
(
"
e
xtrapolationCoefficients"
);
const
SerializationNode
&
coefficients
=
node
.
getChildNode
(
"
E
xtrapolationCoefficients"
);
vector
<
double
>
coeff
;
vector
<
double
>
coeff
;
for
(
int
i
=
0
;
;
i
++
)
{
for
(
int
i
=
0
;
;
i
++
)
{
stringstream
key
;
stringstream
key
;
...
...
wrappers/python/simtk/openmm/app/forcefield.py
View file @
78d42678
...
@@ -6,7 +6,7 @@ Simbios, the NIH National Center for Physics-Based Simulation of
...
@@ -6,7 +6,7 @@ Simbios, the NIH National Center for Physics-Based Simulation of
Biological Structures at Stanford, funded under the NIH Roadmap for
Biological Structures at Stanford, funded under the NIH Roadmap for
Medical Research, grant U54 GM072970. See https://simtk.org.
Medical Research, grant U54 GM072970. See https://simtk.org.
Portions copyright (c) 2012-201
8
Stanford University and the Authors.
Portions copyright (c) 2012-201
9
Stanford University and the Authors.
Authors: Peter Eastman, Mark Friedrichs
Authors: Peter Eastman, Mark Friedrichs
Contributors:
Contributors:
...
@@ -1334,6 +1334,70 @@ def _findBondsForExclusions(data, sys):
...
@@ -1334,6 +1334,70 @@ def _findBondsForExclusions(data, sys):
bondIndices
.
append
((
child
,
atom
.
index
))
bondIndices
.
append
((
child
,
atom
.
index
))
return
bondIndices
return
bondIndices
def
_findExclusions
(
bondIndices
,
maxSeparation
,
numAtoms
):
"""Identify pairs of atoms in the same molecule separated by no more than maxSeparation bonds."""
bondedTo
=
[
set
()
for
i
in
range
(
numAtoms
)]
for
i
,
j
in
bondIndices
:
bondedTo
[
i
].
add
(
j
)
bondedTo
[
j
].
add
(
i
)
# Identify all neighbors of each atom with each separation.
bondedWithSeparation
=
[
bondedTo
]
for
i
in
range
(
maxSeparation
-
1
):
lastBonds
=
bondedWithSeparation
[
-
1
]
newBonds
=
deepcopy
(
lastBonds
)
for
atom
in
range
(
numAtoms
):
for
a1
in
lastBonds
[
atom
]:
for
a2
in
bondedTo
[
a1
]:
newBonds
[
atom
].
add
(
a2
)
bondedWithSeparation
.
append
(
newBonds
)
# Build the list of pairs.
pairs
=
[]
for
atom
in
range
(
numAtoms
):
for
otherAtom
in
bondedWithSeparation
[
-
1
][
atom
]:
if
otherAtom
>
atom
:
# Determine the minimum number of bonds between them.
sep
=
maxSeparation
for
i
in
reversed
(
range
(
maxSeparation
-
1
)):
if
otherAtom
in
bondedWithSeparation
[
i
][
atom
]:
sep
-=
1
else
:
break
pairs
.
append
((
atom
,
otherAtom
,
sep
))
return
pairs
def
_findGroups
(
bondedTo
):
"""Given bonds that connect atoms, identify the connected groups."""
atomGroup
=
[
None
]
*
len
(
bondedTo
)
numGroups
=
0
for
i
in
range
(
len
(
bondedTo
)):
if
atomGroup
[
i
]
is
None
:
# Start a new group.
atomStack
=
[
i
]
neighborStack
=
[
0
]
group
=
numGroups
numGroups
+=
1
# Recursively tag all the bonded atoms.
while
len
(
atomStack
)
>
0
:
atom
=
atomStack
[
-
1
]
atomGroup
[
atom
]
=
group
while
neighborStack
[
-
1
]
<
len
(
bondedTo
[
atom
])
and
atomGroup
[
bondedTo
[
atom
][
neighborStack
[
-
1
]]]
is
not
None
:
neighborStack
[
-
1
]
+=
1
if
neighborStack
[
-
1
]
<
len
(
bondedTo
[
atom
]):
atomStack
.
append
(
bondedTo
[
atom
][
neighborStack
[
-
1
]])
neighborStack
.
append
(
0
)
else
:
atomStack
.
pop
()
neighborStack
.
pop
()
return
atomGroup
def
_countResidueAtoms
(
elements
):
def
_countResidueAtoms
(
elements
):
"""Count the number of atoms of each element in a residue."""
"""Count the number of atoms of each element in a residue."""
counts
=
{}
counts
=
{}
...
@@ -1749,6 +1813,7 @@ def _matchImproper(data, torsion, generator):
...
@@ -1749,6 +1813,7 @@ def _matchImproper(data, torsion, generator):
break
break
return
match
return
match
# The following classes are generators that know how to create Force subclasses and add them to a System that is being
# The following classes are generators that know how to create Force subclasses and add them to a System that is being
# created. Each generator class must define two methods: 1) a static method that takes an etree Element and a ForceField,
# created. Each generator class must define two methods: 1) a static method that takes an etree Element and a ForceField,
# and returns the corresponding generator object; 2) a createForce() method that constructs the Force object and adds it
# and returns the corresponding generator object; 2) a createForce() method that constructs the Force object and adds it
...
@@ -5413,6 +5478,112 @@ parsers["AmoebaUreyBradleyForce"] = AmoebaUreyBradleyGenerator.parseElement
...
@@ -5413,6 +5478,112 @@ parsers["AmoebaUreyBradleyForce"] = AmoebaUreyBradleyGenerator.parseElement
#=============================================================================================
#=============================================================================================
## @private
class
HippoNonbondedGenerator
(
object
):
"""A HippoNonbondedGenerator constructs a HippoNonbondedForce."""
def
__init__
(
self
,
forcefield
,
extrapCoeff
):
self
.
ff
=
forcefield
self
.
extrapCoeff
=
extrapCoeff
self
.
exceptions
=
{}
@
staticmethod
def
parseElement
(
element
,
ff
):
extrapCoeff
=
[
float
(
c
)
for
c
in
element
.
attrib
[
'extrapolationCoefficients'
].
split
(
','
)]
generator
=
HippoNonbondedGenerator
(
ff
,
extrapCoeff
)
ff
.
registerGenerator
(
generator
)
scaleNames
=
(
'mmScale'
,
'dmScale'
,
'ddScale'
,
'dispScale'
,
'repScale'
,
'ctScale'
)
paramNames
=
(
'charge'
,
'coreCharge'
,
'alpha'
,
'epsilon'
,
'damping'
,
'c6'
,
'pauliK'
,
'pauliQ'
,
'pauliAlpha'
,
'polarizability'
,
'axisType'
,
'd0'
,
'd1'
,
'd2'
,
'q11'
,
'q12'
,
'q13'
,
'q21'
,
'q22'
,
'q23'
,
'q31'
,
'q32'
,
'q33'
)
for
ex
in
element
.
findall
(
'Exception'
):
separation
=
int
(
ex
.
attrib
[
'separation'
])
ingroup
=
ex
.
attrib
[
'ingroup'
].
lower
()
==
'true'
key
=
(
separation
,
ingroup
)
if
key
in
generator
.
exceptions
:
raise
ValueError
(
'HippoNonbondedForce: multiple exceptions with separation=%d ingroup=%s'
%
(
separation
,
ingroup
))
generator
.
exceptions
[
key
]
=
[
float
(
ex
.
attrib
[
s
])
for
s
in
scaleNames
]
generator
.
params
=
ForceField
.
_AtomTypeParameters
(
ff
,
'HippoNonbondedForce'
,
'Atom'
,
paramNames
)
generator
.
params
.
parseDefinitions
(
element
)
def
createForce
(
self
,
sys
,
data
,
nonbondedMethod
,
nonbondedCutoff
,
args
):
methodMap
=
{
NoCutoff
:
mm
.
HippoNonbondedForce
.
NoCutoff
,
PME
:
mm
.
HippoNonbondedForce
.
PME
}
if
nonbondedMethod
not
in
methodMap
:
raise
ValueError
(
'Illegal nonbonded method for HippoNonbondedForce'
)
# Build data structures we'll need for building local coordinate frames.
bondIndices
=
_findBondsForExclusions
(
data
,
sys
)
pairs
=
_findExclusions
(
bondIndices
,
2
,
len
(
data
.
atoms
))
bonded12
=
[
set
()
for
i
in
range
(
len
(
data
.
atoms
))]
bonded13
=
[
set
()
for
i
in
range
(
len
(
data
.
atoms
))]
for
atom1
,
atom2
,
sep
in
pairs
:
if
sep
==
1
:
bonded12
[
atom1
].
add
(
data
.
atoms
[
atom2
])
bonded12
[
atom2
].
add
(
data
.
atoms
[
atom1
])
else
:
bonded13
[
atom1
].
add
(
data
.
atoms
[
atom2
])
bonded13
[
atom2
].
add
(
data
.
atoms
[
atom1
])
# Create the force.
force
=
mm
.
HippoNonbondedForce
()
for
atom
in
data
.
atoms
:
values
=
self
.
params
.
getAtomParameters
(
atom
,
data
)
params
=
[
float
(
v
)
for
v
in
values
[:
10
]]
axisType
=
int
(
values
[
10
])
dipole
=
[
float
(
v
)
for
v
in
values
[
11
:
14
]]
quadrupole
=
[
float
(
v
)
for
v
in
values
[
14
:
23
]]
extra
=
self
.
params
.
getExtraParameters
(
atom
,
data
)
zAtom
=
self
.
_findAxisAtom
(
'zAtomType'
,
extra
,
bonded12
[
atom
.
index
],
None
,
data
,
[])
xAtom
=
self
.
_findAxisAtom
(
'xAtomType'
,
extra
,
bonded12
[
atom
.
index
],
bonded13
[
atom
.
index
],
data
,
[
zAtom
])
yAtom
=
self
.
_findAxisAtom
(
'yAtomType'
,
extra
,
bonded12
[
atom
.
index
],
bonded13
[
atom
.
index
],
data
,
[
zAtom
,
xAtom
])
force
.
addParticle
(
params
[
0
],
dipole
,
quadrupole
,
*
params
[
1
:],
axisType
,
zAtom
,
xAtom
,
yAtom
)
force
.
setNonbondedMethod
(
methodMap
[
nonbondedMethod
])
force
.
setExtrapolationCoefficients
(
self
.
extrapCoeff
)
force
.
setCutoffDistance
(
nonbondedCutoff
)
if
args
[
'switchDistance'
]
is
not
None
:
force
.
setSwitchingDistance
(
args
[
'switchDistance'
])
if
'ewaldErrorTolerance'
in
args
:
force
.
setEwaldErrorTolerance
(
args
[
'ewaldErrorTolerance'
])
sys
.
addForce
(
force
)
def
_findAxisAtom
(
self
,
paramName
,
params
,
bonded12
,
bonded13
,
data
,
exclude
):
if
paramName
not
in
params
:
return
-
1
atomType
=
params
[
paramName
]
for
atom
in
bonded12
:
if
data
.
atomType
[
atom
]
==
atomType
and
atom
.
index
not
in
exclude
:
return
atom
.
index
if
bonded13
is
not
None
:
for
atom
in
bonded13
:
if
data
.
atomType
[
atom
]
==
atomType
and
atom
.
index
not
in
exclude
:
return
atom
.
index
raise
ValueError
(
'No bonded atom of type %s'
%
atomType
)
def
postprocessSystem
(
self
,
sys
,
data
,
args
):
# Identify polarization groups.
bondIndices
=
_findBondsForExclusions
(
data
,
sys
)
groupBondTypes
=
[
self
.
params
.
getExtraParameters
(
atom
,
data
)[
'groupTypes'
].
split
(
','
)
for
atom
in
data
.
atoms
]
groupBonds
=
[[]
for
i
in
range
(
len
(
data
.
atoms
))]
for
i
,
j
in
bondIndices
:
if
data
.
atomType
[
data
.
atoms
[
i
]]
in
groupBondTypes
[
j
]:
groupBonds
[
i
].
append
(
j
)
groupBonds
[
j
].
append
(
i
)
polarizationGroup
=
_findGroups
(
groupBonds
)
# Create the exclusions.
maxSeparation
=
max
(
e
[
0
]
for
e
in
self
.
exceptions
)
hippo
=
[
f
for
f
in
sys
.
getForces
()
if
isinstance
(
f
,
mm
.
HippoNonbondedForce
)][
0
]
pairs
=
_findExclusions
(
bondIndices
,
maxSeparation
,
hippo
.
getNumParticles
())
for
atom1
,
atom2
,
sep
in
pairs
:
params
=
self
.
exceptions
[(
sep
,
polarizationGroup
[
atom1
]
==
polarizationGroup
[
atom2
])]
hippo
.
addException
(
atom1
,
atom2
,
*
params
)
parsers
[
"HippoNonbondedForce"
]
=
HippoNonbondedGenerator
.
parseElement
## @private
## @private
class
DrudeGenerator
(
object
):
class
DrudeGenerator
(
object
):
"""A DrudeGenerator constructs a DrudeForce."""
"""A DrudeGenerator constructs a DrudeForce."""
...
...
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