From 68d022987e721deab170dab22916ff546c1c225a Mon Sep 17 00:00:00 2001 From: Anthony Scemama Date: Mon, 28 Dec 2020 23:27:33 +0100 Subject: [PATCH] Elements org --- particles/element.org | 328 ++++++++++++++++++++++++++++++++++++ particles/lib/electrons.ml | 8 +- particles/lib/electrons.mli | 8 +- particles/lib/element.ml | 293 +++++++++++++++++++------------- particles/lib/element.mli | 94 ++++------- particles/test/electrons.ml | 8 +- 6 files changed, 551 insertions(+), 188 deletions(-) create mode 100644 particles/element.org diff --git a/particles/element.org b/particles/element.org new file mode 100644 index 0000000..9852b67 --- /dev/null +++ b/particles/element.org @@ -0,0 +1,328 @@ +#+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 + +* Element + :PROPERTIES: + :header-args: :noweb yes :comments both + :END: + + Chemical elements. + +** Type + + #+NAME: types + #+begin_src ocaml :tangle (eval mli) +type t = + |X + |H |He + |Li|Be |B |C |N |O |F |Ne + |Na|Mg |Al|Si|P |S |Cl|Ar + |K |Ca|Sc|Ti|V |Cr|Mn|Fe|Co|Ni|Cu|Zn|Ga|Ge|As|Se|Br|Kr + |Rb|Sr|Y |Zr|Nb|Mo|Tc|Ru|Rh|Pd|Ag|Cd|In|Sn|Sb|Te|I |Xe + |Pt + +exception ElementError of string + +open Common + #+end_src + + #+begin_src ocaml :tangle (eval ml) :exports none +<> + #+end_src + +** Conversion + + #+begin_src ocaml :tangle (eval mli) +val of_string : string -> t +val to_string : t -> string +val to_long_string : t -> string + +val to_int : t -> int +val of_int : int -> t + +val to_charge : t -> Charge.t +val of_charge : Charge.t -> t + #+end_src + + | ~of_string~ | Creates an ~Element.t~ from a chemical symbol or from the full name of the element (case insensitive) | + | ~to_string~ | Gets the chemical symbol of the ~Element.t~ in a string | + | ~to_long_string~ | Gets the full name of the ~Element.t~ in a string | + | ~to_int~ | Convert to the atomic charge, with ~int~ type | + | ~of_int~ | Create from the atomic charge, with ~int~ type | + | ~to_charge~ | Convert to the atomic charge, with ~Charge.t~ type | + | ~of_charge~ | Create from the atomic charge, with ~Charge.t~ type | + + #+begin_example +Element.of_string "Fe" ;; +- : Element.t = Particles.Element.Fe + +Element.of_string "hydrogen" ;; +- : Element.t = Particles.Element.H + +Element.of_string "Kryptonite" ;; +Exception: Particles.Element.ElementError "Element Kryptonite unknown". + +Element.(to_long_string Fe) ;; +- : string = "Iron" + +Element.(to_string Fe);; +- : string = "Fe" + #+end_example + + #+begin_src ocaml :tangle (eval ml) :exports none +let of_string x = + match (String.capitalize_ascii (String.lowercase_ascii x)) with + | "X" | "Dummy" -> X | "H" | "Hydrogen" -> H + | "He" | "Helium" -> He | "Li" | "Lithium" -> Li + | "Be" | "Beryllium" -> Be | "B" | "Boron" -> B + | "C" | "Carbon" -> C | "N" | "Nitrogen" -> N + | "O" | "Oxygen" -> O | "F" | "Fluorine" -> F + | "Ne" | "Neon" -> Ne | "Na" | "Sodium" -> Na + | "Mg" | "Magnesium" -> Mg | "Al" | "Aluminum" -> Al + | "Si" | "Silicon" -> Si | "P" | "Phosphorus" -> P + | "S" | "Sulfur" -> S | "Cl" | "Chlorine" -> Cl + | "Ar" | "Argon" -> Ar | "K" | "Potassium" -> K + | "Ca" | "Calcium" -> Ca | "Sc" | "Scandium" -> Sc + | "Ti" | "Titanium" -> Ti | "V" | "Vanadium" -> V + | "Cr" | "Chromium" -> Cr | "Mn" | "Manganese" -> Mn + | "Fe" | "Iron" -> Fe | "Co" | "Cobalt" -> Co + | "Ni" | "Nickel" -> Ni | "Cu" | "Copper" -> Cu + | "Zn" | "Zinc" -> Zn | "Ga" | "Gallium" -> Ga + | "Ge" | "Germanium" -> Ge | "As" | "Arsenic" -> As + | "Se" | "Selenium" -> Se | "Br" | "Bromine" -> Br + | "Kr" | "Krypton" -> Kr | "Rb" | "Rubidium" -> Rb + | "Sr" | "Strontium" -> Sr | "Y" | "Yttrium" -> Y + | "Zr" | "Zirconium" -> Zr | "Nb" | "Niobium" -> Nb + | "Mo" | "Molybdenum" -> Mo | "Tc" | "Technetium" -> Tc + | "Ru" | "Ruthenium" -> Ru | "Rh" | "Rhodium" -> Rh + | "Pd" | "Palladium" -> Pd | "Ag" | "Silver" -> Ag + | "Cd" | "Cadmium" -> Cd | "In" | "Indium" -> In + | "Sn" | "Tin" -> Sn | "Sb" | "Antimony" -> Sb + | "Te" | "Tellurium" -> Te | "I" | "Iodine" -> I + | "Xe" | "Xenon" -> Xe | "Pt" | "Platinum" -> Pt + | x -> raise (ElementError ("Element "^x^" unknown")) + + +let to_string = function + | X -> "X" | H -> "H" | He -> "He" | Li -> "Li" + | Be -> "Be" | B -> "B" | C -> "C" | N -> "N" + | O -> "O" | F -> "F" | Ne -> "Ne" | Na -> "Na" + | Mg -> "Mg" | Al -> "Al" | Si -> "Si" | P -> "P" + | S -> "S" | Cl -> "Cl" | Ar -> "Ar" | K -> "K" + | Ca -> "Ca" | Sc -> "Sc" | Ti -> "Ti" | V -> "V" + | Cr -> "Cr" | Mn -> "Mn" | Fe -> "Fe" | Co -> "Co" + | Ni -> "Ni" | Cu -> "Cu" | Zn -> "Zn" | Ga -> "Ga" + | Ge -> "Ge" | As -> "As" | Se -> "Se" | Br -> "Br" + | Kr -> "Kr" | Rb -> "Rb" | Sr -> "Sr" | Y -> "Y" + | Zr -> "Zr" | Nb -> "Nb" | Mo -> "Mo" | Tc -> "Tc" + | Ru -> "Ru" | Rh -> "Rh" | Pd -> "Pd" | Ag -> "Ag" + | Cd -> "Cd" | In -> "In" | Sn -> "Sn" | Sb -> "Sb" + | Te -> "Te" | I -> "I" | Xe -> "Xe" | Pt -> "Pt" + +let to_long_string = function + | X -> "Dummy" | H -> "Hydrogen" | He -> "Helium" + | Li -> "Lithium" | Be -> "Beryllium" | B -> "Boron" + | C -> "Carbon" | N -> "Nitrogen" | O -> "Oxygen" + | F -> "Fluorine" | Ne -> "Neon" | Na -> "Sodium" + | Mg -> "Magnesium" | Al -> "Aluminum" | Si -> "Silicon" + | P -> "Phosphorus" | S -> "Sulfur" | Cl -> "Chlorine" + | Ar -> "Argon" | K -> "Potassium" | Ca -> "Calcium" + | Sc -> "Scandium" | Ti -> "Titanium" | V -> "Vanadium" + | Cr -> "Chromium" | Mn -> "Manganese" | Fe -> "Iron" + | Co -> "Cobalt" | Ni -> "Nickel" | Cu -> "Copper" + | Zn -> "Zinc" | Ga -> "Gallium" | Ge -> "Germanium" + | As -> "Arsenic" | Se -> "Selenium" | Br -> "Bromine" + | Kr -> "Krypton" | Rb -> "Rubidium" | Sr -> "Strontium" + | Y -> "Yttrium" | Zr -> "Zirconium" | Nb -> "Niobium" + | Mo -> "Molybdenum" | Tc -> "Technetium" | Ru -> "Ruthenium" + | Rh -> "Rhodium" | Pd -> "Palladium" | Ag -> "Silver" + | Cd -> "Cadmium" | In -> "Indium" | Sn -> "Tin" + | Sb -> "Antimony" | Te -> "Tellurium" | I -> "Iodine" + | Xe -> "Xenon" | Pt -> "Platinum" + + +let to_int = function + | X -> 0 | H -> 1 | He -> 2 | Li -> 3 + | Be -> 4 | B -> 5 | C -> 6 | N -> 7 + | O -> 8 | F -> 9 | Ne -> 10 | Na -> 11 + | Mg -> 12 | Al -> 13 | Si -> 14 | P -> 15 + | S -> 16 | Cl -> 17 | Ar -> 18 | K -> 19 + | Ca -> 20 | Sc -> 21 | Ti -> 22 | V -> 23 + | Cr -> 24 | Mn -> 25 | Fe -> 26 | Co -> 27 + | Ni -> 28 | Cu -> 29 | Zn -> 30 | Ga -> 31 + | Ge -> 32 | As -> 33 | Se -> 34 | Br -> 35 + | Kr -> 36 | Rb -> 37 | Sr -> 38 | Y -> 39 + | Zr -> 40 | Nb -> 41 | Mo -> 42 | Tc -> 43 + | Ru -> 44 | Rh -> 45 | Pd -> 46 | Ag -> 47 + | Cd -> 48 | In -> 49 | Sn -> 50 | Sb -> 51 + | Te -> 52 | I -> 53 | Xe -> 54 | Pt -> 78 + + +let to_charge c = + to_int c |> Charge.of_int + + +let of_int = function + | 0 -> X | 1 -> H | 2 -> He | 3 -> Li + | 4 -> Be | 5 -> B | 6 -> C | 7 -> N + | 8 -> O | 9 -> F | 10 -> Ne | 11 -> Na + | 12 -> Mg | 13 -> Al | 14 -> Si | 15 -> P + | 16 -> S | 17 -> Cl | 18 -> Ar | 19 -> K + | 20 -> Ca | 21 -> Sc | 22 -> Ti | 23 -> V + | 24 -> Cr | 25 -> Mn | 26 -> Fe | 27 -> Co + | 28 -> Ni | 29 -> Cu | 30 -> Zn | 31 -> Ga + | 32 -> Ge | 33 -> As | 34 -> Se | 35 -> Br + | 36 -> Kr | 37 -> Rb | 38 -> Sr | 39 -> Y + | 40 -> Zr | 41 -> Nb | 42 -> Mo | 43 -> Tc + | 44 -> Ru | 45 -> Rh | 46 -> Pd | 47 -> Ag + | 48 -> Cd | 49 -> In | 50 -> Sn | 51 -> Sb + | 52 -> Te | 53 -> I | 54 -> Xe | 78 -> Pt + | x -> raise (ElementError ("Element of charge "^(string_of_int x)^" unknown")) + + +let of_charge c = + Charge.to_int c |> of_int + + #+end_src + +** Database information + + #+begin_src ocaml :tangle (eval mli) +val covalent_radius : t -> Non_negative_float.t +val vdw_radius : t -> Non_negative_float.t +val mass : t -> Mass.t +val small_core : t -> int +val large_core : t -> int + #+end_src + + | ~covalent_radius~ | Covalent radii of the elements, in atomic units | + | ~vdw_radius~ | Van der Waals radii of the elements, in atomic units | + | ~mass~ | Atomic mass of the elements, in atomic units) | + | ~small_core~ | Number of electrons in the small core model (all except the outermost two shells) | + | ~large_core~ | Number of electrons in the large core model (all except the outermost shell) | + + #+begin_src ocaml :tangle (eval ml) :exports none +let covalent_radius x = + let result = function + | X -> 0. | H -> 0.37 | He -> 0.70 | Li -> 1.23 + | Be -> 0.89 | B -> 0.90 | C -> 0.85 | N -> 0.74 + | O -> 0.74 | F -> 0.72 | Ne -> 0.70 | Na -> 1.00 + | Mg -> 1.36 | Al -> 1.25 | Si -> 1.17 | P -> 1.10 + | S -> 1.10 | Cl -> 0.99 | Ar -> 0.70 | K -> 2.03 + | Ca -> 1.74 | Sc -> 1.44 | Ti -> 1.32 | V -> 1.22 + | Cr -> 0.00 | Mn -> 1.16 | Fe -> 0.00 | Co -> 1.15 + | Ni -> 1.17 | Cu -> 1.25 | Zn -> 1.25 | Ga -> 1.20 + | Ge -> 1.21 | As -> 1.16 | Se -> 0.70 | Br -> 1.24 + | Kr -> 1.91 | Rb -> 2.20 | Sr -> 1.95 | Y -> 1.90 + | Zr -> 1.75 | Nb -> 1.64 | Mo -> 1.54 | Tc -> 1.47 + | Ru -> 1.46 | Rh -> 1.42 | Pd -> 1.39 | Ag -> 1.45 + | Cd -> 1.44 | In -> 1.42 | Sn -> 1.39 | Sb -> 1.39 + | Te -> 1.38 | I -> 1.39 | Xe -> 1.40 | Pt -> 1.30 + in + Constants.a0 *. (result x) + |> Non_negative_float.of_float + + +let vdw_radius x = + let result = function + | X -> 0. | H -> 1.20 | He -> 1.70 | Li -> 1.70 + | Be -> 1.70 | B -> 1.70 | C -> 1.70 | N -> 1.55 + | O -> 1.52 | F -> 1.47 | Ne -> 1.70 | Na -> 1.70 + | Mg -> 1.70 | Al -> 1.94 | Si -> 2.10 | P -> 1.80 + | S -> 1.80 | Cl -> 1.75 | Ar -> 1.70 | K -> 1.70 + | Ca -> 1.70 | Sc -> 1.70 | Ti -> 1.70 | V -> 1.98 + | Cr -> 1.94 | Mn -> 1.93 | Fe -> 1.93 | Co -> 1.92 + | Ni -> 1.70 | Cu -> 1.70 | Zn -> 1.70 | Ga -> 2.02 + | Ge -> 1.70 | As -> 1.96 | Se -> 1.70 | Br -> 2.10 + | Kr -> 1.70 | Rb -> 3.03 | Sr -> 2.49 | Y -> 0. + | Zr -> 0. | Nb -> 0. | Mo -> 0. | Tc -> 0. + | Ru -> 0. | Rh -> 0. | Pd -> 1.63 | Ag -> 1.72 + | Cd -> 1.58 | In -> 1.93 | Sn -> 2.17 | Sb -> 2.06 + | Te -> 2.06 | I -> 1.98 | Xe -> 2.16 | Pt -> 1.75 + in + Constants.a0 *. (result x) + |> Non_negative_float.of_float + + +let mass c = + begin + match c with + | X -> 0. | H -> 1.0079 | He -> 4.00260 | Li -> 6.941 + | Be -> 9.01218 | B -> 10.81 | C -> 12.011 | N -> 14.0067 + | O -> 15.9994 | F -> 18.998403 | Ne -> 20.179 | Na -> 22.98977 + | Mg -> 24.305 | Al -> 26.98154 | Si -> 28.0855 | P -> 30.97376 + | S -> 32.06 | Cl -> 35.453 | Ar -> 39.948 | K -> 39.0983 + | Ca -> 40.08 | Sc -> 44.9559 | Ti -> 47.90 | V -> 50.9415 + | Cr -> 51.996 | Mn -> 54.9380 | Fe -> 55.9332 | Co -> 58.9332 + | Ni -> 58.70 | Cu -> 63.546 | Zn -> 65.38 | Ga -> 69.72 + | Ge -> 72.59 | As -> 74.9216 | Se -> 78.96 | Br -> 79.904 + | Kr -> 83.80 | Rb -> 85.4678 | Sr -> 87.62 | Y -> 88.90584 + | Zr -> 91.224 | Nb -> 92.90637 | Mo -> 95.95 | Tc -> 98. + | Ru -> 101.07 | Rh -> 102.90550 | Pd -> 106.42 | Ag -> 107.8682 + | Cd -> 112.414 | In -> 114.818 | Sn -> 118.710 | Sb -> 121.760 + | Te -> 127.60 | I -> 126.90447 | Xe -> 131.293 | Pt -> 195.084 + end + |> Mass.of_float + + +let noble_gas = + [ He ; Ne ; Ar ; Kr ; Xe ] + + +let large_core t = + let num = to_int t in + let rec loop = function + | gas :: rest -> + if gas < num then + gas + else + loop rest + | [] -> 0 + in + List.rev_map to_int noble_gas + |> loop + + +let small_core t = + let num = to_int t in + let rec loop = function + | large :: small :: rest -> + if large < num then + small + else + loop (small :: rest) + | small :: [] -> + if small < num then + small + else + 0 + | [] -> 0 + in + List.rev_map to_int noble_gas + |> loop + + #+end_src + +** Printers + + #+begin_src ocaml :tangle (eval mli) +val pp : Format.formatter -> t -> unit +val pp_long : Format.formatter -> t -> unit + #+end_src + + #+begin_src ocaml :tangle (eval ml) :exports none +let pp ppf t = + Format.fprintf ppf "@[%s@]" (to_string t) + +let pp_long ppf t = + Format.fprintf ppf "@[%s@]" (to_long_string t) + #+end_src + diff --git a/particles/lib/electrons.ml b/particles/lib/electrons.ml index 3967554..a3d6784 100644 --- a/particles/lib/electrons.ml +++ b/particles/lib/electrons.ml @@ -1,4 +1,4 @@ -(* [[file:../electrons.org::*Type][Type:2]] *) +(* [[file:~/QCaml/particles/electrons.org::*Type][Type:2]] *) type t = { n_alfa : int ; n_beta : int ; @@ -11,7 +11,7 @@ type t = { * | ~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]] *) +(* [[file:~/QCaml/particles/electrons.org::*Creation][Creation:2]] *) open Common let make n_alfa n_beta = @@ -42,7 +42,7 @@ let of_atoms ?multiplicity:(multiplicity=1) ?charge:(charge=0) nuclei = * | ~multiplicity~ | Spin multiplicity: $2S+1$ | *) -(* [[file:../electrons.org::*Access][Access:2]] *) +(* [[file:~/QCaml/particles/electrons.org::*Access][Access:2]] *) let charge e = - (e.n_alfa + e.n_beta) |> Charge.of_int @@ -56,7 +56,7 @@ 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]] *) +(* [[file:~/QCaml/particles/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 57a0a3c..08609a8 100644 --- a/particles/lib/electrons.mli +++ b/particles/lib/electrons.mli @@ -2,14 +2,14 @@ * * #+NAME: types *) -(* [[file:../electrons.org::types][types]] *) +(* [[file:~/QCaml/particles/electrons.org::types][types]] *) type t (* types ends here *) (* Creation *) -(* [[file:../electrons.org::*Creation][Creation:1]] *) +(* [[file:~/QCaml/particles/electrons.org::*Creation][Creation:1]] *) open Common val make : int -> int -> t @@ -25,7 +25,7 @@ val of_atoms : ?multiplicity:int -> ?charge:int -> Nuclei.t -> t (* Access *) -(* [[file:../electrons.org::*Access][Access:1]] *) +(* [[file:~/QCaml/particles/electrons.org::*Access][Access:1]] *) val charge : t -> Charge.t val n_elec : t -> int val n_alfa : t -> int @@ -36,6 +36,6 @@ val multiplicity : t -> int (* Printers *) -(* [[file:../electrons.org::*Printers][Printers:1]] *) +(* [[file:~/QCaml/particles/electrons.org::*Printers][Printers:1]] *) val pp : Format.formatter -> t -> unit (* Printers:1 ends here *) diff --git a/particles/lib/element.ml b/particles/lib/element.ml index 65dbdeb..cfdc2ff 100644 --- a/particles/lib/element.ml +++ b/particles/lib/element.ml @@ -1,16 +1,47 @@ -open Common +(* [[file:../element.org::*Type][Type:2]] *) +type t = + |X + |H |He + |Li|Be |B |C |N |O |F |Ne + |Na|Mg |Al|Si|P |S |Cl|Ar + |K |Ca|Sc|Ti|V |Cr|Mn|Fe|Co|Ni|Cu|Zn|Ga|Ge|As|Se|Br|Kr + |Rb|Sr|Y |Zr|Nb|Mo|Tc|Ru|Rh|Pd|Ag|Cd|In|Sn|Sb|Te|I |Xe + |Pt exception ElementError of string -type t = -|X -|H |He -|Li|Be |B |C |N |O |F |Ne -|Na|Mg |Al|Si|P |S |Cl|Ar -|K |Ca|Sc|Ti|V |Cr|Mn|Fe|Co|Ni|Cu|Zn|Ga|Ge|As|Se|Br|Kr -|Rb|Sr|Y |Zr|Nb|Mo|Tc|Ru|Rh|Pd|Ag|Cd|In|Sn|Sb|Te|I |Xe - |Pt +open Common +(* Type:2 ends here *) + + +(* | ~of_string~ | Creates an ~Element.t~ from a chemical symbol or from the full name of the element (case insensitive) | + * | ~to_string~ | Gets the chemical symbol of the ~Element.t~ in a string | + * | ~to_long_string~ | Gets the full name of the ~Element.t~ in a string | + * | ~to_int~ | Convert to the atomic charge, with ~int~ type | + * | ~of_int~ | Create from the atomic charge, with ~int~ type | + * | ~to_charge~ | Convert to the atomic charge, with ~Charge.t~ type | + * | ~of_charge~ | Create from the atomic charge, with ~Charge.t~ type | + * + * #+begin_example + * Element.of_string "Fe" ;; + * - : Element.t = Particles.Element.Fe + * + * Element.of_string "hydrogen" ;; + * - : Element.t = Particles.Element.H + * + * Element.of_string "Kryptonite" ;; + * Exception: Particles.Element.ElementError "Element Kryptonite unknown". + * + * Element.(to_long_string Fe) ;; + * - : string = "Iron" + * + * Element.(to_string Fe);; + * - : string = "Fe" + * #+end_example *) + + +(* [[file:../element.org::*Conversion][Conversion:2]] *) let of_string x = match (String.capitalize_ascii (String.lowercase_ascii x)) with | "X" | "Dummy" -> X | "H" | "Hydrogen" -> H @@ -45,58 +76,58 @@ let of_string x = let to_string = function -| X -> "X" | H -> "H" | He -> "He" | Li -> "Li" -| Be -> "Be" | B -> "B" | C -> "C" | N -> "N" -| O -> "O" | F -> "F" | Ne -> "Ne" | Na -> "Na" -| Mg -> "Mg" | Al -> "Al" | Si -> "Si" | P -> "P" -| S -> "S" | Cl -> "Cl" | Ar -> "Ar" | K -> "K" -| Ca -> "Ca" | Sc -> "Sc" | Ti -> "Ti" | V -> "V" -| Cr -> "Cr" | Mn -> "Mn" | Fe -> "Fe" | Co -> "Co" -| Ni -> "Ni" | Cu -> "Cu" | Zn -> "Zn" | Ga -> "Ga" -| Ge -> "Ge" | As -> "As" | Se -> "Se" | Br -> "Br" -| Kr -> "Kr" | Rb -> "Rb" | Sr -> "Sr" | Y -> "Y" -| Zr -> "Zr" | Nb -> "Nb" | Mo -> "Mo" | Tc -> "Tc" -| Ru -> "Ru" | Rh -> "Rh" | Pd -> "Pd" | Ag -> "Ag" -| Cd -> "Cd" | In -> "In" | Sn -> "Sn" | Sb -> "Sb" -| Te -> "Te" | I -> "I" | Xe -> "Xe" | Pt -> "Pt" + | X -> "X" | H -> "H" | He -> "He" | Li -> "Li" + | Be -> "Be" | B -> "B" | C -> "C" | N -> "N" + | O -> "O" | F -> "F" | Ne -> "Ne" | Na -> "Na" + | Mg -> "Mg" | Al -> "Al" | Si -> "Si" | P -> "P" + | S -> "S" | Cl -> "Cl" | Ar -> "Ar" | K -> "K" + | Ca -> "Ca" | Sc -> "Sc" | Ti -> "Ti" | V -> "V" + | Cr -> "Cr" | Mn -> "Mn" | Fe -> "Fe" | Co -> "Co" + | Ni -> "Ni" | Cu -> "Cu" | Zn -> "Zn" | Ga -> "Ga" + | Ge -> "Ge" | As -> "As" | Se -> "Se" | Br -> "Br" + | Kr -> "Kr" | Rb -> "Rb" | Sr -> "Sr" | Y -> "Y" + | Zr -> "Zr" | Nb -> "Nb" | Mo -> "Mo" | Tc -> "Tc" + | Ru -> "Ru" | Rh -> "Rh" | Pd -> "Pd" | Ag -> "Ag" + | Cd -> "Cd" | In -> "In" | Sn -> "Sn" | Sb -> "Sb" + | Te -> "Te" | I -> "I" | Xe -> "Xe" | Pt -> "Pt" let to_long_string = function -| X -> "Dummy" | H -> "Hydrogen" | He -> "Helium" -| Li -> "Lithium" | Be -> "Beryllium" | B -> "Boron" -| C -> "Carbon" | N -> "Nitrogen" | O -> "Oxygen" -| F -> "Fluorine" | Ne -> "Neon" | Na -> "Sodium" -| Mg -> "Magnesium" | Al -> "Aluminum" | Si -> "Silicon" -| P -> "Phosphorus" | S -> "Sulfur" | Cl -> "Chlorine" -| Ar -> "Argon" | K -> "Potassium" | Ca -> "Calcium" -| Sc -> "Scandium" | Ti -> "Titanium" | V -> "Vanadium" -| Cr -> "Chromium" | Mn -> "Manganese" | Fe -> "Iron" -| Co -> "Cobalt" | Ni -> "Nickel" | Cu -> "Copper" -| Zn -> "Zinc" | Ga -> "Gallium" | Ge -> "Germanium" -| As -> "Arsenic" | Se -> "Selenium" | Br -> "Bromine" -| Kr -> "Krypton" | Rb -> "Rubidium" | Sr -> "Strontium" -| Y -> "Yttrium" | Zr -> "Zirconium" | Nb -> "Niobium" -| Mo -> "Molybdenum" | Tc -> "Technetium" | Ru -> "Ruthenium" -| Rh -> "Rhodium" | Pd -> "Palladium" | Ag -> "Silver" -| Cd -> "Cadmium" | In -> "Indium" | Sn -> "Tin" -| Sb -> "Antimony" | Te -> "Tellurium" | I -> "Iodine" -| Xe -> "Xenon" | Pt -> "Platinum" + | X -> "Dummy" | H -> "Hydrogen" | He -> "Helium" + | Li -> "Lithium" | Be -> "Beryllium" | B -> "Boron" + | C -> "Carbon" | N -> "Nitrogen" | O -> "Oxygen" + | F -> "Fluorine" | Ne -> "Neon" | Na -> "Sodium" + | Mg -> "Magnesium" | Al -> "Aluminum" | Si -> "Silicon" + | P -> "Phosphorus" | S -> "Sulfur" | Cl -> "Chlorine" + | Ar -> "Argon" | K -> "Potassium" | Ca -> "Calcium" + | Sc -> "Scandium" | Ti -> "Titanium" | V -> "Vanadium" + | Cr -> "Chromium" | Mn -> "Manganese" | Fe -> "Iron" + | Co -> "Cobalt" | Ni -> "Nickel" | Cu -> "Copper" + | Zn -> "Zinc" | Ga -> "Gallium" | Ge -> "Germanium" + | As -> "Arsenic" | Se -> "Selenium" | Br -> "Bromine" + | Kr -> "Krypton" | Rb -> "Rubidium" | Sr -> "Strontium" + | Y -> "Yttrium" | Zr -> "Zirconium" | Nb -> "Niobium" + | Mo -> "Molybdenum" | Tc -> "Technetium" | Ru -> "Ruthenium" + | Rh -> "Rhodium" | Pd -> "Palladium" | Ag -> "Silver" + | Cd -> "Cadmium" | In -> "Indium" | Sn -> "Tin" + | Sb -> "Antimony" | Te -> "Tellurium" | I -> "Iodine" + | Xe -> "Xenon" | Pt -> "Platinum" let to_int = function -| X -> 0 | H -> 1 | He -> 2 | Li -> 3 -| Be -> 4 | B -> 5 | C -> 6 | N -> 7 -| O -> 8 | F -> 9 | Ne -> 10 | Na -> 11 -| Mg -> 12 | Al -> 13 | Si -> 14 | P -> 15 -| S -> 16 | Cl -> 17 | Ar -> 18 | K -> 19 -| Ca -> 20 | Sc -> 21 | Ti -> 22 | V -> 23 -| Cr -> 24 | Mn -> 25 | Fe -> 26 | Co -> 27 -| Ni -> 28 | Cu -> 29 | Zn -> 30 | Ga -> 31 -| Ge -> 32 | As -> 33 | Se -> 34 | Br -> 35 -| Kr -> 36 | Rb -> 37 | Sr -> 38 | Y -> 39 -| Zr -> 40 | Nb -> 41 | Mo -> 42 | Tc -> 43 -| Ru -> 44 | Rh -> 45 | Pd -> 46 | Ag -> 47 -| Cd -> 48 | In -> 49 | Sn -> 50 | Sb -> 51 -| Te -> 52 | I -> 53 | Xe -> 54 | Pt -> 78 + | X -> 0 | H -> 1 | He -> 2 | Li -> 3 + | Be -> 4 | B -> 5 | C -> 6 | N -> 7 + | O -> 8 | F -> 9 | Ne -> 10 | Na -> 11 + | Mg -> 12 | Al -> 13 | Si -> 14 | P -> 15 + | S -> 16 | Cl -> 17 | Ar -> 18 | K -> 19 + | Ca -> 20 | Sc -> 21 | Ti -> 22 | V -> 23 + | Cr -> 24 | Mn -> 25 | Fe -> 26 | Co -> 27 + | Ni -> 28 | Cu -> 29 | Zn -> 30 | Ga -> 31 + | Ge -> 32 | As -> 33 | Se -> 34 | Br -> 35 + | Kr -> 36 | Rb -> 37 | Sr -> 38 | Y -> 39 + | Zr -> 40 | Nb -> 41 | Mo -> 42 | Tc -> 43 + | Ru -> 44 | Rh -> 45 | Pd -> 46 | Ag -> 47 + | Cd -> 48 | In -> 49 | Sn -> 50 | Sb -> 51 + | Te -> 52 | I -> 53 | Xe -> 54 | Pt -> 78 let to_charge c = @@ -104,43 +135,53 @@ let to_charge c = let of_int = function -| 0 -> X | 1 -> H | 2 -> He | 3 -> Li -| 4 -> Be | 5 -> B | 6 -> C | 7 -> N -| 8 -> O | 9 -> F | 10 -> Ne | 11 -> Na -| 12 -> Mg | 13 -> Al | 14 -> Si | 15 -> P -| 16 -> S | 17 -> Cl | 18 -> Ar | 19 -> K -| 20 -> Ca | 21 -> Sc | 22 -> Ti | 23 -> V -| 24 -> Cr | 25 -> Mn | 26 -> Fe | 27 -> Co -| 28 -> Ni | 29 -> Cu | 30 -> Zn | 31 -> Ga -| 32 -> Ge | 33 -> As | 34 -> Se | 35 -> Br -| 36 -> Kr | 37 -> Rb | 38 -> Sr | 39 -> Y -| 40 -> Zr | 41 -> Nb | 42 -> Mo | 43 -> Tc -| 44 -> Ru | 45 -> Rh | 46 -> Pd | 47 -> Ag -| 48 -> Cd | 49 -> In | 50 -> Sn | 51 -> Sb -| 52 -> Te | 53 -> I | 54 -> Xe | 78 -> Pt -| x -> raise (ElementError ("Element of charge "^(string_of_int x)^" unknown")) + | 0 -> X | 1 -> H | 2 -> He | 3 -> Li + | 4 -> Be | 5 -> B | 6 -> C | 7 -> N + | 8 -> O | 9 -> F | 10 -> Ne | 11 -> Na + | 12 -> Mg | 13 -> Al | 14 -> Si | 15 -> P + | 16 -> S | 17 -> Cl | 18 -> Ar | 19 -> K + | 20 -> Ca | 21 -> Sc | 22 -> Ti | 23 -> V + | 24 -> Cr | 25 -> Mn | 26 -> Fe | 27 -> Co + | 28 -> Ni | 29 -> Cu | 30 -> Zn | 31 -> Ga + | 32 -> Ge | 33 -> As | 34 -> Se | 35 -> Br + | 36 -> Kr | 37 -> Rb | 38 -> Sr | 39 -> Y + | 40 -> Zr | 41 -> Nb | 42 -> Mo | 43 -> Tc + | 44 -> Ru | 45 -> Rh | 46 -> Pd | 47 -> Ag + | 48 -> Cd | 49 -> In | 50 -> Sn | 51 -> Sb + | 52 -> Te | 53 -> I | 54 -> Xe | 78 -> Pt + | x -> raise (ElementError ("Element of charge "^(string_of_int x)^" unknown")) let of_charge c = - Charge.to_int c |> of_int + Charge.to_int c |> of_int +(* Conversion:2 ends here *) + +(* | ~covalent_radius~ | Covalent radii of the elements, in atomic units | + * | ~vdw_radius~ | Van der Waals radii of the elements, in atomic units | + * | ~mass~ | Atomic mass of the elements, in atomic units) | + * | ~small_core~ | Number of electrons in the small core model (all except the outermost two shells) | + * | ~large_core~ | Number of electrons in the large core model (all except the outermost shell) | *) + + +(* [[file:../element.org::*Database information][Database information:2]] *) let covalent_radius x = let result = function - | X -> 0. | H -> 0.37 | He -> 0.70 | Li -> 1.23 - | Be -> 0.89 | B -> 0.90 | C -> 0.85 | N -> 0.74 - | O -> 0.74 | F -> 0.72 | Ne -> 0.70 | Na -> 1.00 - | Mg -> 1.36 | Al -> 1.25 | Si -> 1.17 | P -> 1.10 - | S -> 1.10 | Cl -> 0.99 | Ar -> 0.70 | K -> 2.03 - | Ca -> 1.74 | Sc -> 1.44 | Ti -> 1.32 | V -> 1.22 - | Cr -> 0.00 | Mn -> 1.16 | Fe -> 0.00 | Co -> 1.15 - | Ni -> 1.17 | Cu -> 1.25 | Zn -> 1.25 | Ga -> 1.20 - | Ge -> 1.21 | As -> 1.16 | Se -> 0.70 | Br -> 1.24 - | Kr -> 1.91 | Rb -> 2.20 | Sr -> 1.95 | Y -> 1.90 - | Zr -> 1.75 | Nb -> 1.64 | Mo -> 1.54 | Tc -> 1.47 - | Ru -> 1.46 | Rh -> 1.42 | Pd -> 1.39 | Ag -> 1.45 - | Cd -> 1.44 | In -> 1.42 | Sn -> 1.39 | Sb -> 1.39 - | Te -> 1.38 | I -> 1.39 | Xe -> 1.40 | Pt -> 1.30 + | X -> 0. | H -> 0.37 | He -> 0.70 | Li -> 1.23 + | Be -> 0.89 | B -> 0.90 | C -> 0.85 | N -> 0.74 + | O -> 0.74 | F -> 0.72 | Ne -> 0.70 | Na -> 1.00 + | Mg -> 1.36 | Al -> 1.25 | Si -> 1.17 | P -> 1.10 + | S -> 1.10 | Cl -> 0.99 | Ar -> 0.70 | K -> 2.03 + | Ca -> 1.74 | Sc -> 1.44 | Ti -> 1.32 | V -> 1.22 + | Cr -> 0.00 | Mn -> 1.16 | Fe -> 0.00 | Co -> 1.15 + | Ni -> 1.17 | Cu -> 1.25 | Zn -> 1.25 | Ga -> 1.20 + | Ge -> 1.21 | As -> 1.16 | Se -> 0.70 | Br -> 1.24 + | Kr -> 1.91 | Rb -> 2.20 | Sr -> 1.95 | Y -> 1.90 + | Zr -> 1.75 | Nb -> 1.64 | Mo -> 1.54 | Tc -> 1.47 + | Ru -> 1.46 | Rh -> 1.42 | Pd -> 1.39 | Ag -> 1.45 + | Cd -> 1.44 | In -> 1.42 | Sn -> 1.39 | Sb -> 1.39 + | Te -> 1.38 | I -> 1.39 | Xe -> 1.40 | Pt -> 1.30 in Constants.a0 *. (result x) |> Non_negative_float.of_float @@ -148,20 +189,20 @@ let covalent_radius x = let vdw_radius x = let result = function - | X -> 0. | H -> 1.20 | He -> 1.70 | Li -> 1.70 - | Be -> 1.70 | B -> 1.70 | C -> 1.70 | N -> 1.55 - | O -> 1.52 | F -> 1.47 | Ne -> 1.70 | Na -> 1.70 - | Mg -> 1.70 | Al -> 1.94 | Si -> 2.10 | P -> 1.80 - | S -> 1.80 | Cl -> 1.75 | Ar -> 1.70 | K -> 1.70 - | Ca -> 1.70 | Sc -> 1.70 | Ti -> 1.70 | V -> 1.98 - | Cr -> 1.94 | Mn -> 1.93 | Fe -> 1.93 | Co -> 1.92 - | Ni -> 1.70 | Cu -> 1.70 | Zn -> 1.70 | Ga -> 2.02 - | Ge -> 1.70 | As -> 1.96 | Se -> 1.70 | Br -> 2.10 - | Kr -> 1.70 | Rb -> 3.03 | Sr -> 2.49 | Y -> 0. - | Zr -> 0. | Nb -> 0. | Mo -> 0. | Tc -> 0. - | Ru -> 0. | Rh -> 0. | Pd -> 1.63 | Ag -> 1.72 - | Cd -> 1.58 | In -> 1.93 | Sn -> 2.17 | Sb -> 2.06 - | Te -> 2.06 | I -> 1.98 | Xe -> 2.16 | Pt -> 1.75 + | X -> 0. | H -> 1.20 | He -> 1.70 | Li -> 1.70 + | Be -> 1.70 | B -> 1.70 | C -> 1.70 | N -> 1.55 + | O -> 1.52 | F -> 1.47 | Ne -> 1.70 | Na -> 1.70 + | Mg -> 1.70 | Al -> 1.94 | Si -> 2.10 | P -> 1.80 + | S -> 1.80 | Cl -> 1.75 | Ar -> 1.70 | K -> 1.70 + | Ca -> 1.70 | Sc -> 1.70 | Ti -> 1.70 | V -> 1.98 + | Cr -> 1.94 | Mn -> 1.93 | Fe -> 1.93 | Co -> 1.92 + | Ni -> 1.70 | Cu -> 1.70 | Zn -> 1.70 | Ga -> 2.02 + | Ge -> 1.70 | As -> 1.96 | Se -> 1.70 | Br -> 2.10 + | Kr -> 1.70 | Rb -> 3.03 | Sr -> 2.49 | Y -> 0. + | Zr -> 0. | Nb -> 0. | Mo -> 0. | Tc -> 0. + | Ru -> 0. | Rh -> 0. | Pd -> 1.63 | Ag -> 1.72 + | Cd -> 1.58 | In -> 1.93 | Sn -> 2.17 | Sb -> 2.06 + | Te -> 2.06 | I -> 1.98 | Xe -> 2.16 | Pt -> 1.75 in Constants.a0 *. (result x) |> Non_negative_float.of_float @@ -188,25 +229,47 @@ let mass c = |> Mass.of_float -let small_core = function - | X -> 0 | H -> 0 | He -> 0 | Li -> 2 - | Be -> 2 | B -> 2 | C -> 2 | N -> 2 - | O -> 2 | F -> 2 | Ne -> 2 | Na -> 10 - | Mg -> 10 | Al -> 10 | Si -> 10 | P -> 10 - | S -> 10 | Cl -> 10 | Ar -> 10 | K -> 10 - | Ca -> 10 | Sc -> 10 | Ti -> 10 | V -> 10 - | Cr -> 10 | Mn -> 10 | Fe -> 10 | Co -> 10 - | Ni -> 10 | Cu -> 10 | Zn -> 10 | Ga -> 10 - | Ge -> 10 | As -> 10 | Se -> 10 | Br -> 10 - | Kr -> 10 | Rb -> 28 | Sr -> 28 | Y -> 28 - | Zr -> 28 | Nb -> 28 | Mo -> 28 | Tc -> 28 - | Ru -> 28 | Rh -> 28 | Pd -> 28 | Ag -> 28 - | Cd -> 28 | In -> 28 | Sn -> 28 | Sb -> 28 - | Te -> 28 | I -> 28 | Xe -> 28 | Pt -> 60 +let noble_gas = + [ He ; Ne ; Ar ; Kr ; Xe ] +let large_core t = + let num = to_int t in + let rec loop = function + | gas :: rest -> + if gas < num then + gas + else + loop rest + | [] -> 0 + in + List.rev_map to_int noble_gas + |> loop + + +let small_core t = + let num = to_int t in + let rec loop = function + | large :: small :: rest -> + if large < num then + small + else + loop (small :: rest) + | small :: [] -> + if small < num then + small + else + 0 + | [] -> 0 + in + List.rev_map to_int noble_gas + |> loop +(* Database information:2 ends here *) + +(* [[file:../element.org::*Printers][Printers:2]] *) let pp ppf t = Format.fprintf ppf "@[%s@]" (to_string t) let pp_long ppf t = Format.fprintf ppf "@[%s@]" (to_long_string t) +(* Printers:2 ends here *) diff --git a/particles/lib/element.mli b/particles/lib/element.mli index 0133206..d916e4f 100644 --- a/particles/lib/element.mli +++ b/particles/lib/element.mli @@ -1,80 +1,52 @@ -(** Chemical elements. *) +(* Type + * + * #+NAME: types *) -open Common +(* [[file:../element.org::types][types]] *) +type t = + |X + |H |He + |Li|Be |B |C |N |O |F |Ne + |Na|Mg |Al|Si|P |S |Cl|Ar + |K |Ca|Sc|Ti|V |Cr|Mn|Fe|Co|Ni|Cu|Zn|Ga|Ge|As|Se|Br|Kr + |Rb|Sr|Y |Zr|Nb|Mo|Tc|Ru|Rh|Pd|Ag|Cd|In|Sn|Sb|Te|I |Xe + |Pt exception ElementError of string -type t = -|X -|H |He -|Li|Be |B |C |N |O |F |Ne -|Na|Mg |Al|Si|P |S |Cl|Ar -|K |Ca|Sc|Ti|V |Cr|Mn|Fe|Co|Ni|Cu|Zn|Ga|Ge|As|Se|Br|Kr -|Rb|Sr|Y |Zr|Nb|Mo|Tc|Ru|Rh|Pd|Ag|Cd|In|Sn|Sb|Te|I |Xe - |Pt +open Common +(* types ends here *) + +(* Conversion *) -val of_string : string -> t -(** Creates an {!Element.t} from a chemical symbol or from the full name of the - element (case insensitive). - @raise ElementError upon failure - -Examples: - -{[ -Element.of_string "Fe" -> Element.Fe -Element.of_string "hydrogen" -> Element.H -Element.of_string "pouet" -> ElementError "Element pouet unknown" -]} - *) - -val to_string : t -> string -(** Gets the chemical symbol of the {!Element.t} in a string. - -Example: - -[Element.(to_string Fe) -> "Fe"] -*) - +(* [[file:../element.org::*Conversion][Conversion:1]] *) +val of_string : string -> t +val to_string : t -> string val to_long_string : t -> string -(** Gets the full name of the {!Element.t} in a string. - -Example: - -[Element.(to_long_string Fe) -> "Iron"] -*) val to_int : t -> int -(** Convert to the atomic charge, with [int] type. *) - val of_int : int -> t -(** Create from the atomic charge, with [int] type. *) val to_charge : t -> Charge.t -(** Convert to the atomic charge, with {!Charge.t} type. *) - val of_charge : Charge.t -> t -(** Create from the atomic charge, with {!Charge.t} type. *) +(* Conversion:1 ends here *) +(* Database information *) + + +(* [[file:../element.org::*Database information][Database information:1]] *) val covalent_radius : t -> Non_negative_float.t -(** Covalent radii of the elements, in atomic units. *) +val vdw_radius : t -> Non_negative_float.t +val mass : t -> Mass.t +val small_core : t -> int +val large_core : t -> int +(* Database information:1 ends here *) -val vdw_radius : t -> Non_negative_float.t -(** Van der Waals radii of the elements, in atomic units. *) - -val mass : t -> Mass.t -(** Atomic mass of the elements, in atomic units. *) - -val small_core : t -> int -(** Number of electrons in the small core model (all except the outermost two shells). *) - -(* -val large_core : t -> int -(** Number of electrons in the large core model (all except the outermost shell). *) -*) +(* Printers *) -(** Pretty printers *) -val pp : Format.formatter -> t -> unit +(* [[file:../element.org::*Printers][Printers:1]] *) +val pp : Format.formatter -> t -> unit val pp_long : Format.formatter -> t -> unit - +(* Printers:1 ends here *) diff --git a/particles/test/electrons.ml b/particles/test/electrons.ml index 1cfe6b9..5ddf3f5 100644 --- a/particles/test/electrons.ml +++ b/particles/test/electrons.ml @@ -1,4 +1,4 @@ -(* [[file:../electrons.org::*Type][Type:3]] *) +(* [[file:~/QCaml/particles/electrons.org::*Type][Type:3]] *) open Common open Particles open Alcotest @@ -16,12 +16,12 @@ H 0.756950272703377558 0. -0.585882234512562827 let e = Electrons.of_atoms nuclei in (* Type:3 ends here *) -(* [[file:../electrons.org::*Creation][Creation:3]] *) +(* [[file:~/QCaml/particles/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]] *) +(* [[file:~/QCaml/particles/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); @@ -38,7 +38,7 @@ check bool "make" true (Electrons.make 6 4 = Electrons.(of_atoms ~multiplicity:3 (* Tests *) -(* [[file:../electrons.org::*Tests][Tests:1]] *) +(* [[file:~/QCaml/particles/electrons.org::*Tests][Tests:1]] *) () let tests = [