Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add and update conversions for opls and fourier potentials #825

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions gmso/formats/mcf.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from gmso.lib.potential_templates import PotentialTemplateLibrary
from gmso.utils.compatibility import check_compatibility
from gmso.utils.conversions import (
convert_opls_to_ryckaert,
convert_fourier_to_ryckaert,
convert_ryckaert_to_fourier,
)

Expand Down Expand Up @@ -473,7 +473,7 @@
dihedral_style = "FOURIER"

if dihedral_style == "OPLS":
dihedral.connection_type = convert_opls_to_ryckaert(
dihedral.connection_type = convert_fourier_to_ryckaert(

Check warning on line 476 in gmso/formats/mcf.py

View check run for this annotation

Codecov / codecov/patch

gmso/formats/mcf.py#L476

Added line #L476 was not covered by tests
dihedral.connection_type
)
dihedral.connection_type = convert_ryckaert_to_fourier(
Expand Down
10 changes: 5 additions & 5 deletions gmso/tests/test_internal_conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from gmso.lib.potential_templates import PotentialTemplateLibrary
from gmso.tests.base_test import BaseTest
from gmso.utils.conversions import (
convert_opls_to_ryckaert,
convert_fourier_to_ryckaert,
convert_ryckaert_to_fourier,
)

Expand Down Expand Up @@ -81,7 +81,7 @@
)

with pytest.raises(GMSOError, match=""):
ryckaert_connection_type = convert_opls_to_ryckaert(opls_connection_type)
ryckaert_connection_type = convert_fourier_to_ryckaert(opls_connection_type)

Check warning

Code scanning / CodeQL

Variable defined multiple times Warning test

This assignment to 'ryckaert_connection_type' is unnecessary as it is
redefined
before this value is used.

variables = opls_torsion_potential.independent_variables
expression = "k0+k1+k2+k3+k4+phi"
Expand All @@ -93,7 +93,7 @@
)

with pytest.raises(GMSOError, match=""):
ryckaert_connection_type = convert_opls_to_ryckaert(opls_connection_type)
ryckaert_connection_type = convert_fourier_to_ryckaert(opls_connection_type)

Check notice

Code scanning / CodeQL

Unused local variable Note test

Variable ryckaert_connection_type is not used.

def test_ryckaert_to_fourier(self, templates):
# Pick some RB parameters at random
Expand Down Expand Up @@ -176,7 +176,7 @@
)

# Convert connection to RB
ryckaert_connection_type = convert_opls_to_ryckaert(opls_connection_type)
ryckaert_connection_type = convert_fourier_to_ryckaert(opls_connection_type)

# Pick some angles to check
angles = [-2.38, -1.31, -0.44, 0.0, 0.26, 0.92, 1.84, 3.10]
Expand Down Expand Up @@ -231,7 +231,7 @@
)

# Convert connection to RB
ryckaert_connection_type = convert_opls_to_ryckaert(opls_connection_type)
ryckaert_connection_type = convert_fourier_to_ryckaert(opls_connection_type)

# Convert connection back to OPLS
final_connection_type = convert_ryckaert_to_fourier(ryckaert_connection_type)
Expand Down
73 changes: 54 additions & 19 deletions gmso/utils/conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@

@lru_cache(maxsize=128)
def _constant_multiplier(pot1, pot2):
# TODO: Doc string
# TODO: Test outputs
# TODO: Check speed
"""Take two potentials and check for a difference of a constant multiplier between them."""
try:
constant = symengine.expand(pot1.expression / pot2.expression)
# constant = sympy.simplify(pot1.expression / pot2.expression)
Expand Down Expand Up @@ -70,9 +68,9 @@
# Apply from predefined conversions or easy sympy conversions
conversions_map = {
(
"OPLSTorsionPotential",
"FourierTorsionPotential",
"RyckaertBellemansTorsionPotential",
): convert_opls_to_ryckaert,
): convert_fourier_to_ryckaert,
(
"RyckaertBellemansTorsionPotential",
"OPLSTorsionPotential",
Expand All @@ -81,6 +79,10 @@
"RyckaertBellemansTorsionPotential",
"FourierTorsionPotential",
): convert_ryckaert_to_opls,
(
"OPLSTorsionPotential",
"FourierTorsionPotential",
): convert_opls_to_fourier,
} # map of all accessible conversions currently supported

for conv in expressionMap:
Expand Down Expand Up @@ -121,8 +123,8 @@


