Skip to content

Commit

Permalink
Merge pull request ianmackenzie#44 from lenards/add-molarity-module
Browse files Browse the repository at this point in the history
Add Molarity module
  • Loading branch information
ianmackenzie authored Oct 23, 2019
2 parents a395fa5 + ab85c42 commit 3385082
Show file tree
Hide file tree
Showing 6 changed files with 273 additions and 6 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ Ian Mackenzie <[email protected]>
Matthias Devlamynck <[email protected]>
Katja Mordaunt <[email protected]>
Karim Ulzhabayev <[email protected]>
Andrew Lenards <[email protected]>
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
46 changes: 45 additions & 1 deletion src/Constants.elm
Original file line number Diff line number Diff line change
@@ -1,4 +1,39 @@
module Constants exposing (acre, bushel, cubicFoot, cubicInch, cubicMeter, cubicYard, day, foot, hour, imperialFluidOunce, imperialGallon, imperialPint, imperialQuart, inch, liter, meter, mile, ounce, peck, pound, squareFoot, squareInch, squareMile, squareYard, usDryGallon, usDryPint, usDryQuart, usFluidOunce, usLiquidGallon, usLiquidPint, usLiquidQuart, week, yard)
module Constants exposing
( acre
, bushel
, cubicFoot
, cubicInch
, cubicMeter
, cubicYard
, day
, foot
, hour
, imperialFluidOunce
, imperialGallon
, imperialPint
, imperialQuart
, inch
, liter
, meter
, mile
, mole
, ounce
, peck
, pound
, squareFoot
, squareInch
, squareMile
, squareYard
, usDryGallon
, usDryPint
, usDryQuart
, usFluidOunce
, usLiquidGallon
, usLiquidPint
, usLiquidQuart
, week
, yard
)

