pub struct MdState {Show 18 fields
pub cfg: MdConfig,
pub atoms: Vec<AtomDynamics>,
pub water: Vec<WaterMol>,
pub adjacency_list: Vec<Vec<usize>>,
pub time: f64,
pub step_count: usize,
pub snapshots: Vec<Snapshot>,
pub cell: SimBox,
pub neighbors_nb: NeighborsNb,
pub water_pme_sites_forces: Vec<[Vec3; 3]>,
pub kinetic_energy: f64,
pub potential_energy: f64,
pub potential_energy_nonbonded: f64,
pub potential_energy_bonded: f64,
pub potential_energy_between_mols: Vec<f64>,
pub neighbor_rebuild_count: usize,
pub computation_time: ComputationTimeSums,
pub mol_start_indices: Vec<usize>,
/* private fields */
}Fields§
§cfg: MdConfig§atoms: Vec<AtomDynamics>§water: Vec<WaterMol>§adjacency_list: Vec<Vec<usize>>Note: We don’t use bond structs once the simulation is set up; the adjacency list is the source of this.
time: f64Current simulation time, in picoseconds.
step_count: usize§snapshots: Vec<Snapshot>These are the snapshots we keep in memory, accumulating.
cell: SimBox§neighbors_nb: NeighborsNb§water_pme_sites_forces: Vec<[Vec3; 3]>§kinetic_energy: f64kcal/mol
potential_energy: f64§potential_energy_nonbonded: f64A newer, simpler approach for energy between molecules, compared to potential_energy_between_mols.
This is simply the potential energy from non-bonded interactions, and excludes that from bonded.
potential_energy_bonded: f64E.g. energy in covalent bonds, as modelled as oscillators.
potential_energy_between_mols: Vec<f64>Every so many snapshots, write these to file, then clear from memory. Used to track which molecule each atom is associated with in our flattened structures. This is the potential energy between every pair of molecules.
neighbor_rebuild_count: usize§computation_time: ComputationTimeSums§mol_start_indices: Vec<usize>Used to track which molecule each atom is associated with in our flattened structures.
Implementations§
Source§impl MdState
impl MdState
Sourcepub fn apply_angle_bending_forces(&mut self)
pub fn apply_angle_bending_forces(&mut self)
This maintains bond angles between sets of three atoms as they should be from hybridization. It reflects this hybridization, steric clashes, and partial double-bond character. This identifies deviations from the ideal angle, calculates restoring torque, and applies forces based on this to push the atoms back into their ideal positions in the molecule.
Valence angles, which are the angle formed by two adjacent bonds ba et bc in a same molecule; a valence angle tends to maintain constant the anglê abc. A valence angle is thus concerned by the positions of three atoms.
Source§impl MdState
impl MdState
Sourcepub fn step(&mut self, dev: &ComputationDevice, dt: f32)
pub fn step(&mut self, dev: &ComputationDevice, dt: f32)
Perform one integration step. This is the entry point for running the simulation.
One step of length dt is in picoseconds (10^-12),
with typical values of 0.001, or 0.002ps (1 or 2fs).
This method orchestrates the dynamics at each time step. Uses a Verlet Velocity base,
with different thermostat approaches depending on configuration.
Examples found in repository?
11fn main() {
12 let dev = ComputationDevice::Cpu;
13 let param_set = FfParamSet::new_amber().unwrap();
14
15 let mut protein = MmCif::load(Path::new("1c8k.cif")).unwrap();
16 let mol = Mol2::load(Path::new("CPB.mol2")).unwrap();
17
18 // Add Hydrogens, force field type, and partial charge to atoms in the protein; these usually aren't
19 // included from RSCB PDB. You can also call `populate_hydrogens_dihedrals()`, and
20 // `populate_peptide_ff_and_q() separately. Add bonds.
21 let (_bonds, _dihedrals) = prepare_peptide_mmcif(
22 &mut protein,
23 ¶m_set.peptide_ff_q_map.as_ref().unwrap(),
24 7.0,
25 )
26 .unwrap();
27
28 let mols = vec![
29 MolDynamics::from_mol2(&mol, None),
30 MolDynamics {
31 ff_mol_type: FfMolType::Peptide,
32 atoms: protein.atoms.clone(),
33 static_: true,
34 ..Default::default()
35 },
36 ];
37
38 let mut md = MdState::new(&dev, &MdConfig::default(), &mols, ¶m_set).unwrap();
39
40 let n_steps = 100;
41 let dt = 0.002; // picoseconds.
42
43 for _ in 0..n_steps {
44 md.step(&dev, dt);
45 }
46
47 let snap = &md.snapshots[md.snapshots.len() - 1]; // A/R.
48 println!(
49 "KE: {}, PE: {}, Atom posits:",
50 snap.energy_kinetic, snap.energy_potential
51 );
52 for posit in &snap.atom_posits {
53 println!("Posit: {posit}");
54 // Also keeps track of velocities, and water molecule positions/velocity
55 }
56
57 // Do something with snapshot data, like displaying atom positions in your UI.
58 // You can save to DCD file, and adjust the ratio they're saved at using the `MdConfig.snapshot_setup`
59 // field: See the example below.
60 for snap in &md.snapshots {}
61}Source§impl MdState
impl MdState
Sourcepub fn apply_nonbonded_forces(&mut self, dev: &ComputationDevice)
pub fn apply_nonbonded_forces(&mut self, dev: &ComputationDevice)
Run the appropriate force-computation function to get force on non-water atoms, force on water atoms, and virial sum for the barostat. Uses GPU if available.
Applies Coulomb and Van der Waals (Lennard-Jones) forces on non-water atoms, in place. We use the MD-standard [S]PME approach to handle approximated Coulomb forces. This function applies forces from non-water, and water sources.
Source§impl MdState
impl MdState
pub fn pack_atoms(&mut self)
Source§impl MdState
impl MdState
Sourcepub fn md_on_water_only(&mut self, dev: &ComputationDevice)
pub fn md_on_water_only(&mut self, dev: &ComputationDevice)
Use this to help initialize water molecules to realistic geometry of hydrogen bond networks, prior to the first proper simulation step. Runs MD on water only. Make sure to only run this after state is properly initialized, e.g. towards the end of init; not immediately after populating waters.
This will result in an immediate energy bump as water positions settle from their grid into position. As they settle, the thermostat will bring the velocities down to set the target temp. This sim should run long enough to the water is stable by the time the main sim starts.
Source§impl MdState
impl MdState
Sourcepub fn zero_linear_momentum(&mut self)
pub fn zero_linear_momentum(&mut self)
Remove center-of-mass drift. This can help stabilize system energy. We perform the sums here as f64.
Sourcepub fn zero_angular_momentum(&mut self)
pub fn zero_angular_momentum(&mut self)
Remove rigid-body rotation. Computes ω from I ω = L about the atoms’ COM, then sets v’ = v - ω × (r - r_cm).
Source§impl MdState
impl MdState
Sourcepub fn minimize_energy(&mut self, dev: &ComputationDevice, max_iters: usize)
pub fn minimize_energy(&mut self, dev: &ComputationDevice, max_iters: usize)
Relaxes the molecules. Use this at the start of the simulation to control kinetic energy that arrises from differences between atom positions, and bonded parameters. It can also be called externally. It also stabilizes the water molecules, so that their hydrogen bond structure is correct at initialization.
Uses flexible bonds to hydrogen. (Not Shake/Rattle constraints)
We don’t apply this to water molecules, as we have a pre-sim set up for them that runs prior to this.
Source§impl MdState
impl MdState
Sourcepub fn new(
dev: &ComputationDevice,
cfg: &MdConfig,
mols: &[MolDynamics],
param_set: &FfParamSet,
) -> Result<Self, ParamError>
pub fn new( dev: &ComputationDevice, cfg: &MdConfig, mols: &[MolDynamics], param_set: &FfParamSet, ) -> Result<Self, ParamError>
Examples found in repository?
11fn main() {
12 let dev = ComputationDevice::Cpu;
13 let param_set = FfParamSet::new_amber().unwrap();
14
15 let mut protein = MmCif::load(Path::new("1c8k.cif")).unwrap();
16 let mol = Mol2::load(Path::new("CPB.mol2")).unwrap();
17
18 // Add Hydrogens, force field type, and partial charge to atoms in the protein; these usually aren't
19 // included from RSCB PDB. You can also call `populate_hydrogens_dihedrals()`, and
20 // `populate_peptide_ff_and_q() separately. Add bonds.
21 let (_bonds, _dihedrals) = prepare_peptide_mmcif(
22 &mut protein,
23 ¶m_set.peptide_ff_q_map.as_ref().unwrap(),
24 7.0,
25 )
26 .unwrap();
27
28 let mols = vec![
29 MolDynamics::from_mol2(&mol, None),
30 MolDynamics {
31 ff_mol_type: FfMolType::Peptide,
32 atoms: protein.atoms.clone(),
33 static_: true,
34 ..Default::default()
35 },
36 ];
37
38 let mut md = MdState::new(&dev, &MdConfig::default(), &mols, ¶m_set).unwrap();
39
40 let n_steps = 100;
41 let dt = 0.002; // picoseconds.
42
43 for _ in 0..n_steps {
44 md.step(&dev, dt);
45 }
46
47 let snap = &md.snapshots[md.snapshots.len() - 1]; // A/R.
48 println!(
49 "KE: {}, PE: {}, Atom posits:",
50 snap.energy_kinetic, snap.energy_potential
51 );
52 for posit in &snap.atom_posits {
53 println!("Posit: {posit}");
54 // Also keeps track of velocities, and water molecule positions/velocity
55 }
56
57 // Do something with snapshot data, like displaying atom positions in your UI.
58 // You can save to DCD file, and adjust the ratio they're saved at using the `MdConfig.snapshot_setup`
59 // field: See the example below.
60 for snap in &md.snapshots {}
61}pub fn computation_time(&self) -> Result<ComputationTime>
Trait Implementations§
Auto Trait Implementations§
impl Freeze for MdState
impl !RefUnwindSafe for MdState
impl !Send for MdState
impl !Sync for MdState
impl Unpin for MdState
impl !UnwindSafe for MdState
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.