Coverage for openxps/simulation.py: 92%
25 statements
« prev ^ index » next coverage.py v7.11.3, created at 2025-11-13 22:08 +0000
« prev ^ index » next coverage.py v7.11.3, created at 2025-11-13 22:08 +0000
1"""
2.. module:: openxps.simulation
3 :platform: Linux, MacOS, Windows
4 :synopsis: Simulation class for extended phase-space simulations with OpenMM.
6.. classauthor:: Charlles Abreu <craabreu@gmail.com>
8"""
10import typing as t
12import openmm as mm
13from openmm import app as mmapp
15from .context import ExtendedSpaceContext
16from .integrator import ExtendedSpaceIntegrator
17from .system import ExtendedSpaceSystem
20class ExtendedSpaceSimulation(mmapp.Simulation):
21 """
22 A :OpenMM:`Simulation` object that uses an :class:`ExtendedSpaceContext` to enable
23 extended phase-space (XPS) simulations with dynamical variables.
25 This class extends :OpenMM:`Simulation` to seamlessly integrate extended phase-space
26 capabilities by creating an :class:`ExtendedSpaceContext` instead of a standard
27 :OpenMM:`Context`. All other functionality is inherited from the base class.
29 **Note**: The system and integrator provided as arguments are modified in place.
31 Parameters
32 ----------
33 topology
34 The :OpenMM:`Topology` describing the system to be simulated.
35 system
36 The :class:`ExtendedSpaceSystem` object to simulate.
37 integrator
38 An :class:`ExtendedSpaceIntegrator` object to be used for advancing the XPS
39 simulation. Available implementations include :class:`LockstepIntegrator` for
40 systems where both integrators use the same step size, and
41 :class:`SplitIntegrator` for systems with different step sizes related by an
42 even integer ratio.
43 platform
44 The :OpenMM:`Platform` to use for calculations. If None, the default Platform
45 will be used.
46 platformProperties
47 A dictionary of platform-specific properties. If None, the default properties
48 will be used.
49 state
50 If specified, the simulation state will be set to this :OpenMM:`State` object
51 after initialization.
53 Example
54 -------
55 >>> import openxps as xps
56 >>> from math import pi
57 >>> import cvpack
58 >>> import openmm
59 >>> from openmm import unit
60 >>> from openmmtools import testsystems
61 >>> model = testsystems.AlanineDipeptideVacuum()
62 >>> mass = 3 * unit.dalton*(unit.nanometer/unit.radian)**2
63 >>> phi0 = xps.DynamicalVariable("phi0", unit.radian, mass, xps.CircularBounds())
64 >>> phi = cvpack.Torsion(6, 8, 14, 16, name="phi")
65 >>> kappa = 1000 * unit.kilojoules_per_mole / unit.radian**2
66 >>> harmonic_force = xps.HarmonicCoupling(phi, phi0, kappa)
67 >>> integrator = openmm.LangevinMiddleIntegrator(
68 ... 300 * unit.kelvin, 1 / unit.picosecond, 4 * unit.femtosecond
69 ... )
70 >>> integrator.setRandomNumberSeed(1234)
71 >>> simulation = xps.ExtendedSpaceSimulation(
72 ... model.topology,
73 ... xps.ExtendedSpaceSystem(model.system, harmonic_force),
74 ... xps.LockstepIntegrator(integrator),
75 ... openmm.Platform.getPlatformByName("Reference"),
76 ... )
77 >>> simulation.context.setPositions(model.positions)
78 >>> simulation.context.setVelocitiesToTemperature(300 * unit.kelvin, 1234)
79 >>> simulation.context.setDynamicalVariableValues([180 * unit.degree])
80 >>> simulation.context.setDynamicalVariableVelocitiesToTemperature(
81 ... 300 * unit.kelvin, 1234
82 ... )
83 >>> simulation.step(100)
84 >>> simulation.context.getDynamicalVariableValues()
85 (... rad,)
86 """
88 def __init__( # noqa: PLR0913 pylint: disable=super-init-not-called
89 self,
90 topology: mmapp.Topology,
91 system: ExtendedSpaceSystem,
92 integrator: ExtendedSpaceIntegrator,
93 platform: t.Optional[mm.Platform] = None,
94 platformProperties: t.Optional[dict] = None,
95 state: t.Optional[mm.State] = None,
96 ) -> None:
97 self.topology = topology
98 self.system = system
100 args = [system, integrator]
101 if platform is not None:
102 args.append(platform)
103 if platformProperties is not None:
104 args.append(platformProperties)
106 self.context = self.extended_space_context = ExtendedSpaceContext(*args)
107 self.integrator = self.context.getIntegrator()
109 self.currentStep = 0
110 self.reporters = []
112 if state is not None:
113 self.context.setState(state)
115 try:
116 self._usesPBC = self.system.usesPeriodicBoundaryConditions()
117 except Exception:
118 self._usesPBC = topology.getUnitCellDimensions() is not None