Skip to content

Commit

Permalink
Add Molarity module
Browse files Browse the repository at this point in the history
See ianmackenzie#6.

An SI unit, mole per cubic meter (mol/m3), `Molarity` is an amount of
substance divided by the volume of the mixture. Values stored in number
of mole per cubic meter. All `*PerLiter` definitions are defined in
terms of `decimolesPerLiter`. Why? This was done because a liter equal
to a cubic decimeter, and `mole per cubic meter` is a `Rate`. This may
make the various `*PerLiter` definition appear off by a factor of 10
because the definitions are in terms of decimoles per cubic decimeter
(same as `decimolesPerLiter`).
  • Loading branch information
lenards committed Oct 13, 2019
1 parent 7060ad0 commit 88fcc9f
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 0 deletions.
1 change: 1 addition & 0 deletions elm.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"LuminousFlux",
"LuminousIntensity",
"Mass",
"Molarity",
"Pixels",
"Power",
"Pressure",
Expand Down
110 changes: 110 additions & 0 deletions src/Molarity.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
module Molarity exposing
( Molarity, MolesPerCubicMeter
, molesPerCubicMeter, inMolesPerCubicMeter
, decimolesPerLiter, inDecimolesPerLiter
, centimolesPerLiter, inCentimolesPerLiter
, millimolesPerLiter, inMillimolesPerLiter
, micromolesPerLiter, inMicromolesPerLiter
)

{-| A `Molarity` value represents a concentration in mole per cubic meter, decimoles per liter, etc.
It is stored in number of mole per cubic meter.
An SI unit, mole per cubic meter (mol/m3), `Molarity` is an amount of substance divided by the volume of the mixture.
_Note: A liter is equal to a cubic decimeter._
Section 8.6.5 in Chapter 8 of the [NIST Guide to the SI](https://www.nist.gov/pml/special-publication-811/nist-guide-si-chapter-8) does notes that the term molarity is consider obsolete. The initial decision to use `Molarity` as the module name was due to the verbosity of "amount-of-substance concentration".
@docs Molarity, MolesPerCubicMeter
@docs molesPerCubicMeter, inMolesPerCubicMeter
@docs decimolesPerLiter, inDecimolesPerLiter
@docs centimolesPerLiter, inCentimolesPerLiter
@docs millimolesPerLiter, inMillimolesPerLiter
@docs micromolesPerLiter, inMicromolesPerLiter
-}

import Quantity exposing (Quantity(..), Rate)
import SubstanceAmount exposing (Moles)
import Volume exposing (CubicMeters)


{-| -}
type alias MolesPerCubicMeter =
Rate Moles CubicMeters


{-| -}
type alias Molarity =
Quantity Float MolesPerCubicMeter


{-| Construct a molarity from a number of moles per cubic meter.
-}
molesPerCubicMeter : Float -> Molarity
molesPerCubicMeter numMolesPerCubicMeter =
Quantity numMolesPerCubicMeter


{-| Convert a molarity to a number of moles per cubic meter.
-}
inMolesPerCubicMeter : Molarity -> Float
inMolesPerCubicMeter (Quantity numMolesPerCubicMeter) =
numMolesPerCubicMeter


{-| Construct a molarity from a number of decimoles per liter.
-}
decimolesPerLiter : Float -> Molarity
decimolesPerLiter numDecimolesPerLiter =
molesPerCubicMeter (10 * numDecimolesPerLiter)


{-| Convert a molarity to a number of decimoles per liter.
-}
inDecimolesPerLiter : Molarity -> Float
inDecimolesPerLiter (Quantity numMolesPerCubicMeter) =
numMolesPerCubicMeter / 10


{-| Construct a molarity from a number of centimoles per liter.
-}
centimolesPerLiter : Float -> Molarity
centimolesPerLiter numCentimolesPerLiter =
decimolesPerLiter (10 * numCentimolesPerLiter)


{-| Convert a molarity to a number of centimoles per liter.
-}
inCentimolesPerLiter : Molarity -> Float
inCentimolesPerLiter molar =
inDecimolesPerLiter molar / 10


{-| Construct a molarity from a number of millimoles per liter.
-}
millimolesPerLiter : Float -> Molarity
millimolesPerLiter numMillimolesPerLiter =
decimolesPerLiter (100 * numMillimolesPerLiter)


{-| Convert a molarity to a number of millimoles per liter.
-}
inMillimolesPerLiter : Molarity -> Float
inMillimolesPerLiter molar =
inDecimolesPerLiter molar / 100


{-| Construct a molarity from a number of micromoles per liter.
-}
micromolesPerLiter : Float -> Molarity
micromolesPerLiter numMicromolesPerLiter =
decimolesPerLiter (1000 * numMicromolesPerLiter)


{-| Convert a molarity to a number of micromoles per liter.
-}
inMicromolesPerLiter : Molarity -> Float
inMicromolesPerLiter molar =
inDecimolesPerLiter molar / 1000
8 changes: 8 additions & 0 deletions tests/Tests.elm
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import Luminance
import LuminousFlux
import LuminousIntensity
import Mass exposing (..)
import Molarity exposing (..)
import Pixels exposing (..)
import Power exposing (..)
import Pressure exposing (..)
Expand Down Expand Up @@ -525,6 +526,13 @@ conversionsToQuantityAndBack =
, fuzzFloatToQuantityAndBack "shortTons" Mass.shortTons Mass.inShortTons
, fuzzFloatToQuantityAndBack "longTons" Mass.longTons Mass.inLongTons
]
, Test.describe "Molarity" <|
[ fuzzFloatToQuantityAndBack "molesPerCubicMeter" Molarity.molesPerCubicMeter Molarity.inMolesPerCubicMeter
, fuzzFloatToQuantityAndBack "decimolesPerLiter" Molarity.decimolesPerLiter Molarity.inDecimolesPerLiter
, fuzzFloatToQuantityAndBack "centimolesPerLiter" Molarity.centimolesPerLiter Molarity.inCentimolesPerLiter
, fuzzFloatToQuantityAndBack "millimolesPerLiter" Molarity.millimolesPerLiter Molarity.inMillimolesPerLiter
, fuzzFloatToQuantityAndBack "micromolesPerLiter" Molarity.micromolesPerLiter Molarity.inMicromolesPerLiter
]
, Test.describe "Pixels" <|
[ fuzzFloatToQuantityAndBack "pixels" Pixels.pixels Pixels.inPixels
, fuzzFloatToQuantityAndBack "pixelsPerSecond" Pixels.pixelsPerSecond Pixels.inPixelsPerSecond
Expand Down

0 comments on commit 88fcc9f

Please sign in to comment.