{-| All conversion factors sourced from [National Institute of Standards and Technology (NIST)][1]
unless otherwise specified.
Expand Down Expand Up @@ -211,3 +246,12 @@ day =
week : Float
week =
7 * day



---------- UNITS OF SUBSTANCE AMOUNT (in moles) ----------


mole : Float
mole =
1
166 changes: 166 additions & 0 deletions src/Molarity.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
module Molarity exposing
( Molarity, MolesPerCubicMeter
, molesPerCubicMeter, inMolesPerCubicMeter
, molesPerLiter, inMolesPerLiter
, decimolesPerLiter, inDecimolesPerLiter
, centimolesPerLiter, inCentimolesPerLiter
, millimolesPerLiter, inMillimolesPerLiter
, micromolesPerLiter, inMicromolesPerLiter
)

{-| A `Molarity` value represents a concentration of substance in moles per
cubic meter, moles per liter, millimoles per liter etc. It is stored as a number
of moles per cubic meter.
Note that the [NIST Guide to the
SI](https://www.nist.gov/pml/special-publication-811/nist-guide-si-chapter-8)
states that the term "molarity" is considered obsolete, but it appears to still
be in common use and is far less verbose than the alternative NIST suggestion of
"amount-of-substance concentration".
Since the units of `Molarity` are defined to be `Rate Moles CubicMeters` (amount
of substance per unit volume), you can construct a `Molarity` value using
`Quantity.per`:
molarity =
substanceAmount |> Quantity.per volume
You can also do rate-related calculations with `Molarity` values to compute
`SubstanceAmount` or `Volume`:
substanceAmount =
volume |> Quantity.at molarity
volume =
substanceAmount |> Quantity.at_ molarity
@docs Molarity, MolesPerCubicMeter
@docs molesPerCubicMeter, inMolesPerCubicMeter
@docs molesPerLiter, inMolesPerLiter
@docs decimolesPerLiter, inDecimolesPerLiter
@docs centimolesPerLiter, inCentimolesPerLiter
@docs millimolesPerLiter, inMillimolesPerLiter
@docs micromolesPerLiter, inMicromolesPerLiter
-}

import Constants
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



---------- CONSTANTS ----------


{-| One mole per liter, in moles per cubic meter
-}
oneMolePerLiter : Float
oneMolePerLiter =
Constants.mole / Constants.liter


{-| One decimole per liter, in moles per cubic meter
-}
oneDecimolePerLiter : Float
oneDecimolePerLiter =
0.1 * Constants.mole / Constants.liter



---------- FUNCTIONS ----------


{-| 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 moles per liter.
-}
molesPerLiter : Float -> Molarity
molesPerLiter numMolesPerLiter =
molesPerCubicMeter (numMolesPerLiter * oneMolePerLiter)


{-| Convert a molarity to a number of moles per liter.
-}
inMolesPerLiter : Molarity -> Float
inMolesPerLiter molarity =
inMolesPerCubicMeter molarity / oneMolePerLiter


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


{-| Convert a molarity to a number of decimoles per liter.
-}
inDecimolesPerLiter : Molarity -> Float
inDecimolesPerLiter molarity =
inMolesPerCubicMeter molarity / oneDecimolePerLiter


{-| 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
38 changes: 34 additions & 4 deletions src/SubstanceAmount.elm
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
module SubstanceAmount exposing
( SubstanceAmount, Moles
, moles, inMoles, picomoles, inPicomoles, nanomoles, inNanomoles
, micromoles, inMicromoles, millimoles, inMillimoles, kilomoles, inKilomoles
, megamoles, inMegamoles, gigamoles, inGigamoles
, micromoles, inMicromoles, millimoles, inMillimoles
, centimoles, inCentimoles, decimoles, inDecimoles
, kilomoles, inKilomoles, megamoles, inMegamoles, gigamoles, inGigamoles
)

{-| A `SubstanceAmount` value represents a substance amount in [moles][1].
Expand All @@ -15,8 +16,9 @@ module SubstanceAmount exposing
## Conversions
@docs moles, inMoles, picomoles, inPicomoles, nanomoles, inNanomoles
@docs micromoles, inMicromoles, millimoles, inMillimoles, kilomoles, inKilomoles
@docs megamoles, inMegamoles, gigamoles, inGigamoles
@docs micromoles, inMicromoles, millimoles, inMillimoles
@docs centimoles, inCentimoles, decimoles, inDecimoles
@docs kilomoles, inKilomoles, megamoles, inMegamoles, gigamoles, inGigamoles
-}

Expand Down Expand Up @@ -103,6 +105,34 @@ inMillimoles substanceAmount =
inMoles substanceAmount / 1.0e-3


{-| Construct a substance amount from a number of centimoles.
-}
centimoles : Float -> SubstanceAmount
centimoles numCentimoles =
moles (numCentimoles * 1.0e-2)


{-| Convert a substance amount to a number of centimoles.
-}
inCentimoles : SubstanceAmount -> Float
inCentimoles substanceAmount =
inMoles substanceAmount / 1.0e-2


{-| Construct a substance amount from a number of decimoles.
-}
decimoles : Float -> SubstanceAmount
decimoles numDecimoles =
moles (numDecimoles * 1.0e-1)


{-| Convert a substance amount to a number of decimoles.
-}
inDecimoles : SubstanceAmount -> Float
inDecimoles substanceAmount =
inMoles substanceAmount / 1.0e-1


{-| Construct a substance amount from a number of kilomoles.
-}
kilomoles : Float -> SubstanceAmount
Expand Down
27 changes: 26 additions & 1 deletion 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 @@ -229,15 +230,30 @@ substanceAmount =
equalPairs
"SubstanceAmounts"
"ν"
[ ( millimoles 3
[ ( nanomoles 20
, picomoles 20000
)
, ( nanomoles 7000
, micromoles 7
)
, ( millimoles 3
, micromoles 3000
)
, ( nanomoles 1000000
, millimoles 1
)
, ( centimoles 600
, decimoles 60
)
, ( moles 1
, millimoles 1000
)
, ( moles 4
, centimoles 400
)
, ( moles 2
, decimoles 20
)
, ( moles 2000
, kilomoles 2
)
Expand Down Expand Up @@ -525,6 +541,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 Expand Up @@ -561,6 +584,8 @@ conversionsToQuantityAndBack =
, fuzzFloatToQuantityAndBack "nanomoles" SubstanceAmount.nanomoles SubstanceAmount.inNanomoles
, fuzzFloatToQuantityAndBack "micromoles" SubstanceAmount.micromoles SubstanceAmount.inMicromoles
, fuzzFloatToQuantityAndBack "millimoles" SubstanceAmount.millimoles SubstanceAmount.inMillimoles
, fuzzFloatToQuantityAndBack "centimoles" SubstanceAmount.centimoles SubstanceAmount.inCentimoles
, fuzzFloatToQuantityAndBack "decimoles" SubstanceAmount.decimoles SubstanceAmount.inDecimoles
, fuzzFloatToQuantityAndBack "kilomoles" SubstanceAmount.kilomoles SubstanceAmount.inKilomoles
, fuzzFloatToQuantityAndBack "megamoles" SubstanceAmount.megamoles SubstanceAmount.inMegamoles
, fuzzFloatToQuantityAndBack "gigamoles" SubstanceAmount.gigamoles SubstanceAmount.inGigamoles
Expand Down

0 comments on commit 3385082

Please sign in to comment.