Utilities
ChemistryLab.ChemistryLabChemistryLab.COL_CHARGEChemistryLab.COL_PARChemistryLab.COL_STOICH_EXTChemistryLab.COL_STOICH_INTChemistryLab.FARADAYChemistryLab.FARADAY_QChemistryLab.R_GASChemistryLab.R_GAS_QChemistryLab.dict_all_normal_to_subChemistryLab.dict_frac_unicodeChemistryLab.dict_normal_to_subChemistryLab.dict_normal_to_superChemistryLab.dict_sub_to_normalChemistryLab.dict_super_to_normalChemistryLab.dict_unicode_fracChemistryLab.RT_over_FChemistryLab._ensure_unitChemistryLab._primalChemistryLab.all_normal_to_subChemistryLab.force_uconvertChemistryLab.from_subscriptnumberChemistryLab.from_superscriptnumberChemistryLab.issubscriptChemistryLab.issuperscriptChemistryLab.normal_to_subChemistryLab.normal_to_superChemistryLab.print_titleChemistryLab.root_typeChemistryLab.safe_uconvertChemistryLab.safe_uparseChemistryLab.safe_ustripChemistryLab.sub_to_normalChemistryLab.subscriptnumberChemistryLab.super_to_normalChemistryLab.superscriptnumber
Module
ChemistryLab.ChemistryLab Module
ChemistryLabTop-level module for parsing, representing and manipulating chemical formulas, species, stoichiometric matrices and ThermoFun / PHREEQC-like data.
Overview
Canonical containers:
AtomGroup,Formula.Species representations:
Species,CemSpecies.Parsers and IO helpers for ThermoFun / PHREEQC data (substances, reactions).
Stoichiometric matrix construction and reaction helpers.
Utilities for units, colored and Unicode terminal output.
Examples
julia> using ChemistryLab
julia> f = Formula("H2O")
Formula{Int64}
formula: H2O ◆ H₂O
composition: H => 2, O => 1
charge: 0
julia> f[:H]
2
julia> H2O = Species(f; name="Vapour", symbol="H₂O", aggregate_state=AS_GAS, class=SC_GASFLUID)
Species{Int64}
name: Vapour
symbol: H₂O
formula: H2O ◆ H₂O
atoms: H => 2, O => 1
charge: 0
aggregate_state: AS_GAS
class: SC_GASFLUID
properties: M = 0.0180149999937744 kg mol⁻¹
julia> CO2 = Species(
Dict(:C=>1, :O=>2);
name="Carbon dioxide",
symbol="CO₂",
aggregate_state=AS_GAS,
class=SC_GASFLUID,
) # definition from Dict
Species{Int64}
name: Carbon dioxide
symbol: CO₂
formula: CO2 ◆ CO₂
atoms: O => 2, C => 1
charge: 0
aggregate_state: AS_GAS
class: SC_GASFLUID
properties: M = 0.04400899998479143 kg mol⁻¹
julia> O2 = Species("O2"; name="Dioxygen", symbol="O₂", aggregate_state=AS_GAS, class=SC_GASFLUID) # definition from String
Species{Int64}
name: Dioxygen
symbol: O₂
formula: O2 ◆ O₂
atoms: O => 2
charge: 0
aggregate_state: AS_GAS
class: SC_GASFLUID
properties: M = 0.03199799998894218 kg mol⁻¹
julia> C3H8 = Species(
"C₃H₈"; name="Propane", symbol="C₃H₈", aggregate_state=AS_GAS, class=SC_GASFLUID
) # definition from Unicode String
Species{Int64}
name: Propane
symbol: C₃H₈
formula: C₃H₈ ◆ C3H8
atoms: C => 3, H => 8
charge: 0
aggregate_state: AS_GAS
class: SC_GASFLUID
properties: M = 0.04409699998476102 kg mol⁻¹
julia> r = Reaction([C3H8, O2, CO2, H2O])
equation: C₃H₈ + 5O₂ = 4H₂O + 3CO₂
reactants: C₃H₈ => 1, O₂ => 5
products: H₂O => 4, CO₂ => 3
charge: 0Physical constants
The gas constant and the Faraday constant, taken from DynamicQuantities rather than written down, each in two forms: the bare SI number for arithmetic and the dimensioned quantity for anything that must carry its unit.
ChemistryLab.FARADAY Constant
FARADAYThe Faraday constant as a plain Float64 in C/mol, derived from FARADAY_Q. Used by the Nernst relation between pe and Eh.
ChemistryLab.FARADAY_Q Constant
FARADAY_QThe Faraday constant with its dimensions, 96485.332… C/mol, from DynamicQuantities.Constants.F (CODATA, exact by the 2019 SI redefinition).
ChemistryLab.R_GAS Constant
R_GASThe molar gas constant as a plain Float64 in J/(mol·K), derived from R_GAS_Q rather than written again.
This is the form the inner loops want: an activity model is evaluated once per species per Newton iteration, on Float64 and on ForwardDiff.Dual, and a dimensional Quantity there costs an allocation each time for a factor whose units are known at the call site anyway.
ChemistryLab.R_GAS_Q Constant
R_GAS_QThe molar gas constant with its dimensions, 8.314462618… J/(mol·K), taken from DynamicQuantities.Constants.R (CODATA).
Use this wherever the surrounding quantities carry units. For the plain number used inside an activity model or a rate law, see R_GAS.
ChemistryLab.RT_over_F Method
RT_over_F(T)RT/F in volts at temperature T in kelvin — the natural scale of an electrochemical potential, and the factor in Nernst's relation. At 25 °C, RT ln(10)/F is the familiar 0.05916 V per unit of pe.
Miscellaneous helpers
ChemistryLab.COL_CHARGE Constant
Terminal color for charge display (cyan bold).
ChemistryLab.COL_PAR Constant
Terminal color for parentheses (magenta bold).
ChemistryLab.COL_STOICH_EXT Constant
Terminal color for external stoichiometric coefficients (yellow bold).
ChemistryLab.COL_STOICH_INT Constant
Terminal color for internal stoichiometric coefficients (red bold).
ChemistryLab._ensure_unit Method
_ensure_unit(unit, x::Real) -> Quantity
_ensure_unit(unit, x) -> QuantityEnsure a value is a Quantity with the given unit.
Plain
Real→ interpreted as SI, wrapped:x * unit.Quantity→ converted tounitviasafe_uconvert.
ChemistryLab._primal Method
_primal(x::Real) -> RealExtract the primal (non-derivative) value of x for use in control-flow decisions.
For plain Real numbers this is a no-op. For forward-mode AD types such as ForwardDiff.Dual (which are subtypes of Real) this returns x itself, but since those types overload comparison operators to compare only the primal value, writing _primal(x) > threshold makes the intent explicit and ensures that branching decisions are always taken on physical values rather than derivatives.
Adding a method _primal(x::YourDualType) = x.value enables support for non-standard AD frameworks that do not overload comparison operators.
Examples
julia> _primal(3.14)
3.14ChemistryLab.force_uconvert Method
force_uconvert(qout::UnionAbstractQuantity, q) -> AbstractQuantityStrip units from q (converting to qout dimensions when possible) and re-attach the unit of qout. Unlike safe_uconvert, this always returns a quantity with the units of qout, even when the input is dimensionless.
ChemistryLab.print_title Method
print_title(title; crayon=:none, indent="", style=:none)Print a formatted title with optional styling and indentation.
Arguments
title: title string to display.crayon: Crayon for colored output (default:none).indent: left indentation string (default"").style: formatting style -:none,:underline, or:box(default:none).
Examples
julia> print_title("Test Title"; style=:none)
Test Title
julia> print_title("Section"; style=:underline, indent=" ")
Section
───────ChemistryLab.root_type Method
root_type(T) -> TypeGet the root type wrapper from a potentially parameterized type.
ChemistryLab.safe_uconvert Method
safe_uconvert(qout::UnionAbstractQuantity{<:Any, <:AbstractSymbolicDimensions}, q::UnionAbstractQuantity{<:Any, <:Dimensions}) -> UnionAbstractQuantity
safe_uconvert(qout::UnionAbstractQuantity{<:Any, <:AbstractSymbolicDimensions}, q) -> AnyConvert q to the unit type represented by qout using uconvert when q is a quantity with compatible dimensions. If q is a plain numeric value, return q unchanged.
Arguments
qout: unitful quantity target (e.g., u"m", u"kg").q: a quantity or a plain numeric value.
Returns
- Converted quantity (of type
qout) or the originalqwhenqhas no units.
Examples
julia> safe_uconvert(us"m", 5u"cm")
0.05 m
julia> safe_uconvert(us"m", 3.0)
3.0ChemistryLab.safe_uparse Method
safe_uparse(x::AbstractString) -> AbstractQuantity
safe_uparse(x::AbstractQuantity) -> AbstractQuantityParse a unit string into a quantity via uparse, or return an existing quantity unchanged. Acts as an idempotent wrapper.
ChemistryLab.safe_ustrip Method
safe_ustrip(unit::UnionAbstractQuantity, q::UnionAbstractQuantity) -> Number
safe_ustrip(unit::UnionAbstractQuantity, q) -> NumberSafely remove units from q, converting to unit when their dimensions match. If q is a plain numeric value (no units) it is returned unchanged.
When the dimensions of unit and q differ (e.g. unit is dimensionless but q carries a physical dimension) the conversion is skipped and q is stripped in its native unit. This prevents a DimensionError in contexts such as ThermoFactory where a dimensionless placeholder unit u"1" may be passed alongside a quantity with physical dimensions.
Examples
julia> safe_ustrip(u"m", 5u"m")
5.0
julia> safe_ustrip(u"cm", 1u"m")
100.0
julia> safe_ustrip(u"m", 3.0)
3.0Sub/superscripts
ChemistryLab.dict_all_normal_to_sub Constant
Extended mapping from normal-line characters (digits, letters, operators) to Unicode subscripts.
ChemistryLab.dict_frac_unicode Constant
Mapping from Rational fractions to their Unicode vulgar fraction strings.
ChemistryLab.dict_normal_to_sub Constant
Mapping from normal-line digits and signs to their Unicode subscript equivalents.
ChemistryLab.dict_normal_to_super Constant
Mapping from normal-line characters to their Unicode superscript equivalents.
ChemistryLab.dict_sub_to_normal Constant
Mapping from Unicode subscript digits to their normal-line equivalents.
ChemistryLab.dict_super_to_normal Constant
Mapping from Unicode superscript characters to their normal-line equivalents.
ChemistryLab.dict_unicode_frac Constant
Mapping from Unicode vulgar fraction characters to Rational values.
ChemistryLab.all_normal_to_sub Method
all_normal_to_sub(s::AbstractString) -> StringConvert all normal characters (including letters and operators) to subscripts.
ChemistryLab.from_subscriptnumber Method
from_subscriptnumber(s::String) -> IntParse a Unicode subscript number string to an integer.
Examples
julia> from_subscriptnumber("₄₂")
42
julia> from_subscriptnumber("₋₃")
-3ChemistryLab.from_superscriptnumber Method
from_superscriptnumber(s::String) -> IntParse a Unicode superscript number string to an integer.
Examples
julia> from_superscriptnumber("⁴²")
42
julia> from_superscriptnumber("⁻²")
-2ChemistryLab.issubscript Method
issubscript(c::Char) -> BoolReturn whether c is a numeric subscript.
Examples
julia> issubscript('₂')
true
julia> issubscript('2')
falseChemistryLab.issuperscript Method
issuperscript(c::Char) -> BoolReturn whether c is a numeric superscript or ⁺/⁻.
Examples
julia> issuperscript('²')
true
julia> issuperscript('a')
falseChemistryLab.normal_to_sub Method
normal_to_sub(s::AbstractString) -> StringConvert all normal characters in s to numeric subscripts.
Examples
julia> normal_to_sub("H2O")
"H₂O"ChemistryLab.normal_to_super Method
normal_to_super(s::AbstractString) -> StringConvert all normal characters or +/- in s to numeric superscripts.
Examples
julia> normal_to_super("2+")
"²⁺"ChemistryLab.sub_to_normal Method
sub_to_normal(s::AbstractString) -> StringConvert all numeric subscripts in s to normal line.
Examples
julia> sub_to_normal("H₂O")
"H2O"ChemistryLab.subscriptnumber Method
subscriptnumber(i::Integer) -> StringConvert an integer to its Unicode subscript representation.
Examples
julia> subscriptnumber(42)
"₄₂"
julia> subscriptnumber(-3)
"₋₃"ChemistryLab.super_to_normal Method
super_to_normal(s::AbstractString) -> StringConvert all numeric superscripts or ⁺/⁻ in s to normal line.
Examples
julia> super_to_normal("Ca²⁺")
"Ca2+"ChemistryLab.superscriptnumber Method
superscriptnumber(i::Integer) -> StringConvert an integer to its Unicode superscript representation.
Examples
julia> superscriptnumber(42)
"⁴²"
julia> superscriptnumber(-2)
"⁻²"