Source code for maxwelllink.em_solvers.gridmd

# --------------------------------------------------------------------------------------#
# Copyright (c) 2026 MaxwellLink                                                        #
# This file is part of MaxwellLink. Repository: https://github.com/TaoELi/MaxwellLink   #
# If you use this code, always credit and cite arXiv:2512.06173.                        #
# See AGENTS.md and README.md for details.                                              #
# --------------------------------------------------------------------------------------#

"""
GridMD implemented in MaxwellLink: Thermodynamical sampling of molecular properties under
large-scale inhomogenenous EM fields.
"""

from __future__ import annotations

from typing import Iterable, Optional, Union, Callable

import numpy as np

from ..molecule import Molecule
from ..sockets import SocketHub
from .laser_driven import LaserDrivenSimulation


[docs] class GridMDSimulation(LaserDrivenSimulation): r""" GridMD of the MaxwellLink molecules. This class samples the inhomogenenous electric field on molecules via a time-dependent stochastic electric field. .. math:: E(t) = f(t) A thermostat should be attached to the molecules as well for removing the artificial excitation due to the electric field time evolution. All quantities are in atomic units. """
[docs] def __init__( self, dt_au: float, molecules: Optional[Iterable[Molecule]] = None, hub: Optional[SocketHub] = None, # GridMD specific options grid_diffusion_au: float = 1e-4, dimension: int = 1, efield_map: Optional[Union[float, Callable[[float], float]]] = None, # end with GridMD specific options coupling_axis: str = "xyz", record_history: bool = True, ): super().__init__( dt_au=dt_au, molecules=molecules, drive=None, coupling_axis=coupling_axis, hub=hub, record_history=record_history, ) self.grid_diffusion_au = grid_diffusion_au self.dimension = dimension self.efield_map = efield_map # store coordinates of the grid point self.R0 = np.array([0.0, 0.0, 0.0]) # initial coordinate self.R = np.copy(self.R0) # instantaneous coordinate self.R_history = [] # history trajectory of the COM grid point # determine the output label in self.run() self._tag = "GridMD"
# ------------------------------------------------------------------ # Core helpers [reloaded] # ------------------------------------------------------------------ def _calc_effective_efield(self, time_au: float) -> np.ndarray: """ Calculate the effective electric field vector for GridMD. Parameters ---------- time_au : float Current time in atomic units. Returns ------- numpy.ndarray of float, shape (3,) Effective electric field vector in atomic units. """ # LaserDrivenSimulation almost has everything for GridMD except an explicit # biased Langevin motion of the E-field, representing the center-of-mass motion # of molecules under large-scale inhomogenous EM fields. efield_vec = np.ones(3, dtype=float) # We need to propagate E_vec at each time step now ... # finally filtered by the axes (so users can decide to turn off interactions at specific dimensions) efield_vec *= self.axis return efield_vec