Skip to content

Commit 306fb85

Browse files
committed
Add bond/angle wildcard handling
1 parent c0add66 commit 306fb85

File tree

3 files changed

+89
-41
lines changed

3 files changed

+89
-41
lines changed

gmso/core/forcefield.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,33 @@ def _get_bond_type(self, atom_types, return_match_order=False, warn=False):
351351
if reverse in self.bond_types:
352352
match = self.bond_types[reverse], (1, 0)
353353

354+
if match:
355+
if return_match_order:
356+
return match
357+
else:
358+
return match[0]
359+
360+
for i in range(1, 3):
361+
forward_patterns = mask_with(atom_types, i)
362+
reverse_patterns = mask_with(reversed(atom_types), i)
363+
364+
for forward_pattern, reverse_pattern in zip(
365+
forward_patterns, reverse_patterns
366+
):
367+
forward_match_key = FF_TOKENS_SEPARATOR.join(forward_pattern)
368+
reverse_match_key = FF_TOKENS_SEPARATOR.join(reverse_pattern)
369+
370+
if forward_match_key in self.bond_types:
371+
match = self.bond_types[forward_match_key], (0, 1)
372+
break
373+
374+
if reverse_match_key in self.bond_types:
375+
match = self.bond_types[reverse_match_key], (2, 1)
376+
break
377+
378+
if match:
379+
break
380+
354381
msg = (
355382
f"BondType between atoms {atom_types[0]} and {atom_types[1]} "
356383
f"is missing from the ForceField"
@@ -382,6 +409,33 @@ def _get_angle_type(self, atom_types, return_match_order=False, warn=False):
382409
if reverse in self.angle_types:
383410
match = self.angle_types[reverse], (2, 1, 0)
384411

412+
if match:
413+
if return_match_order:
414+
return match
415+
else:
416+
return match[0]
417+
418+
for i in range(1, 4):
419+
forward_patterns = mask_with(atom_types, i)
420+
reverse_patterns = mask_with(reversed(atom_types), i)
421+
422+
for forward_pattern, reverse_pattern in zip(
423+
forward_patterns, reverse_patterns
424+
):
425+
forward_match_key = FF_TOKENS_SEPARATOR.join(forward_pattern)
426+
reverse_match_key = FF_TOKENS_SEPARATOR.join(reverse_pattern)
427+
428+
if forward_match_key in self.angle_types:
429+
match = self.angle_types[forward_match_key], (0, 1, 2)
430+
break
431+
432+
if reverse_match_key in self.angle_types:
433+
match = self.angle_types[reverse_match_key], (2, 1, 0)
434+
break
435+
436+
if match:
437+
break
438+
385439
msg = (
386440
f"AngleType between atoms {atom_types[0]}, {atom_types[1]} "
387441
f"and {atom_types[2]} is missing from the ForceField"

gmso/tests/files/alkanes_wildcards.xml

Lines changed: 13 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -46,38 +46,20 @@
4646
<BondTypes expression="0.5*k*(r - r_eq)**2">
4747
<ParametersUnitDef parameter="k" unit="kJ/(mol*nm**2)"/>
4848
<ParametersUnitDef parameter="r_eq" unit="nm"/>
49-
<BondType name="BondType-Harmonic-1" type1="CT" type2="HC">
49+
<BondType name="BondType-Harmonic-1" type1="*" type2="*">
5050
<Parameters>
51-
<Parameter name="k" value="284512.0"/>
52-
<Parameter name="r_eq" value="0.109"/>
53-
</Parameters>
54-
</BondType>
55-
<BondType name="BondType-Harmonic-2" type1="CT" type2="CT">
56-
<Parameters>
57-
<Parameter name="k" value="224262.4"/>
58-
<Parameter name="r_eq" value="0.1529"/>
51+
<Parameter name="k" value="1"/>
52+
<Parameter name="r_eq" value="1"/>
5953
</Parameters>
6054
</BondType>
6155
</BondTypes>
6256
<AngleTypes expression="0.5*k*(theta - theta_eq)**2">
6357
<ParametersUnitDef parameter="k" unit="kJ/(mol*rad**2)"/>
6458
<ParametersUnitDef parameter="theta_eq" unit="rad"/>
65-
<AngleType name="AngleType-Harmonic-1" type1="HC" type2="CT" type3="HC">
66-
<Parameters>
67-
<Parameter name="k" value="276.144"/>
68-
<Parameter name="theta_eq" value="1.88146493365"/>
69-
</Parameters>
70-
</AngleType>
71-
<AngleType name="AngleType-Harmonic-2" type1="CT" type2="CT" type3="HC">
59+
<AngleType name="AngleType-Harmonic-1" type1="*" type2="*" type3="*">
7260
<Parameters>
73-
<Parameter name="k" value="313.8"/>
74-
<Parameter name="theta_eq" value="1.93207948196"/>
75-
</Parameters>
76-
</AngleType>
77-
<AngleType name="AngleType-Harmonic-3" type1="CT" type2="CT" type3="CT">
78-
<Parameters>
79-
<Parameter name="k" value="488.273"/>
80-
<Parameter name="theta_eq" value="1.966986067"/>
61+
<Parameter name="k" value="1"/>
62+
<Parameter name="theta_eq" value="1"/>
8163
</Parameters>
8264
</AngleType>
8365
</AngleTypes>
@@ -88,24 +70,14 @@
8870
<ParametersUnitDef parameter="c3" unit="kJ/mol"/>
8971
<ParametersUnitDef parameter="c4" unit="kJ/mol"/>
9072
<ParametersUnitDef parameter="c5" unit="kJ/mol"/>
91-
<DihedralType name="RyckaertBellemansTorsionPotential-1" type1="HC" type2="CT" type3="CT" type4="">
92-
<Parameters>
93-
<Parameter name="c0" value="0.6276"/>
94-
<Parameter name="c1" value="1.8828"/>
95-
<Parameter name="c2" value="0.0"/>
96-
<Parameter name="c3" value="-2.5104"/>
97-
<Parameter name="c4" value="0.0"/>
98-
<Parameter name="c5" value="0.0"/>
99-
</Parameters>
100-
</DihedralType>
101-
<DihedralType name="RyckaertBellemansTorsionPotential-3" type1="CT" type2="CT" type3="CT" type4="CT">
73+
<DihedralType name="RyckaertBellemansTorsionPotential-1" type1="*" type2="*" type3="*" type4="">
10274
<Parameters>
103-
<Parameter name="c0" value="2.9288"/>
104-
<Parameter name="c1" value="-1.4644"/>
105-
<Parameter name="c2" value="0.2092"/>
106-
<Parameter name="c3" value="-1.6736"/>
107-
<Parameter name="c4" value="0.0"/>
108-
<Parameter name="c5" value="0.0"/>
75+
<Parameter name="c0" value="1"/>
76+
<Parameter name="c1" value="1"/>
77+
<Parameter name="c2" value="1"/>
78+
<Parameter name="c3" value="1"/>
79+
<Parameter name="c4" value="1"/>
80+
<Parameter name="c5" value="1"/>
10981
</Parameters>
11082
</DihedralType>
11183
</DihedralTypes>

gmso/tests/parameterization/test_opls_gmso.py renamed to gmso/tests/parameterization/test_parameterizations.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
import parmed as pmd
55
import pytest
66

7+
from gmso import ForceField
78
from gmso.external.convert_parmed import from_parmed
89
from gmso.parameterization.parameterize import apply
910
from gmso.tests.parameterization.parameterization_base_test import (
1011
ParameterizationBaseTest,
1112
)
13+
from gmso.tests.utils import get_path
1214

1315

1416
def get_foyer_opls_test_dirs():
@@ -56,3 +58,23 @@ def test_foyer_oplsaa_files(
5658
assert_same_connection_params(gmso_top, gmso_top_from_pmd)
5759
assert_same_connection_params(gmso_top, gmso_top_from_pmd, "angles")
5860
assert_same_connection_params(gmso_top, gmso_top_from_pmd, "dihedrals")
61+
62+
63+
class TestGeneralParameterizations(ParameterizationBaseTest):
64+
def test_wildcards(self, ethane_methane_top):
65+
from gmso.core.views import PotentialFilters
66+
67+
ff = ForceField(get_path("alkanes_wildcards.xml"))
68+
ptop = apply(ethane_methane_top, ff, identify_connections=True)
69+
assert ptop.is_fully_typed()
70+
assert len(ptop.bond_types) == 11
71+
assert len(ptop.bond_types(PotentialFilters.UNIQUE_NAME_CLASS)) == 1
72+
assert ptop.bonds[0].bond_type.member_types == ("*", "*")
73+
74+
assert len(ptop.angle_types) == 12 + 6 # ethane + methane
75+
assert len(ptop.angle_types(PotentialFilters.UNIQUE_NAME_CLASS)) == 1
76+
assert ptop.angles[0].angle_type.member_types == ("*", "*", "*")
77+
78+
assert len(ptop.dihedral_types) == 9
79+
assert len(ptop.dihedral_types(PotentialFilters.UNIQUE_NAME_CLASS)) == 1
80+
assert ptop.dihedrals[0].dihedral_type.member_types == ("*", "*", "*", "*")

0 commit comments

Comments
 (0)