From 20737d63951a609dfcead89ab747adfa8810d623 Mon Sep 17 00:00:00 2001 From: Willem Van Onsem Date: Fri, 28 Jul 2023 12:28:39 +0200 Subject: [PATCH] add orbital formatting --- chem-formula.cabal | 1 + src/Chemistry/Element.hs | 21 --------------------- src/Chemistry/Orbit.hs | 31 +++++++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 21 deletions(-) create mode 100644 src/Chemistry/Orbit.hs diff --git a/chem-formula.cabal b/chem-formula.cabal index a2fe1ff..ed7f896 100644 --- a/chem-formula.cabal +++ b/chem-formula.cabal @@ -22,6 +22,7 @@ library , Chemistry.Element , Chemistry.Formula , Chemistry.Isotope + , Chemistry.Orbit , Chemistry.Parser build-depends: base >= 4.7 && < 5 diff --git a/src/Chemistry/Element.hs b/src/Chemistry/Element.hs index 2382c1a..8046301 100644 --- a/src/Chemistry/Element.hs +++ b/src/Chemistry/Element.hs @@ -27,8 +27,6 @@ module Chemistry.Element ( , elementName -- * Possible covalent bonds , covalentBonds - -- * Orbitals - , molecularOrbital, dd -- * Colors , withElementColorS, elementCPK, symbolColoured, symbolColouredS ) where @@ -50,14 +48,6 @@ import Numeric.Units.Dimensional.NonSI (dalton) import Text.Blaze(ToMarkup(toMarkup), preEscapedString) import Test.QuickCheck.Arbitrary(Arbitrary(arbitrary), arbitraryBoundedEnum) -data Orbital = OrbS | OrbP | OrbD | OrbF | OrbG - -maxElectronsPerOrbital :: Int -> Int -maxElectronsPerOrbital n = 4*n + 2 - -orbitalNames :: [Char] -orbitalNames = "spdfgh" - -- | A data type that defines the different chemical elements. data Element = H -- ^ The /hydrogen/ element. @@ -255,17 +245,6 @@ pattern Uus = Ts pattern Uuo :: Element pattern Uuo = Og -molecularOrbital :: Element -> [(Int, Char, Int)] -molecularOrbital = fill 0 0 . atomNumber - where fill _ _ 0 = [] - fill m 0 k = (m+1, 's', d) : fill (m - (m-1) `div` 2) ((m+1) `div` 2) (k-d) - where d = min 2 k - fill m n k = (m+1, "spdfg" !! n, d) : fill (m+1) (n-1) (k-d) - where d = min (maxElectronsPerOrbital n) k - --- electronsPerShell :: Element -> [Int] --- electronsPerShell = map sum . molecularOrbital - -- | Obtain the atomic number of the given 'Element'. atomNumber :: Element -- ^ The element for which we want to calculate the atomic number. -> Int -- ^ The atomic number of the given element. diff --git a/src/Chemistry/Orbit.hs b/src/Chemistry/Orbit.hs new file mode 100644 index 0000000..0be69a1 --- /dev/null +++ b/src/Chemistry/Orbit.hs @@ -0,0 +1,31 @@ +module Chemistry.Orbit where + +import Data.List.NonEmpty(NonEmpty) + +data Orbit = S | P | D | F | G deriving (Enum, Eq, Ord, Read, Show) +newtype OrbitalConfig = OrbitalConfig (NonEmpty (NonEmpty Int)) deriving (Eq, Ord, Read, Show) + +totalElectrons :: OrbitalConfig -> Int +totalElectrons (OrbitalConfig vs) = sum (fmap sum vs) + +toArrowText :: Int -> Int -> String +toArrowText n k = concat (replicate f "\8645\8414" ++ [ "\8593\8414" | h == 1 ] ++ replicate ((maxElectronsForOrbit' n `div` 2) - f - h) " \8414") + where ~(f, h) = k `divMod` 2 + +maxElectronsForOrbit' :: Int -> Int +maxElectronsForOrbit' = (2+) . (4*) + +maxElectronsForOrbit :: Orbit -> Int +maxElectronsForOrbit = maxElectronsForOrbit' . fromEnum + +electronsToOrbitals :: Int -> [(Int, Orbit, Int)] +electronsToOrbitals = fill 0 0 + where fill _ _ 0 = [] + fill m 0 k = (m+1, S, d) : fill (m - (m-1) `div` 2) ((m+1) `div` 2) (k-d) + where d = min 2 k + fill m n k = (m+1, toEnum n, d) : fill (m+1) (n-1) (k-d) + where d = min (maxElectronsForOrbit' n) k + +-- electronsPerShell :: Element -> [Int] +-- electronsPerShell = map sum . molecularOrbital +