10
1
mirror of https://gitlab.com/scemama/QCaml.git synced 2024-12-23 12:53:46 +01:00
QCaml/common/lib/coordinate.ml

152 lines
3.5 KiB
OCaml
Raw Normal View History

2020-12-28 01:55:03 +01:00
(* [[file:~/QCaml/common/coordinate.org::*Type][Type:2]] *)
type bohr
type angstrom
2018-02-02 01:25:10 +01:00
type xyz = {
x : float ;
y : float ;
z : float ;
}
type 'a point = xyz
type t = bohr point
2018-02-13 17:36:25 +01:00
type axis = X | Y | Z
2020-12-27 17:23:47 +01:00
(* Type:2 ends here *)
2018-01-17 18:19:38 +01:00
2018-02-14 18:08:43 +01:00
2020-12-27 23:08:12 +01:00
(* | ~make~ | Creates a point in atomic units |
* | ~make_angstrom~ | Creates a point in angstrom |
* | ~zero~ | $(0., 0., 0.)$ | *)
2020-12-28 01:55:03 +01:00
(* [[file:~/QCaml/common/coordinate.org::*Creation][Creation:2]] *)
2020-12-27 23:08:12 +01:00
external make : 'a point -> t = "%identity"
2020-12-27 17:23:47 +01:00
external make_angstrom : 'a point -> angstrom point = "%identity"
2020-12-27 23:08:12 +01:00
let zero =
make { x = 0. ; y = 0. ; z = 0. }
(* Creation:2 ends here *)
(* | ~bohr_to_angstrom~ | Converts a point in bohr to angstrom |
* | ~angstrom_to_bohr~ | Converts a point in angstrom to bohr | *)
2018-01-17 18:19:38 +01:00
2020-12-27 23:08:12 +01:00
2020-12-28 01:55:03 +01:00
(* [[file:~/QCaml/common/coordinate.org::*Conversion][Conversion:2]] *)
2020-12-27 23:08:12 +01:00
let b_to_a b = Constants.a0 *. b
let bohr_to_angstrom { x ; y ; z } =
2020-12-27 17:23:47 +01:00
make { x = b_to_a x ;
y = b_to_a y ;
z = b_to_a z ; }
2018-01-17 18:19:38 +01:00
2020-12-27 23:08:12 +01:00
let a_to_b a = Constants.a0_inv *. a
2020-12-27 17:23:47 +01:00
let angstrom_to_bohr { x ; y ; z } =
make { x = a_to_b x ;
y = a_to_b y ;
z = a_to_b z ; }
2020-12-27 23:08:12 +01:00
(* Conversion:2 ends here *)
2018-01-17 18:19:38 +01:00
2020-12-27 17:23:47 +01:00
2021-01-28 00:34:26 +01:00
(* | ~neg~ | Negative of a point |
* | ~get~ | Extracts the projection of the coordinate on an axis |
* | ~dot~ | Dot product |
* | ~norm~ | $\ell{^2}$ norm of the vector |
* | $\vert .$ | Scales the vector by a constant |
* | $\vert +$ | Adds two vectors |
* | $\vert -$ | Subtracts two vectors |
2020-12-27 23:08:12 +01:00
*
2021-01-28 00:34:26 +01:00
* Example:
2020-12-27 23:08:12 +01:00
* #+begin_example
* Coordinate.neg { x=1. ; y=2. ; z=3. } ;;
2020-12-29 01:08:37 +01:00
* - : Coordinate.t = -1.0000 -2.0000 -3.0000
2020-12-27 23:08:12 +01:00
*
* Coordinate.(get Y { x=1. ; y=2. ; z=3. }) ;;
* - : float = 2.
*
2020-12-27 17:23:47 +01:00
* Coordinate.(
* 2. |. { x=1. ; y=2. ; z=3. }
* ) ;;
2020-12-29 01:08:37 +01:00
* - : Coordinate.t = 2.0000 4.0000 6.0000
2020-12-27 23:08:12 +01:00
*
* Coordinate.(
* { x=1. ; y=2. ; z=3. } |+ { x=2. ; y=3. ; z=1. }
* );;
2020-12-29 01:08:37 +01:00
* - : Coordinate.t = 3.0000 5.0000 4.0000
2020-12-27 23:08:12 +01:00
*
* Coordinate.(
* { x=1. ; y=2. ; z=3. } |- { x=2. ; y=3. ; z=1. }
* );;
2020-12-29 01:08:37 +01:00
* - : Coordinate.t = -1.0000 -1.0000 2.0000
2020-12-27 23:08:12 +01:00
* #+end_example *)
2022-11-07 14:59:11 +01:00
(* [[file:~/QCaml/common/coordinate.org::*Vector operations][Vector operations:2]] *)
2020-12-27 23:08:12 +01:00
let get axis { x ; y ; z } =
match axis with
| X -> x
| Y -> y
| Z -> z
2020-12-27 17:23:47 +01:00
let ( |. ) s { x ; y ; z } =
2020-12-27 17:23:47 +01:00
make { x = s *. x ;
y = s *. y ;
z = s *. z ; }
2018-02-13 17:36:25 +01:00
2020-12-27 17:23:47 +01:00
let ( |+ )
{ x = x1 ; y = y1 ; z = z1 }
{ x = x2 ; y = y2 ; z = z2 } =
make { x = x1 +. x2 ;
y = y1 +. y2 ;
z = z1 +. z2 ; }
2018-01-17 18:19:38 +01:00
2020-12-27 17:23:47 +01:00
let ( |- )
{ x = x1 ; y = y1 ; z = z1 }
{ x = x2 ; y = y2 ; z = z2 } =
make { x = x1 -. x2 ;
y = y1 -. y2 ;
z = z1 -. z2 ; }
let neg a = -1. |. a
2020-12-27 23:08:12 +01:00
2020-12-27 17:23:47 +01:00
let dot
{ x = x1 ; y = y1 ; z = z1 }
{ x = x2 ; y = y2 ; z = z2 } =
x1 *. x2 +.
y1 *. y2 +.
z1 *. z2
2020-12-27 23:08:12 +01:00
let norm u =
sqrt ( dot u u )
(* Vector operations:2 ends here *)
2020-12-27 17:23:47 +01:00
2020-12-27 23:08:12 +01:00
(* Coordinates can be printed in bohr or angstrom. *)
2020-12-27 17:23:47 +01:00
2020-12-28 01:55:03 +01:00
(* [[file:~/QCaml/common/coordinate.org::*Printers][Printers:2]] *)
2018-03-16 00:23:47 +01:00
open Format
let pp ppf c =
fprintf ppf "@[@[%8.4f@] @[%8.4f@] @[%8.4f@]@]" c.x c.y c.z
2018-03-15 15:25:49 +01:00
let pp_bohr ppf c =
2018-03-16 00:23:47 +01:00
fprintf ppf "@[(@[%10f@], @[%10f@], @[%10f@] Bohr)@]" c.x c.y c.z
2018-03-15 15:25:49 +01:00
let pp_angstrom ppf c =
let c = bohr_to_angstrom c in
2018-03-16 00:23:47 +01:00
fprintf ppf "@[(@[%10f@], @[%10f@], @[%10f@] Angs)@]" c.x c.y c.z
2020-12-27 17:23:47 +01:00
(* Printers:2 ends here *)