2018-01-18 14:56:08 +01:00
|
|
|
type t =
|
2018-01-19 18:11:03 +01:00
|
|
|
| Bohr of (float * float * float)
|
|
|
|
| Angstrom of (float * float * float)
|
2018-01-17 18:19:38 +01:00
|
|
|
|
2018-01-19 17:42:12 +01:00
|
|
|
let a0 = Constants.a0
|
2018-01-17 18:19:38 +01:00
|
|
|
|
2018-01-19 18:11:03 +01:00
|
|
|
let zero = Bohr (0., 0., 0.)
|
2018-01-17 18:19:38 +01:00
|
|
|
|
2018-01-18 14:56:08 +01:00
|
|
|
let of_float_triplet (x,y,z) = function
|
2018-01-19 18:11:03 +01:00
|
|
|
| `Bohr -> Bohr (x,y,z)
|
|
|
|
| `Angstrom -> Angstrom (x,y,z)
|
2018-01-17 18:19:38 +01:00
|
|
|
|
2018-01-18 14:56:08 +01:00
|
|
|
let of_3_floats x y z =
|
|
|
|
of_float_triplet (x,y,z)
|
2018-01-17 18:19:38 +01:00
|
|
|
|
2018-01-19 18:11:03 +01:00
|
|
|
let to_string t =
|
|
|
|
let result (x,y,z) =
|
|
|
|
(string_of_float x)^" "^(string_of_float y)^" "^(string_of_float z)
|
2018-01-18 14:56:08 +01:00
|
|
|
in
|
2018-01-19 18:11:03 +01:00
|
|
|
match t with
|
2018-01-18 14:56:08 +01:00
|
|
|
| Bohr x -> (result x) ^ " Bohr"
|
|
|
|
| Angstrom x -> (result x) ^ " Angstrom"
|
2018-01-17 18:19:38 +01:00
|
|
|
|
|
|
|
|
2018-01-19 18:11:03 +01:00
|
|
|
let extract_float_tuple = function
|
2018-01-18 14:56:08 +01:00
|
|
|
| Bohr a
|
|
|
|
| Angstrom a -> a
|
2018-01-17 18:19:38 +01:00
|
|
|
|
|
|
|
|
2018-01-18 14:56:08 +01:00
|
|
|
(** Linear algebra *)
|
2018-01-17 18:19:38 +01:00
|
|
|
let (|.) s a =
|
|
|
|
match a with
|
2018-01-19 18:11:03 +01:00
|
|
|
| Bohr (x,y,z) -> Bohr ( s*.x, s*.y, s*.z )
|
|
|
|
| Angstrom (x,y,z) -> Angstrom ( s*.x, s*.y, s*.z )
|
2018-01-17 18:19:38 +01:00
|
|
|
|
2018-01-18 14:56:08 +01:00
|
|
|
let to_Angstrom = function
|
|
|
|
| Angstrom a -> Angstrom a
|
2018-01-19 18:11:03 +01:00
|
|
|
| Bohr a -> Angstrom (a0 |. Bohr a |> extract_float_tuple)
|
2018-01-18 14:56:08 +01:00
|
|
|
|
|
|
|
let to_Bohr = function
|
2018-01-19 18:11:03 +01:00
|
|
|
| Angstrom a -> Bohr (1./.a0 |. Angstrom a |> extract_float_tuple)
|
2018-01-18 14:56:08 +01:00
|
|
|
| Bohr a -> Bohr a
|
|
|
|
|
|
|
|
let (|-), (|+) =
|
|
|
|
let rec op f p q =
|
|
|
|
match (p, q) with
|
|
|
|
| (Angstrom a, Angstrom b) -> Angstrom (f a b)
|
|
|
|
| (Bohr a, Bohr b) -> Bohr (f a b)
|
|
|
|
| (Angstrom a, Bohr b) -> op f (to_Bohr p) q
|
|
|
|
| (Bohr a, Angstrom b) -> op f p (to_Bohr q)
|
|
|
|
in
|
2018-01-19 18:11:03 +01:00
|
|
|
(op (fun (x,y,z) (x',y',z') -> ( x-.x', y-.y', z-.z' )) ,
|
|
|
|
op (fun (x,y,z) (x',y',z') -> ( x+.x', y+.y', z+.z' ))
|
2018-01-18 14:56:08 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
2018-01-19 18:11:03 +01:00
|
|
|
let rec dot p q =
|
|
|
|
match (p,q) with
|
|
|
|
| Bohr (x,y,z), Bohr (x',y',z') -> x*.x' +. y*.y' +. z*.z'
|
|
|
|
| _ -> dot (to_Bohr p) (to_Bohr q)
|
2018-01-17 18:19:38 +01:00
|
|
|
|
|
|
|
|
|
|
|
let norm u =
|
|
|
|
sqrt @@ dot u u
|
|
|
|
|
2018-01-18 14:56:08 +01:00
|
|
|
|
2018-01-19 18:11:03 +01:00
|
|
|
let rec to_tuple a =
|
|
|
|
to_Bohr a |> extract_float_tuple
|
|
|
|
|
|
|
|
let x a =
|
|
|
|
let (result, _, _) = extract_float_tuple @@ to_Bohr a in
|
|
|
|
result
|
2018-01-19 17:42:12 +01:00
|
|
|
|
2018-01-19 18:11:03 +01:00
|
|
|
let y a =
|
|
|
|
let (_, result, _) = extract_float_tuple @@ to_Bohr a in
|
|
|
|
result
|
2018-01-19 17:42:12 +01:00
|
|
|
|
2018-01-19 18:11:03 +01:00
|
|
|
let z a =
|
|
|
|
let (_, _, result) = extract_float_tuple @@ to_Bohr a in
|
|
|
|
result
|
2018-01-19 17:42:12 +01:00
|
|
|
|
|
|
|
let coord a = function
|
2018-01-19 18:11:03 +01:00
|
|
|
| 0 -> x a
|
|
|
|
| 1 -> y a
|
|
|
|
| 2 -> z a
|
2018-01-19 17:42:12 +01:00
|
|
|
| _ -> raise (Invalid_argument "Coordinate")
|
|
|
|
|