openff-interchange
openff-interchange copied to clipboard
[DNM]: Add experimental "auto" idivf
Description
Requires installing a branch of the same name from the toolkit. Here's a script that demonstrates it:
import openmm
from openff.toolkit import ForceField, Molecule, Quantity, unit
from openff.toolkit.typing.engines.smirnoff.parameters import (
ParameterList,
ProperTorsionType,
)
def get_torsion_force_constants(system: openmm.System) -> set[float]:
k = list()
for force in system.getForces():
if isinstance(force, openmm.PeriodicTorsionForce):
for torison_index in range(force.getNumTorsions()):
torsion = force.getTorsionParameters(torison_index)
k.append(torsion[6]._value)
return set(k)
force_field = ForceField("openff-2.1.0.offxml")
force_field.deregister_parameter_handler("ImproperTorsions")
# This is super illegal
force_field["ProperTorsions"]._parameters = ParameterList(
[
ProperTorsionType(
smirks="[#1:1]-[*:2]~[*:3]-[#1:4]",
periodicity=[1],
phase=[0],
k=[Quantity(10.0, unit.kilojoule_per_mole)],
idivf=["experimental-auto"],
id="expt1",
)
]
)
for smiles in ["CC", "CO", "C=C", "C#C"]:
print(
smiles,
get_torsion_force_constants(
force_field.create_openmm_system(Molecule.from_smiles(smiles).to_topology())
),
)
# CC {1.1111111111111112}
# CO {3.3333333333333335}
# C=C {2.5}
# C#C {10.0}