Sophia Tang
Initial commit with LFS
7efee70
Raw
History Blame Contribute Delete
3.28 kB
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)