@lru_cache(maxsize=128)
def convert_opls_to_ryckaert(opls_connection_type):
"""Convert an OPLS dihedral to Ryckaert-Bellemans dihedral.
def convert_fourier_to_ryckaert(fourier_connection_type):
"""Convert a Foufourier dihedral to Ryckaert-Bellemans dihedral.

Equations taken/modified from:
http://manual.gromacs.org/documentation/2019/
Expand All @@ -133,31 +135,32 @@
phi_cis = 0 while RB torsions are defined as phi_trans = 0.
"""
# TODO: this function really converts the fourier torsion to rb, not opls
opls_torsion_potential = templates["FourierTorsionPotential"]
fourier_torsion_potential = templates["FourierTorsionPotential"]
valid_connection_type = False
if (
opls_connection_type.independent_variables
== opls_torsion_potential.independent_variables
fourier_connection_type.independent_variables
== fourier_torsion_potential.independent_variables
):
if (
sympy.simplify(
opls_connection_type.expression - opls_torsion_potential.expression
fourier_connection_type.expression
- fourier_torsion_potential.expression
)
== 0
):
valid_connection_type = True
if not valid_connection_type:
raise GMSOError(
"Cannot use convert_opls_to_ryckaert "
"Cannot use convert_fourier_to_ryckaert "
"function to convert a ConnectionType that is not an "
"OPLSTorsionPotential"
"FourierTorsionPotential"
)

f0 = opls_connection_type.parameters["k0"]
f1 = opls_connection_type.parameters["k1"]
f2 = opls_connection_type.parameters["k2"]
f3 = opls_connection_type.parameters["k3"]
f4 = opls_connection_type.parameters["k4"]
f0 = fourier_connection_type.parameters["k0"]
f1 = fourier_connection_type.parameters["k1"]
f2 = fourier_connection_type.parameters["k2"]
f3 = fourier_connection_type.parameters["k3"]
f4 = fourier_connection_type.parameters["k4"]

converted_params = {
"c0": (f2 + 0.5 * (f0 + f1 + f3)),
Expand All @@ -179,7 +182,8 @@
expression=expression,
independent_variables=variables,
parameters=converted_params,
member_types=opls_connection_type.member_types,
member_types=fourier_connection_type.member_types,
member_classes=fourier_connection_type.member_classes,
)

return ryckaert_connection_type
Expand Down Expand Up @@ -285,6 +289,37 @@
return fourier_connection_type


def convert_opls_to_fourier(opls_connection_type):
"""Convert opls dihedrals to Fourier.

NOTE: These only differ by the number of elements. Fourier style has a k0 term.
LAMMPS uses the opls style -> https://docs.lammps.org/dihedral_opls.html.
GROMACS uses the fourier style ->
https://manual.gromacs.org/documentation/current/reference-manual/functions/bonded-interactions.html#proper-dihedrals-fourier-function.
"""

fourier_torsion_potential = templates["FourierTorsionPotential"]
converted_params = {

Check warning on line 302 in gmso/utils/conversions.py

View check run for this annotation

Codecov / codecov/patch

gmso/utils/conversions.py#L301-L302

Added lines #L301 - L302 were not covered by tests
k: opls_connection_type.parameters.get(k, None)
for k in ["k1", "k2", "k3", "k4"]
}
converted_params["k0"] = 0 * u.kJ / u.mol
name = fourier_torsion_potential.name
expression = fourier_torsion_potential.expression
variables = fourier_torsion_potential.independent_variables

Check warning on line 309 in gmso/utils/conversions.py

View check run for this annotation

Codecov / codecov/patch

gmso/utils/conversions.py#L306-L309

Added lines #L306 - L309 were not covered by tests

fourier_connection_type = gmso.DihedralType(

Check warning on line 311 in gmso/utils/conversions.py

View check run for this annotation

Codecov / codecov/patch

gmso/utils/conversions.py#L311

Added line #L311 was not covered by tests
name=name,
expression=expression,
independent_variables=variables,
parameters=converted_params,
member_classes=opls_connection_type.member_classes,
member_types=opls_connection_type.member_types,
)

return fourier_connection_type

Check warning on line 320 in gmso/utils/conversions.py

View check run for this annotation

Codecov / codecov/patch

gmso/utils/conversions.py#L320

Added line #L320 was not covered by tests


def convert_kelvin_to_energy_units(
energy_input_unyt,
energy_output_unyt_units_str,
Expand Down
Loading