(* [[file:../coordinate.org::*Type][Type:2]] *) type bohr type angstrom type xyz = { x : float ; y : float ; z : float ; } type 'a point = xyz type t = bohr point type axis = X | Y | Z (* Type:2 ends here *) (* [[file:../coordinate.org::*~make~][~make~:2]] *) external make : 'a point -> t = "%identity" (* ~make~:2 ends here *) (* [[file:../coordinate.org::*~make_angstrom~][~make_angstrom~:2]] *) external make_angstrom : 'a point -> angstrom point = "%identity" (* ~make_angstrom~:2 ends here *) (* [[file:../coordinate.org::*~bohr_to_angstrom~][~bohr_to_angstrom~:2]] *) let b_to_a b = Constants.a0 *. b let bohr_to_angstrom { x ; y ; z } = make { x = b_to_a x ; y = b_to_a y ; z = b_to_a z ; } (* ~bohr_to_angstrom~:2 ends here *) (* [[file:../coordinate.org::*~angstrom_to_bohr~][~angstrom_to_bohr~:2]] *) let a_to_b a = Constants.a0_inv *. a let angstrom_to_bohr { x ; y ; z } = make { x = a_to_b x ; y = a_to_b y ; z = a_to_b z ; } (* ~angstrom_to_bohr~:2 ends here *) (* [[file:../coordinate.org::*~zero~][~zero~:2]] *) let zero = make { x = 0. ; y = 0. ; z = 0. } (* ~zero~:2 ends here *) (* [[file:../coordinate.org::*~get~][~get~:2]] *) let get axis { x ; y ; z } = match axis with | X -> x | Y -> y | Z -> z (* ~get~:2 ends here *) (* #+begin_example * Coordinate.( * 2. |. { x=1. ; y=2. ; z=3. } * ) ;; * - : Coordinate.t = {Qcaml.Common.Coordinate.x = 2.; y = 4.; z = 6.} * #+end_example *) (* [[file:../coordinate.org::*Scale][Scale:2]] *) let ( |. ) s { x ; y ; z } = make { x = s *. x ; y = s *. y ; z = s *. z ; } (* Scale:2 ends here *) (* #+begin_example * Coordinate.( * { x=1. ; y=2. ; z=3. } |+ { x=2. ; y=3. ; z=1. } * );; * - : Coordinate.t = {Qcaml.Common.Coordinate.x = 3.; y = 5.; z = 4.} * #+end_example *) (* [[file:../coordinate.org::*Add][Add:2]] *) let ( |+ ) { x = x1 ; y = y1 ; z = z1 } { x = x2 ; y = y2 ; z = z2 } = make { x = x1 +. x2 ; y = y1 +. y2 ; z = z1 +. z2 ; } (* Add:2 ends here *) (* #+begin_example * Coordinate.( * { x=1. ; y=2. ; z=3. } |- { x=2. ; y=3. ; z=1. } * );; * - : Coordinate.t = {Qcaml.Common.Coordinate.x = -1.; y = -1.; z = 2.} * #+end_example *) (* [[file:../coordinate.org::*Subtract][Subtract:2]] *) let ( |- ) { x = x1 ; y = y1 ; z = z1 } { x = x2 ; y = y2 ; z = z2 } = make { x = x1 -. x2 ; y = y1 -. y2 ; z = z1 -. z2 ; } (* Subtract:2 ends here *) (* #+begin_example * Coordinate.neg { x=1. ; y=2. ; z=3. } ;; * - : Coordinate.t = {Qcaml.Common.Coordinate.x = -1.; y = -2.; z = -3.} * #+end_example *) (* [[file:../coordinate.org::*Negative][Negative:2]] *) let neg a = -1. |. a (* Negative:2 ends here *) (* [[file:../coordinate.org::*Dot product][Dot product:2]] *) let dot { x = x1 ; y = y1 ; z = z1 } { x = x2 ; y = y2 ; z = z2 } = x1 *. x2 +. y1 *. y2 +. z1 *. z2 (* Dot product:2 ends here *) (* $\ell{^2}$ norm of the vector. *) (* [[file:../coordinate.org::*Norm][Norm:2]] *) let norm u = sqrt ( dot u u ) (* Norm:2 ends here *) (* [[file:../coordinate.org::*Printers][Printers:2]] *) open Format let pp ppf c = fprintf ppf "@[@[%8.4f@] @[%8.4f@] @[%8.4f@]@]" c.x c.y c.z let pp_bohr ppf c = fprintf ppf "@[(@[%10f@], @[%10f@], @[%10f@] Bohr)@]" c.x c.y c.z let pp_angstrom ppf c = let c = bohr_to_angstrom c in fprintf ppf "@[(@[%10f@], @[%10f@], @[%10f@] Angs)@]" c.x c.y c.z (* Printers:2 ends here *)