gosh_dimer/dimer.rs
1// [[file:../dimer.note::782181ce][782181ce]]
2use super::*;
3// 782181ce ends here
4
5// [[file:../dimer.note::df98a463][df98a463]]
6/// Optimized results in DIMER algorithm
7pub struct DimerOutput {
8 /// DIMER energy, which is equal to potential energy when at dimer center.
9 pub total_energy: f64,
10 /// The effective force felt at dimer center (modified force for DIMER translation)
11 pub effective_force: Vec<f64>,
12 /// The optimized lowest curvature
13 pub curvature: f64,
14}
15
16/// Main entry point for DIMER algorithm.
17impl Dimer {
18 /// Optimize `orientation` into the lowest curvature mode in Dimer
19 /// algorithm. `pot` is a potential surface walker for evaluation of energy
20 /// and force required in optimization. The dimer center is set as current
21 /// position of potential `pot`. `pot` will be reset to its starting
22 /// position on done. On input, `orientation` is the starting orientation of
23 /// the dimer. On output, `orientation` is the optimized dimer orientation
24 /// with lowest curvature.
25 pub fn optimize_rotation(&mut self, orientation: &mut [f64], pot: &mut impl EvaluateDimer) -> Result<DimerOutput> {
26 let center = pot.position().to_vector();
27 assert_eq!(center.len(), orientation.len());
28 let mut tau = orientation.to_vector().normalize();
29
30 let rotation = self.next_rotation_step(¢er, &mut tau, self.vars.max_num_rot, pot)?;
31 let mut raw_dimer = rotation.raw_dimer;
32 let c_min = rotation.curvature_min;
33 let effective_force = self
34 .next_translation_step(&tau, &mut raw_dimer, c_min)
35 .as_slice()
36 .to_vec();
37 orientation.clone_from_slice(tau.as_slice());
38 // reset potential to starting point
39 pot.set_position(center.as_slice());
40
41 Ok(DimerOutput {
42 effective_force,
43 curvature: c_min,
44 total_energy: rotation.energy,
45 })
46 }
47}
48// df98a463 ends here