Source code for mdpy.integrator.langevin_integrator

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
file : langevin_integrator.py
created time : 2021/10/25
author : Zhenyu Wei
copyright : (C)Copyright 2021-present, mdpy organization
"""

import cupy as cp
import numpy as np
from mdpy.core import Ensemble
from mdpy.integrator import Integrator
from mdpy.unit import *
from mdpy.utils import *


[docs]class LangevinIntegrator(Integrator):
[docs] def __init__( self, time_step, temperature, friction_rate, update_tile_list_frequency=10 ) -> None: super().__init__(time_step, update_tile_list_frequency) self._temperature = check_quantity_value(temperature, default_temperature_unit) self._gamma = check_quantity_value(friction_rate, 1 / default_time_unit) self._kbt = ( (Quantity(self._temperature, default_temperature_unit) * KB) .convert_to(default_energy_unit) .value ) self._sigma = np.sqrt(2 * self._kbt * self._gamma) self._a = (1 - self._gamma * self._time_step / 2) / ( 1 + self._gamma * self._time_step / 2 ) self._b = 1 / (1 + self._gamma * self._time_step / 2) self._time_step_square = self._time_step**2 self._time_step_3_over_2 = self._time_step ** (3 / 2) self._time_step_sqrt = np.sqrt(self._time_step) self._cur_velocities = None self._pre_velocities = None self._cur_acceleration = None self._pre_acceleration = None
def integrate(self, ensemble: Ensemble, num_steps: int = 1): # Setting variables cur_step = 0 masses = ensemble.topology.device_masses sqrt_masses = cp.sqrt(masses) self._cur_acceleration = ensemble.forces / masses if self.is_cached == False: self._cur_velocities = ensemble.state.velocities self._pre_velocities = ensemble.state.velocities self._cur_positions = ensemble.state.positions self._pre_positions = ensemble.state.positions self._matrix_shape = list(self._pre_positions.shape) while cur_step < num_steps: # Iterate position if cur_step != 0: ensemble.update_constraints() ensemble.update_constraints() xi_over_sqrt_masses = cp.random.randn(*self._matrix_shape) / sqrt_masses self._pre_acceleration = self._cur_acceleration self._cur_positions, self._pre_positions = ( self._pre_positions + self._b * self._time_step * self._pre_velocities - self._b * self._time_step_square / 2 * self._pre_acceleration + self._b * self._sigma * self._time_step_3_over_2 / 2 * xi_over_sqrt_masses ), self._cur_positions # Update position ensemble.state.set_positions(self._cur_positions) if cur_step % self._update_tile_list_frequency == 0: ensemble.update_tile_list() ensemble.update_constraints() self._cur_acceleration = ensemble.forces / masses self._cur_velocities, self._pre_velocities = ( self._a * self._pre_velocities - self._time_step / 2 * (self._a * self._pre_acceleration + self._cur_acceleration) + self._b * self._sigma * self._time_step_sqrt * xi_over_sqrt_masses ), self._cur_velocities cur_step += 1 ensemble.state.set_velocities(self._cur_velocities)