Source code for openff.interchange.components.base

"""
Base models for engine- and force field-agnostic components.
"""
from openff.units import unit
from pydantic import Field
from typing_extensions import Literal

from openff.interchange.components.potentials import PotentialHandler
from openff.interchange.types import FloatQuantity


[docs]class BaseBondHandler(PotentialHandler): """Base handler for storing generic bond interactions.""" type: str = "Bonds" expression: str = "k/2*(r-length)**2"
[docs]class BaseAngleHandler(PotentialHandler): """Base handler for storing generic angle interactions.""" type: str = "Angle" expression: str = "k/2*(theta-angle)**2"
[docs]class BaseProperTorsionHandler(PotentialHandler): """Base handler for storing generic proper torsion interactions.""" type: str = "ProperTorsions" expression: str = "k*(1+cos(periodicity*theta-phase))"
[docs]class BaseImproperTorsionHandler(PotentialHandler): """Base handler for storing generic improper torsion interactions.""" type: str = "ImproperTorsions" expression: str = "k*(1+cos(periodicity*theta-phase))"
class _BaseNonbondedHandler(PotentialHandler): """Base handler for storing generic nonbonded interactions.""" type: str = "Nonbonded" scale_13: float = Field( 0.0, description="The scaling factor applied to 1-3 interactions" ) scale_14: float = Field( 0.5, description="The scaling factor applied to 1-4 interactions" ) scale_15: float = Field( 1.0, description="The scaling factor applied to 1-5 interactions" ) cutoff: FloatQuantity["angstrom"] = Field( # type: ignore 10.0 * unit.angstrom, description="The distance at which pairwise interactions are truncated", )
[docs]class BasevdWHandler(_BaseNonbondedHandler): """Base handler for storing vdW interactions.""" type: str = "vdW" expression: str = "4*epsilon*((sigma/r)**12-(sigma/r)**6)" method: Literal["cutoff", "pme", "no-cutoff"] = Field("cutoff") mixing_rule: str = Field( "lorentz-berthelot", description="The mixing rule (combination rule) used in computing pairwise vdW interactions", )
[docs]class BaseElectrostaticsHandler(_BaseNonbondedHandler): """Base handler for storing vdW interactions.""" type: str = "Electrostatics" expression: str = "coul" method: Literal["pme", "cutoff", "reaction-field", "no-cutoff"] = Field("pme") @property def charges(self): """Get the total partial charge on each atom, excluding virtual sites.""" return { topology_key: self.potentials[potential_key].parameters["charge"] for topology_key, potential_key in self.slot_map.items() }