Source code for MDMC.MD.engine_facades.facade

"""Module containing an abstract base class for MD engine facades"""
from abc import ABC, abstractmethod
from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
    from MDMC.MD.simulation import Simulation
    from MDMC.trajectory_analysis.compact_trajectory import CompactTrajectory
    from MDMC.trajectory_analysis.trajectory import Configuration


[docs] class MDEngine(ABC): """Abstract base class for MD engine facades""" def __repr__(self) -> str: return ('<{0}\n' ' {{MD_engine: {MD_engine},\n' ' exp_datasets: {exp_datasets},\n' ' FoM_calculator: {FoM_calculator},\n' ' minimizer: {minimizer},\n' ' reset_config: {reset_config},\n' ' fit_parameters: {fit_parameters},\n' ' settings: {settings}}}>').format(self.__class__.__name__, **self.__dict__) @property @abstractmethod def saved_config(self) -> 'Configuration': """ Get the saved configuration of the atomic positions Returns ------- ``Configuration`` The atomic positions """ raise NotImplementedError @property def parent_simulation(self) -> 'Simulation': """ Get or set the simulation that created this engine facade Returns ------- `Simulation` The Simulation object that created this engine facade """ try: return self._parent_simulation except AttributeError as error: raise AttributeError("This MD engine does not belong to a simulation. " "MD engines should be created through initialising Simulations." "") from error @parent_simulation.setter def parent_simulation(self, value: 'Simulation') -> None: # pylint: disable=attribute-defined-outside-init # as this is internal and abstract self._parent_simulation = value @property def time_step(self) -> float: """ Get the simulation time step in ``fs`` from the parent simulation Returns ------- `float` Simulation time step in ``fs`` """ return self.parent_simulation.time_step @property def traj_step(self) -> int: """ Get the number of simulation steps between saving the ``CompactTrajectory`` from the parent simulation Returns ------- `int` Number of simulation steps that elapse between the ``CompactTrajectory`` being stored """ try: return self.parent_simulation.traj_step except AttributeError: return None
[docs] @abstractmethod def setup_universe(self, universe: str, **settings: dict) -> None: """ Creates a ``Universe.configuration`` and populates with ``Structure`` Parameters ---------- universe : Universe A molecular dynamics ``Universe`` which will be setup in the ``MDEngine``. **settings The majority of these are generic but some are specific to the ``MDEngine`` that is being used. """ raise NotImplementedError
[docs] @abstractmethod def setup_simulation(self, **settings: dict) -> None: """ Sets the options required to perform a simulation on a setup ``Universe``. Must follow a call to ``setup_universe()``. Parameters ---------- universe : Universe A molecular dynamics ``Universe`` which will be simulated in the ``MDEngine``. settings** The majority of these are generic but some are specific to the ``MDEngine`` that is being used. """ raise NotImplementedError
[docs] @abstractmethod def minimize(self, n_steps: int, minimize_every: int = 10, **settings: dict) -> None: """ Minimizes the simulation energy Parameters ---------- n_steps : int Maximum number of MD steps during the energy minimization. minimize_every : int, optional, default 10 Number of MD steps between two consecutive minimizations. """ raise NotImplementedError
[docs] @abstractmethod def run(self, n_steps: int, equilibration: bool) -> None: """ Runs a simulation. Must follow a call to ``setup_universe()`` and ``setup_simulation()``. Parameters ---------- n_steps : int Number of steps for the time integrator. equilibration : bool If `True`, run is equilibration which does not store the ``trajectory``. Otherwise run is prodution. """ raise NotImplementedError
[docs] @abstractmethod def convert_trajectory(self, start: int = 0, stop: int = None, step: int = 1, **settings: dict) -> 'CompactTrajectory': """ Parses the trajectory from the ``MDEngine`` format into MDMC format Parameters ---------- start : int The index of the first trajectory, inclusive. stop : int The index of the last trajectory, exclusive. step : int The step size between trajectories. **settings ``scaled_positions`` (`bool`) If the ``trajectory_file`` has scaled ``positions`` ``atom_IDs`` (`list`) LAMMPS ``ID`` of the atoms which should be included. If not passed then all atoms are included in the converted trajectory. Returns ------- ``CompactTrajectory`` The ``CompactTrajectory`` from the most recent production simulation """ # convert_trajectory has no range function as it is assumed that the # trajectory that is calculated by MD is exactly what is required raise NotImplementedError
[docs] @abstractmethod def update_parameters(self) -> None: """ Updates the ``MDEngine`` force field ``Parameter`` objects from the ``Universe`` """ raise NotImplementedError
[docs] @abstractmethod def save_config(self) -> None: """ Sets ``self.saved_config`` to the current configuration """ raise NotImplementedError
[docs] def clear(self) -> None: """ Deletes all atoms of the MD engine, restores all settings to their default values, and frees all memory. """ raise NotImplementedError
[docs] @abstractmethod def reset_config(self) -> None: """ Resets the configuration of the simulation to that in ``saved_config`` """ raise NotImplementedError
[docs] @abstractmethod def eval(self, variable: str) -> Any: """ Evaluates some simulation variable. """ raise NotImplementedError
[docs] class MDEngineError(Exception): "Raised when MD engine raises an exception from a run command"