Sophia Tang
Initial commit with LFS
7efee70
import numpy as np
import openmm.unit as unit
from abc import abstractmethod, ABC
from scipy.constants import physical_constants
class BaseDynamics(ABC):
def __init__(self, args, state):
super().__init__()
self.start_file = f"./data/{args.molecule}/{state}.pdb"
self.temperature = args.temperature * unit.kelvin
self.friction = args.friction / unit.femtoseconds
self.timestep = args.timestep * unit.femtoseconds
self.pdb, self.integrator, self.simulation, self.external_force = self.setup()
self.get_md_info()
self.simulation.minimizeEnergy()
self.position = self.report()[0]
@abstractmethod
def setup(self):
pass
def get_md_info(self):
self.num_particles = self.simulation.system.getNumParticles()
m = np.array([
self.simulation.system.getParticleMass(i).value_in_unit(unit.dalton)
for i in range(self.num_particles)
])
self.heavy_atoms = m > 1.1
m = unit.Quantity(m, unit.dalton)
unadjusted_variance = (
2 * self.timestep * self.friction * unit.BOLTZMANN_CONSTANT_kB * self.temperature / m[:, None]
)
std_SI_units = (
1 / physical_constants["unified atomic mass unit"][0] *
unadjusted_variance.value_in_unit(unit.joule / unit.dalton)
)
self.std = unit.Quantity(
np.sqrt(std_SI_units), unit.meter / unit.second
).value_in_unit(unit.nanometer / unit.femtosecond)
self.m = m.value_in_unit(unit.dalton)
def step(self, forces):
for i in range(forces.shape[0]):
self.external_force.setParticleParameters(i, i, forces[i])
self.external_force.updateParametersInContext(self.simulation.context)
self.simulation.step(1)
def report(self):
state = self.simulation.context.getState(getPositions=True, getForces=True)
positions = state.getPositions().value_in_unit(unit.nanometer)
forces = state.getForces().value_in_unit(
unit.dalton * unit.nanometer / unit.femtosecond ** 2
)
return positions, forces
def reset(self):
for i in range(len(self.position)):
self.external_force.setParticleParameters(i, i, [0, 0, 0])
self.external_force.updateParametersInContext(self.simulation.context)
self.simulation.context.setPositions(self.position)
self.simulation.context.setVelocitiesToTemperature(self.temperature)
def set_temperature(self, temperature):
self.integrator.setTemperature(temperature * unit.kelvin)
def energy_function(self, positions):
forces, potentials = [], []
for i in range(len(positions)):
self.simulation.context.setPositions(positions[i])
state = self.simulation.context.getState(getForces=True, getEnergy=True)
force = state.getForces().value_in_unit(
unit.dalton * unit.nanometer / unit.femtosecond ** 2
)
potential = state.getPotentialEnergy().value_in_unit(
unit.kilojoules / unit.mole
)
forces.append(force)
potentials.append(potential)
return np.array(forces), np.array(potentials)