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
0ae7458e
Unverified
Commit
0ae7458e
authored
Apr 17, 2025
by
Peter Eastman
Committed by
GitHub
Apr 17, 2025
Browse files
Fixed error adding vsites that depend on other vsites (#4898)
parent
de180e4e
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
74 additions
and
19 deletions
+74
-19
wrappers/python/openmm/app/modeller.py
wrappers/python/openmm/app/modeller.py
+25
-18
wrappers/python/tests/TestModeller.py
wrappers/python/tests/TestModeller.py
+49
-1
No files found.
wrappers/python/openmm/app/modeller.py
View file @
0ae7458e
...
...
@@ -1208,6 +1208,7 @@ class Modeller(object):
if
site
.
index
==
index
:
# This is a virtual site. Compute its position by the correct rule.
try
:
if
site
.
type
==
'average2'
:
position
=
site
.
weights
[
0
]
*
templateAtomPositions
[
site
.
atoms
[
0
]]
+
site
.
weights
[
1
]
*
templateAtomPositions
[
site
.
atoms
[
1
]]
elif
site
.
type
==
'average3'
:
...
...
@@ -1222,10 +1223,16 @@ class Modeller(object):
xdir
=
unit
.
sum
([
templateAtomPositions
[
atom
]
*
weight
for
atom
,
weight
in
zip
(
site
.
atoms
,
site
.
xWeights
)])
ydir
=
unit
.
sum
([
templateAtomPositions
[
atom
]
*
weight
for
atom
,
weight
in
zip
(
site
.
atoms
,
site
.
yWeights
)])
zdir
=
Vec3
(
xdir
[
1
]
*
ydir
[
2
]
-
xdir
[
2
]
*
ydir
[
1
],
xdir
[
2
]
*
ydir
[
0
]
-
xdir
[
0
]
*
ydir
[
2
],
xdir
[
0
]
*
ydir
[
1
]
-
xdir
[
1
]
*
ydir
[
0
])
xdir
/=
norm
(
xdir
)
;
zdir
/=
norm
(
zdir
)
;
xdir
/=
norm
(
xdir
)
zdir
/=
norm
(
zdir
)
ydir
=
Vec3
(
zdir
[
1
]
*
xdir
[
2
]
-
zdir
[
2
]
*
xdir
[
1
],
zdir
[
2
]
*
xdir
[
0
]
-
zdir
[
0
]
*
xdir
[
2
],
zdir
[
0
]
*
xdir
[
1
]
-
zdir
[
1
]
*
xdir
[
0
])
position
=
origin
+
xdir
*
site
.
localPos
[
0
]
+
ydir
*
site
.
localPos
[
1
]
+
zdir
*
site
.
localPos
[
2
];
position
=
origin
+
xdir
*
site
.
localPos
[
0
]
+
ydir
*
site
.
localPos
[
1
]
+
zdir
*
site
.
localPos
[
2
]
except
:
# This can happen if the virtual site depends on another virtual site whose position
# hasn't been set yet. Ignore the error. We'll put it at a random position (see below),
# which will get replaced with the correct position at the start of the simulation.
pass
if
position
is
None
and
atom
.
type
in
drudeTypeMap
:
# This is a Drude particle. Put it on top of its parent atom.
...
...
wrappers/python/tests/TestModeller.py
View file @
0ae7458e
...
...
@@ -1087,7 +1087,7 @@ class TestModeller(unittest.TestCase):
residue
=
topology
.
addResidue
(
'Test'
,
chain
)
topology
.
addAtom
(
'C'
,
element
.
carbon
,
residue
)
topology
.
addAtom
(
'N'
,
element
.
nitrogen
,
residue
)
topology
.
addAtom
(
'
V
'
,
element
.
oxygen
,
residue
)
topology
.
addAtom
(
'
O
'
,
element
.
oxygen
,
residue
)
# Add the virtual sites.
...
...
@@ -1115,6 +1115,54 @@ class TestModeller(unittest.TestCase):
self
.
assertVecAlmostEqual
(
p1
.
value_in_unit
(
nanometers
),
p2
.
value_in_unit
(
nanometers
),
1e-6
)
def
testNestedVirtualSites
(
self
):
"""Test adding virtual sites that depend on other virtual sites."""
xml
=
"""
<ForceField>
<AtomTypes>
<Type name="C" class="C" element="C" mass="10"/>
<Type name="N" class="N" element="N" mass="10"/>
<Type name="V" class="V" mass="0.0"/>
</AtomTypes>
<Residues>
<Residue name="Test">
<Atom name="C" type="C"/>
<Atom name="N" type="N"/>
<Atom name="V1" type="V"/>
<Atom name="V2" type="V"/>
<VirtualSite type="average2" index="2" atom1="0" atom2="1" weight1="0.5" weight2="0.5"/>
<VirtualSite type="average2" index="3" atom1="0" atom2="2" weight1="0.5" weight2="0.5"/>
</Residue>
</Residues>
</ForceField>"""
ff
=
ForceField
(
StringIO
(
xml
))
# Create the three real atoms.
topology
=
Topology
()
chain
=
topology
.
addChain
()
residue
=
topology
.
addResidue
(
'Test'
,
chain
)
topology
.
addAtom
(
'C'
,
element
.
carbon
,
residue
)
topology
.
addAtom
(
'N'
,
element
.
nitrogen
,
residue
)
# Add the virtual sites.
modeller
=
Modeller
(
topology
,
[
Vec3
(
0.0
,
0.0
,
0.0
),
Vec3
(
1.0
,
0.0
,
0.0
)]
*
nanometers
)
modeller
.
addExtraParticles
(
ff
)
top
=
modeller
.
topology
pos
=
modeller
.
positions
# Check that the correct particles were added.
self
.
assertEqual
(
len
(
pos
),
4
)
for
atom
,
elem
in
zip
(
top
.
atoms
(),
[
element
.
carbon
,
element
.
nitrogen
,
None
,
None
]):
self
.
assertEqual
(
elem
,
atom
.
element
)
# The positions of the first virtual site should be correct, but the second one won't be.
self
.
assertVecAlmostEqual
(
Vec3
(
0.5
,
0.0
,
0.0
),
pos
[
2
].
value_in_unit
(
nanometers
),
1e-6
)
def
test_multiSiteIon
(
self
):
"""Test adding extra particles whose positions are determined based on bonds."""
xml
=
"""
...
...
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