Source code for pydft_qmmm.hamiltonians.mm_hamiltonian

"""A Hamiltonian representing the MM level of theory.
"""
from __future__ import annotations

from dataclasses import asdict
from dataclasses import dataclass
from typing import Callable
from typing import TYPE_CHECKING

from .hamiltonian import CalculatorHamiltonian
from pydft_qmmm.calculators import InterfaceCalculator
from pydft_qmmm.common import lazy_load
from pydft_qmmm.common import Subsystem
from pydft_qmmm.common import TheoryLevel
from pydft_qmmm.interfaces import MMSettings

if TYPE_CHECKING:
    from pydft_qmmm import System
    from pydft_qmmm.interfaces.interface import MMInterface
    Factory = Callable[[MMSettings], MMInterface]


[docs] @dataclass class MMHamiltonian(CalculatorHamiltonian): r"""A Hamiltonian representing the MM level of theory. Args: forcefield: The files containing forcefield and topology data for the system. nonbonded_method: The method for treating non-bonded interactions, as in OpenMM. nonbonded_cutoff: The distance at which to truncate close-range non-bonded interactions. pme_gridnumber: The number of grid points to include along each lattice edge in PME summation. pme_alpha: The Gaussian width parameter in Ewald summation (:math:`\mathrm{nm^{-1}}`). """ forcefield: str | list[str] nonbonded_method: str = "PME" nonbonded_cutoff: float | int = 14. pme_gridnumber: int | tuple[int, int, int] |None = None pme_alpha: float | int | None = None def __post_init__(self) -> None: """Set level of theory. """ self.theory_level = TheoryLevel.MM
[docs] def build_calculator(self, system: System) -> InterfaceCalculator: """Build the calculator corresponding to the Hamiltonian. Args: system: The system that will be used to calculate the calculator. Returns: The calculator which is defined by the system and the Hamiltonian. """ mm_atoms = self._parse_atoms(system) system.subsystems[mm_atoms] = Subsystem.III if isinstance(self.pme_gridnumber, int): self.pme_gridnumber = (self.pme_gridnumber,) * 3 if isinstance(self.forcefield, str): self.forcefield = [self.forcefield] settings = MMSettings(system=system, **asdict(self)) interface = lazy_load("pydft_qmmm.interfaces").mm_factory(settings) calculator = InterfaceCalculator(system=system, interface=interface) return calculator
def __str__(self) -> str: """Create a LATEX string representation of the Hamiltonian. Returns: The string representation of the Hamiltonian. """ return "H^{MM}" + super().__str__()