Utilities

Module

ChemistryLab.ChemistryLabModule
ChemistryLab

Top-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: 0
source

Miscellaneous helpers

ChemistryLab._ensure_unitMethod
_ensure_unit(unit, x::Real) -> Quantity
_ensure_unit(unit, x) -> Quantity

Ensure a value is a Quantity with the given unit.

  • Plain Real → interpreted as SI, wrapped: x * unit.
  • Quantity → converted to unit via safe_uconvert.
source
ChemistryLab._primalMethod
_primal(x::Real) -> Real

Extract 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.14
source
ChemistryLab.force_uconvertMethod
force_uconvert(qout::UnionAbstractQuantity, q) -> AbstractQuantity

Strip 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.

source
ChemistryLab.print_titleMethod
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
  ───────
source
ChemistryLab.safe_uconvertMethod
safe_uconvert(qout::UnionAbstractQuantity{<:Any, <:AbstractSymbolicDimensions}, q::UnionAbstractQuantity{<:Any, <:Dimensions}) -> UnionAbstractQuantity
safe_uconvert(qout::UnionAbstractQuantity{<:Any, <:AbstractSymbolicDimensions}, q) -> Any

Convert 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 original q when q has no units.

Examples

julia> safe_uconvert(us"m", 5u"cm")
0.05 m

julia> safe_uconvert(us"m", 3.0)
3.0
source
ChemistryLab.safe_uparseMethod
safe_uparse(x::AbstractString) -> AbstractQuantity
safe_uparse(x::AbstractQuantity) -> AbstractQuantity

Parse a unit string into a quantity via uparse, or return an existing quantity unchanged. Acts as an idempotent wrapper.

source
ChemistryLab.safe_ustripMethod
safe_ustrip(unit::UnionAbstractQuantity, q::UnionAbstractQuantity) -> Number
safe_ustrip(unit::UnionAbstractQuantity, q) -> Number

Safely 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.0
source

Sub/superscripts

ChemistryLab.from_subscriptnumberMethod
from_subscriptnumber(s::String) -> Int

Parse a Unicode subscript number string to an integer.

Examples

julia> from_subscriptnumber("₄₂")
42

julia> from_subscriptnumber("₋₃")
-3
source
ChemistryLab.from_superscriptnumberMethod
from_superscriptnumber(s::String) -> Int

Parse a Unicode superscript number string to an integer.

Examples

julia> from_superscriptnumber("⁴²")
42

julia> from_superscriptnumber("⁻²")
-2
source
ChemistryLab.issubscriptMethod
issubscript(c::Char) -> Bool

Return whether c is a numeric subscript.

Examples

julia> issubscript('₂')
true

julia> issubscript('2')
false
source
ChemistryLab.issuperscriptMethod
issuperscript(c::Char) -> Bool

Return whether c is a numeric superscript or ⁺/⁻.

Examples

julia> issuperscript('²')
true

julia> issuperscript('a')
false
source
ChemistryLab.normal_to_subMethod
normal_to_sub(s::AbstractString) -> String

Convert all normal characters in s to numeric subscripts.

Examples

julia> normal_to_sub("H2O")
"H₂O"
source
ChemistryLab.normal_to_superMethod
normal_to_super(s::AbstractString) -> String

Convert all normal characters or +/- in s to numeric superscripts.

Examples

julia> normal_to_super("2+")
"²⁺"
source
ChemistryLab.sub_to_normalMethod
sub_to_normal(s::AbstractString) -> String

Convert all numeric subscripts in s to normal line.

Examples

julia> sub_to_normal("H₂O")
"H2O"
source
ChemistryLab.subscriptnumberMethod
subscriptnumber(i::Integer) -> String

Convert an integer to its Unicode subscript representation.

Examples

julia> subscriptnumber(42)
"₄₂"

julia> subscriptnumber(-3)
"₋₃"
source
ChemistryLab.super_to_normalMethod
super_to_normal(s::AbstractString) -> String

Convert all numeric superscripts or ⁺/⁻ in s to normal line.

Examples

julia> super_to_normal("Ca²⁺")
"Ca2+"
source
ChemistryLab.superscriptnumberMethod
superscriptnumber(i::Integer) -> String

Convert an integer to its Unicode superscript representation.

Examples

julia> superscriptnumber(42)
"⁴²"

julia> superscriptnumber(-2)
"⁻²"
source