From 79f1b581f93f7449e153177dc4f58bab1e001315 Mon Sep 17 00:00:00 2001 From: Anthony Scemama Date: Mon, 28 Dec 2020 12:43:32 +0100 Subject: [PATCH] Electrons org-mode --- particles/electrons.org | 160 ++++++++++++++++++++++++++++++++++++ particles/lib/electrons.ml | 34 ++++++-- particles/lib/electrons.mli | 48 ++++++----- particles/test/electrons.ml | 41 +++++---- 4 files changed, 244 insertions(+), 39 deletions(-) create mode 100644 particles/electrons.org diff --git a/particles/electrons.org b/particles/electrons.org new file mode 100644 index 0000000..6f3f1dc --- /dev/null +++ b/particles/electrons.org @@ -0,0 +1,160 @@ +#+begin_src elisp tangle: no :results none :exports none +(setq pwd (file-name-directory buffer-file-name)) +(setq name (file-name-nondirectory (substring buffer-file-name 0 -4))) +(setq lib (concat pwd "lib/")) +(setq testdir (concat pwd "test/")) +(setq mli (concat lib name ".mli")) +(setq ml (concat lib name ".ml")) +(setq test-ml (concat testdir name ".ml")) +(org-babel-tangle) +#+end_src + +* Electrons + :PROPERTIES: + :header-args: :noweb yes :comments both + :END: + + Data structure which contains the number of \alpha and \beta electrons. + +** Type + + #+NAME: types + #+begin_src ocaml :tangle (eval mli) +type t + #+end_src + + #+begin_src ocaml :tangle (eval ml) :exports none +type t = { + n_alfa : int ; + n_beta : int ; +} + #+end_src + + #+begin_src ocaml :tangle (eval test-ml) :exports none +open Common +open Particles +open Alcotest + +let test_all () = + let nuclei = +"3 +Water +O 0. 0. 0. +H -0.756950272703377558 0. -0.585882234512562827 +H 0.756950272703377558 0. -0.585882234512562827 +" + |> Nuclei.of_xyz_string + in + let e = Electrons.of_atoms nuclei in + #+end_src + +** Creation + + #+begin_src ocaml :tangle (eval mli) +open Common + +val make : int -> int -> t + +val of_atoms : ?multiplicity:int -> ?charge:int -> Nuclei.t -> t +(* @param multiplicity default is 1 + @param charge default is 0 + @raise Invalid_argument if the spin multiplicity is not compatible with + the molecule and the total charge. +*) + #+end_src + + | ~make~ | ~make n_alfa n_beta~ | + | ~of_atoms~ | Creates the data relative to electrons for a molecular system described by ~Nuclei.t~ for a given total charge and spin multiplicity. | + + #+begin_src ocaml :tangle (eval ml) :exports none +open Common + +let make n_alfa n_beta = + { n_alfa ; n_beta } + + +let of_atoms ?multiplicity:(multiplicity=1) ?charge:(charge=0) nuclei = + let positive_charges = + Array.fold_left (fun accu (e, _) -> accu + Charge.to_int (Element.to_charge e) ) + 0 nuclei + in + let negative_charges = charge - positive_charges in + let n_elec = - negative_charges in + let n_beta = ((n_elec - multiplicity)+1)/2 in + let n_alfa = n_elec - n_beta in + let result = { n_alfa ; n_beta } in + if multiplicity <> (n_alfa - n_beta)+1 then + invalid_arg (__FILE__^": make"); + result + + #+end_src + + #+begin_src ocaml :tangle (eval test-ml) :exports none +check int "of_atoms alfa" 5 (Electrons.n_alfa e); +check int "of_atoms beta" 5 (Electrons.n_beta e); + #+end_src + +** Access + + #+begin_src ocaml :tangle (eval mli) +val charge : t -> Charge.t +val n_elec : t -> int +val n_alfa : t -> int +val n_beta : t -> int +val multiplicity : t -> int + #+end_src + + | ~charge~ | Sum of the charges of the electrons | + | ~n_elec~ | Number of electrons | + | ~n_alfa~ | Number of alpha electrons | + | ~n_beta~ | Number of beta electrons | + | ~multiplicity~ | Spin multiplicity: $2S+1$ | + + #+begin_src ocaml :tangle (eval ml) :exports none +let charge e = + - (e.n_alfa + e.n_beta) + |> Charge.of_int + +let n_alfa t = t.n_alfa + +let n_beta t = t.n_beta + +let n_elec t = t.n_alfa + t.n_beta + +let multiplicity t = t.n_alfa - t.n_beta + 1 + #+end_src + + #+begin_src ocaml :tangle (eval test-ml) :exports none +check int "charge " (-10) (Charge.to_int @@ Electrons.charge e); +check int "n_elec" 10 (Electrons.n_elec e); +check int "multiplicity" 1 (Electrons.multiplicity e); +check int "of_atoms alfa m3" 6 (Electrons.(of_atoms ~multiplicity:3 nuclei |> n_alfa)); +check int "of_atoms beta m3" 4 (Electrons.(of_atoms ~multiplicity:3 nuclei |> n_beta)); +check int "of_atoms n_elec m3" 10 (Electrons.(of_atoms ~multiplicity:3 nuclei |> n_elec)); +check int "of_atoms alfa m2 c1" 5 (Electrons.(of_atoms ~multiplicity:2 ~charge:1 nuclei |> n_alfa)); +check int "of_atoms beta m2 c1" 4 (Electrons.(of_atoms ~multiplicity:2 ~charge:1 nuclei |> n_beta)); +check int "of_atoms beta m2 c1" 9 (Electrons.(of_atoms ~multiplicity:2 ~charge:1 nuclei |> n_elec)); +check int "of_atoms mult m2 c1" 2 (Electrons.(of_atoms ~multiplicity:2 ~charge:1 nuclei |> multiplicity)); +check bool "make" true (Electrons.make 6 4 = Electrons.(of_atoms ~multiplicity:3 nuclei)); + #+end_src + +** Printers + + #+begin_src ocaml :tangle (eval mli) +val pp : Format.formatter -> t -> unit + #+end_src + + #+begin_src ocaml :tangle (eval ml) :exports none +let pp ppf t = + Format.fprintf ppf "@[n_alfa=%d, n_beta=%d@]" t.n_alfa t.n_beta + #+end_src + +** Tests + + #+begin_src ocaml :tangle (eval test-ml) :exports none + () + +let tests = [ + "all", `Quick, test_all +] + #+end_src diff --git a/particles/lib/electrons.ml b/particles/lib/electrons.ml index 0c382c7..3967554 100644 --- a/particles/lib/electrons.ml +++ b/particles/lib/electrons.ml @@ -1,13 +1,19 @@ -(** Number of {% $\alpha$ %} and {% $\beta$ %} electrons *) - -open Common - +(* [[file:../electrons.org::*Type][Type:2]] *) type t = { n_alfa : int ; n_beta : int ; } +(* Type:2 ends here *) + +(* | ~make~ | ~make n_alfa n_beta~ | + * | ~of_atoms~ | Creates the data relative to electrons for a molecular system described by ~Nuclei.t~ for a given total charge and spin multiplicity. | *) + + +(* [[file:../electrons.org::*Creation][Creation:2]] *) +open Common + let make n_alfa n_beta = { n_alfa ; n_beta } @@ -25,14 +31,32 @@ let of_atoms ?multiplicity:(multiplicity=1) ?charge:(charge=0) nuclei = if multiplicity <> (n_alfa - n_beta)+1 then invalid_arg (__FILE__^": make"); result +(* Creation:2 ends here *) + +(* | ~charge~ | Sum of the charges of the electrons | + * | ~n_elec~ | Number of electrons | + * | ~n_alfa~ | Number of alpha electrons | + * | ~n_beta~ | Number of beta electrons | + * | ~multiplicity~ | Spin multiplicity: $2S+1$ | *) + + +(* [[file:../electrons.org::*Access][Access:2]] *) let charge e = - (e.n_alfa + e.n_beta) |> Charge.of_int - let n_alfa t = t.n_alfa + let n_beta t = t.n_beta + let n_elec t = t.n_alfa + t.n_beta + let multiplicity t = t.n_alfa - t.n_beta + 1 +(* Access:2 ends here *) + +(* [[file:../electrons.org::*Printers][Printers:2]] *) +let pp ppf t = + Format.fprintf ppf "@[n_alfa=%d, n_beta=%d@]" t.n_alfa t.n_beta +(* Printers:2 ends here *) diff --git a/particles/lib/electrons.mli b/particles/lib/electrons.mli index eb66b1b..57a0a3c 100644 --- a/particles/lib/electrons.mli +++ b/particles/lib/electrons.mli @@ -1,33 +1,41 @@ -(** Information related to electrons. *) +(* Type + * + * #+NAME: types *) +(* [[file:../electrons.org::types][types]] *) +type t +(* types ends here *) + +(* Creation *) + + +(* [[file:../electrons.org::*Creation][Creation:1]] *) open Common -type t - val make : int -> int -> t -(** make [n_alfa] [n_beta] *) val of_atoms : ?multiplicity:int -> ?charge:int -> Nuclei.t -> t -(** Creates the data relative to electrons for a molecular system - described by {!Nuclei.t} for a given total charge and spin multiplicity. - @param multiplicity default is 1 - @param charge default is 0 - @raise Invalid_argument if the spin multiplicity is not compatible with +(* @param multiplicity default is 1 + @param charge default is 0 + @raise Invalid_argument if the spin multiplicity is not compatible with the molecule and the total charge. - *) +*) +(* Creation:1 ends here *) -val charge : t -> Charge.t -(** Sum of the charges of the electrons. *) +(* Access *) -val n_elec : t -> int -(** Number of electrons *) -val n_alfa : t -> int -(** Number of alpha electrons *) +(* [[file:../electrons.org::*Access][Access:1]] *) +val charge : t -> Charge.t +val n_elec : t -> int +val n_alfa : t -> int +val n_beta : t -> int +val multiplicity : t -> int +(* Access:1 ends here *) -val n_beta : t -> int -(** Number of beta electrons *) +(* Printers *) -val multiplicity : t -> int -(** Spin multiplicity: {% $2S+1$ %} *) +(* [[file:../electrons.org::*Printers][Printers:1]] *) +val pp : Format.formatter -> t -> unit +(* Printers:1 ends here *) diff --git a/particles/test/electrons.ml b/particles/test/electrons.ml index c60a834..1cfe6b9 100644 --- a/particles/test/electrons.ml +++ b/particles/test/electrons.ml @@ -1,8 +1,8 @@ +(* [[file:../electrons.org::*Type][Type:3]] *) open Common open Particles open Alcotest - let test_all () = let nuclei = "3 @@ -14,21 +14,34 @@ H 0.756950272703377558 0. -0.585882234512562827 |> Nuclei.of_xyz_string in let e = Electrons.of_atoms nuclei in - check int "of_atoms alfa" 5 (Electrons.n_alfa e); - check int "of_atoms beta" 5 (Electrons.n_beta e); - check int "charge " (-10) (Charge.to_int @@ Electrons.charge e); - check int "n_elec" 10 (Electrons.n_elec e); - check int "multiplicity" 1 (Electrons.multiplicity e); - check int "of_atoms alfa m3" 6 (Electrons.(of_atoms ~multiplicity:3 nuclei |> n_alfa)); - check int "of_atoms beta m3" 4 (Electrons.(of_atoms ~multiplicity:3 nuclei |> n_beta)); - check int "of_atoms n_elec m3" 10 (Electrons.(of_atoms ~multiplicity:3 nuclei |> n_elec)); - check int "of_atoms alfa m2 c1" 5 (Electrons.(of_atoms ~multiplicity:2 ~charge:1 nuclei |> n_alfa)); - check int "of_atoms beta m2 c1" 4 (Electrons.(of_atoms ~multiplicity:2 ~charge:1 nuclei |> n_beta)); - check int "of_atoms beta m2 c1" 9 (Electrons.(of_atoms ~multiplicity:2 ~charge:1 nuclei |> n_elec)); - check int "of_atoms mult m2 c1" 2 (Electrons.(of_atoms ~multiplicity:2 ~charge:1 nuclei |> multiplicity)); - check bool "make" true (Electrons.make 6 4 = Electrons.(of_atoms ~multiplicity:3 nuclei)); +(* Type:3 ends here *) + +(* [[file:../electrons.org::*Creation][Creation:3]] *) +check int "of_atoms alfa" 5 (Electrons.n_alfa e); +check int "of_atoms beta" 5 (Electrons.n_beta e); +(* Creation:3 ends here *) + +(* [[file:../electrons.org::*Access][Access:3]] *) +check int "charge " (-10) (Charge.to_int @@ Electrons.charge e); +check int "n_elec" 10 (Electrons.n_elec e); +check int "multiplicity" 1 (Electrons.multiplicity e); +check int "of_atoms alfa m3" 6 (Electrons.(of_atoms ~multiplicity:3 nuclei |> n_alfa)); +check int "of_atoms beta m3" 4 (Electrons.(of_atoms ~multiplicity:3 nuclei |> n_beta)); +check int "of_atoms n_elec m3" 10 (Electrons.(of_atoms ~multiplicity:3 nuclei |> n_elec)); +check int "of_atoms alfa m2 c1" 5 (Electrons.(of_atoms ~multiplicity:2 ~charge:1 nuclei |> n_alfa)); +check int "of_atoms beta m2 c1" 4 (Electrons.(of_atoms ~multiplicity:2 ~charge:1 nuclei |> n_beta)); +check int "of_atoms beta m2 c1" 9 (Electrons.(of_atoms ~multiplicity:2 ~charge:1 nuclei |> n_elec)); +check int "of_atoms mult m2 c1" 2 (Electrons.(of_atoms ~multiplicity:2 ~charge:1 nuclei |> multiplicity)); +check bool "make" true (Electrons.make 6 4 = Electrons.(of_atoms ~multiplicity:3 nuclei)); +(* Access:3 ends here *) + +(* Tests *) + + +(* [[file:../electrons.org::*Tests][Tests:1]] *) () let tests = [ "all", `Quick, test_all ] +(* Tests:1 ends here *)