type bohr = Bohr.t type angstrom = Angstrom.t type t = bohr type axis = X | Y | Z let a_to_b a = Constants.a0_inv *. a let b_to_a b = Constants.a0 *. b let bohr_to_angstrom { Bohr.x ; y ; z } = Angstrom.make { Point. x = b_to_a x ; y = b_to_a y ; z = b_to_a z ; } let angstrom_to_bohr { Angstrom.x ; y ; z } = Bohr.make { Point. x = a_to_b x ; y = a_to_b y ; z = a_to_b z ; } let zero = Bohr.make { Point.x = 0. ; y = 0. ; z = 0. } (** Linear algebra *) let ( |. ) s { Bohr.x ; y ; z } = Bohr.make { Point. x = s *. x ; y = s *. y ; z = s *. z ; } let ( |+ ) { Bohr.x = x1 ; y = y1 ; z = z1 } { Bohr.x = x2 ; y = y2 ; z = z2 } = Bohr.make { Point. x = x1 +. x2 ; y = y1 +. y2 ; z = z1 +. z2 ; } let ( |- ) { Bohr.x = x1 ; y = y1 ; z = z1 } { Bohr.x = x2 ; y = y2 ; z = z2 } = Bohr.make { Point. x = x1 -. x2 ; y = y1 -. y2 ; z = z1 -. z2 ; } let neg a = -1. |. a let dot { Bohr.x = x1 ; y = y1 ; z = z1 } { Bohr.x = x2 ; y = y2 ; z = z2 } = x1 *. x2 +. y1 *. y2 +. z1 *. z2 let norm u = sqrt ( dot u u ) let get axis { Bohr.x ; y ; z } = match axis with | X -> x | Y -> y | Z -> z