Chemical systems and states
ChemistryLab.ChemicalStateChemistryLab.ChemicalSystemChemistryLab.aqueousChemistryLab.componentsChemistryLab.crystalChemistryLab.gasChemistryLab.gasfluidChemistryLab.get_reactionChemistryLab.massChemistryLab.molesChemistryLab.pHChemistryLab.pOHChemistryLab.porosityChemistryLab.pressureChemistryLab.saturationChemistryLab.set_pressure!ChemistryLab.set_quantity!ChemistryLab.set_temperature!ChemistryLab.solutesChemistryLab.solventChemistryLab.temperatureChemistryLab.volume
ChemicalSystem
ChemistryLab.ChemicalSystem — Type
struct ChemicalSystem{T<:AbstractSpecies, R<:AbstractReaction, C, S} <: AbstractVector{T}An immutable, fully typed collection of chemical species and reactions with derived index structures and stoichiometric matrices.
Immutability guarantees that all derived fields (dict_species, dict_reactions, index vectors, CSM, SM) remain consistent with species and reactions throughout the lifetime of the object. To modify the system, use merge to construct a new ChemicalSystem.
Fields
species: ordered list of all species.dict_species: fast O(1) lookup by species symbol.idx_aqueous,idx_crystal,idx_gas: indices by aggregate state.idx_solutes,idx_solvent,idx_components,idx_gasfluid: indices by class.reactions: ordered list of all reactions.dict_reactions: fast O(1) lookup by reaction symbol.CSM: canonical stoichiometric matrix.SM: stoichiometric matrix with respect to primaries.
ChemistryLab.aqueous — Function
aqueous(cs::ChemicalSystem) -> SubArrayReturn a view of all aqueous species.
Examples
julia> cs = ChemicalSystem([
Species("H2O"; aggregate_state=AS_AQUEOUS),
Species("NaCl"; aggregate_state=AS_CRYSTAL),
]);
julia> length(aqueous(cs))
1
julia> aggregate_state(aqueous(cs)[1]) == AS_AQUEOUS
trueChemistryLab.crystal — Function
crystal(cs::ChemicalSystem) -> SubArrayReturn a view of all crystalline species.
Examples
julia> cs = ChemicalSystem([
Species("H2O"; aggregate_state=AS_AQUEOUS),
Species("NaCl"; aggregate_state=AS_CRYSTAL),
]);
julia> aggregate_state(crystal(cs)[1]) == AS_CRYSTAL
trueChemistryLab.gas — Function
gas(cs::ChemicalSystem) -> SubArrayReturn a view of all gas-phase species.
Examples
julia> cs = ChemicalSystem([Species("CO2"; aggregate_state=AS_GAS)]);
julia> aggregate_state(gas(cs)[1]) == AS_GAS
trueChemistryLab.solutes — Function
solutes(cs::ChemicalSystem) -> SubArrayReturn a view of all aqueous solute species.
Examples
julia> cs = ChemicalSystem([Species("Na+"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLUTE)]);
julia> class(solutes(cs)[1]) == SC_AQSOLUTE
trueChemistryLab.solvent — Function
solvent(cs::ChemicalSystem) -> AbstractSpeciesReturn the unique solvent species directly (not a view), since a chemical system contains at most one solvent.
Examples
julia> cs = ChemicalSystem([Species("H2O"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLVENT)]);
julia> class(solvent(cs)) == SC_AQSOLVENT
trueChemistryLab.components — Function
components(s::Species) -> OrderedDict{Symbol,Number}Return the components of a Species (atomic composition with charge).
components(s::CemSpecies) -> OrderedDict{Symbol,Number}Return the components of a CemSpecies (oxide composition with charge).
components(cs::ChemicalSystem) -> SubArrayReturn a view of all component species.
Examples
julia> cs = ChemicalSystem([Species("SiO2"; aggregate_state=AS_CRYSTAL, class=SC_COMPONENT)]);
julia> class(components(cs)[1]) == SC_COMPONENT
trueChemistryLab.gasfluid — Function
gasfluid(cs::ChemicalSystem) -> SubArrayReturn a view of all gas/fluid species.
Examples
julia> cs = ChemicalSystem([Species("CO2"; aggregate_state=AS_GAS, class=SC_GASFLUID)]);
julia> class(gasfluid(cs)[1]) == SC_GASFLUID
trueChemistryLab.get_reaction — Function
get_reaction(cs::ChemicalSystem, sym::AbstractString) -> AbstractReactionReturn the reaction identified by symbol sym. Runs in O(1) via dict_reactions.
Examples
julia> cs = ChemicalSystem(
[Species("H2O"; aggregate_state=AS_AQUEOUS)];
reactions=[Reaction("H2O = H+ + OH-"; symbol="water_diss")],
);
julia> symbol(get_reaction(cs, "water_diss"))
"water_diss"ChemicalState
ChemistryLab.ChemicalState — Type
struct ChemicalState{C, S, Q<:AbstractQuantity}Immutable container holding the thermodynamic state of a ChemicalSystem.
Molar amounts are always stored internally in mol regardless of the input unit. Each species can be provided independently as a molar amount (mol) or as a mass (g, kg, etc.) — the constructor converts each entry individually using the molar mass M stored in the corresponding species.
The struct itself is immutable — fields cannot be reassigned. However, n, T, and P are stored as Vector to allow in-place mutation via set_quantity!, set_temperature!, and set_pressure!.
system is a shared reference: cloning via Base.copy does not duplicate the underlying ChemicalSystem.
Fields
system: reference to the underlyingChemicalSystem.n: molar amounts (mol), one per species — mutable in place.T: temperature (K) — 1-element Vector, mutable in place.P: pressure (Pa) — 1-element Vector, mutable in place.n_phases: moles per phase(liquid, solid, gas, total).m_phases: mass per phase(liquid, solid, gas, total).V_phases: volume per phase(liquid, solid, gas, total).pH: pH of the liquid phase, ornothingif H⁺ is absent.pOH: pOH of the liquid phase, ornothingif OH⁻ is absent.porosity:(V_liquid + V_gas) / V_total, ornothingif volumes unavailable.saturation:V_liquid / (V_liquid + V_gas), ornothingif pore volume is zero.
Examples
julia> cs = ChemicalSystem([
Species("H2O"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLVENT),
Species("Na+"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLUTE),
]);
julia> state = ChemicalState(cs; T=298.15u"K", P=1u"bar");
julia> length(state.n)
2
julia> ustrip(state.T[])
298.15ChemistryLab.temperature — Function
temperature(state::ChemicalState) -> AbstractQuantityReturn the current temperature.
Examples
julia> cs = ChemicalSystem([Species("H2O"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLVENT)]);
julia> state = ChemicalState(cs; T=298.15u"K", P=1u"bar");
julia> ustrip(temperature(state))
298.15ChemistryLab.pressure — Function
pressure(state::ChemicalState) -> AbstractQuantityReturn the current pressure.
Examples
julia> cs = ChemicalSystem([Species("H2O"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLVENT)]);
julia> state = ChemicalState(cs; T=298.15u"K", P=1u"bar");
julia> isapprox(ustrip(pressure(state)), 1e5; rtol=1e-4)
trueChemistryLab.set_temperature! — Function
set_temperature!(state::ChemicalState, T::AbstractQuantity) -> ChemicalStateSet the temperature in place and update all derived quantities.
Examples
julia> cs = ChemicalSystem([Species("H2O"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLVENT)]);
julia> state = ChemicalState(cs; T=298.15u"K", P=1u"bar");
julia> set_temperature!(state, 350.0u"K");
julia> ustrip(temperature(state))
350.0ChemistryLab.set_pressure! — Function
set_pressure!(state::ChemicalState, P::AbstractQuantity) -> ChemicalStateSet the pressure in place and update all derived quantities.
Examples
julia> cs = ChemicalSystem([Species("H2O"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLVENT)]);
julia> state = ChemicalState(cs; T=298.15u"K", P=1u"bar");
julia> set_pressure!(state, 2u"bar");
julia> isapprox(ustrip(pressure(state)), 2e5; rtol=1e-4)
trueChemistryLab.moles — Function
moles(state::ChemicalState) -> NamedTupleReturn moles per phase (liquid, solid, gas, total).
Examples
julia> cs = ChemicalSystem([
Species("H2O"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLVENT),
Species("NaCl"; aggregate_state=AS_CRYSTAL),
]);
julia> state = ChemicalState(cs, [55.5u"mol", 0.05u"mol"]);
julia> ustrip(moles(state).liquid)
55.5moles(state::ChemicalState, s::AbstractSpecies) -> AbstractQuantityReturn the molar amount of species s in mol.
Examples
julia> cs = ChemicalSystem([Species("H2O"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLVENT)]);
julia> state = ChemicalState(cs, [55.5u"mol"]);
julia> ustrip(moles(state, cs[1]))
55.5moles(state::ChemicalState, sym::AbstractString) -> AbstractQuantityReturn the molar amount of the species identified by symbol sym.
Examples
julia> cs = ChemicalSystem([Species("H2O"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLVENT)]);
julia> state = ChemicalState(cs, [55.5u"mol"]);
julia> ustrip(moles(state, "H2O"))
55.5ChemistryLab.set_quantity! — Function
set_quantity!(state::ChemicalState, s::AbstractSpecies, n::AbstractQuantity) -> ChemicalStateSet the molar amount of species s in place and update all derived quantities. If n has mass dimension, it is automatically converted to moles using M.
Examples
julia> cs = ChemicalSystem([Species("H2O"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLVENT)]);
julia> state = ChemicalState(cs, [55.5u"mol"]);
julia> set_quantity!(state, cs[1], 10.0u"mol");
julia> ustrip(moles(state, "H2O"))
10.0set_quantity!(state::ChemicalState, sym::AbstractString, n::AbstractQuantity) -> ChemicalStateSet the molar amount of the species identified by symbol sym in place and update all derived quantities.
Examples
julia> cs = ChemicalSystem([Species("H2O"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLVENT)]);
julia> state = ChemicalState(cs, [55.5u"mol"]);
julia> set_quantity!(state, "H2O", 10.0u"mol");
julia> ustrip(moles(state, "H2O"))
10.0ChemistryLab.mass — Function
mass(state::ChemicalState) -> NamedTupleReturn mass per phase (liquid, solid, gas, total).
Examples
julia> cs = ChemicalSystem([
Species("H2O"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLVENT),
Species("NaCl"; aggregate_state=AS_CRYSTAL),
]);
julia> state = ChemicalState(cs, [55.5u"mol", 0.05u"mol"]);
julia> mass(state).total isa AbstractQuantity
truemass(state::ChemicalState, s::AbstractSpecies) -> AbstractQuantityReturn the mass of species s, computed as n × M.
Examples
julia> cs = ChemicalSystem([Species("H2O"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLVENT)]);
julia> state = ChemicalState(cs, [55.5u"mol"]);
julia> ustrip(uconvert(us"g", mass(state, cs[1]))) ≈ 55.5 * 18.015
truemass(state::ChemicalState, sym::AbstractString) -> AbstractQuantityReturn the mass of the species identified by symbol sym.
Examples
julia> cs = ChemicalSystem([Species("H2O"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLVENT)]);
julia> state = ChemicalState(cs, [55.5u"mol"]);
julia> ustrip(uconvert(us"g", mass(state, "H2O"))) ≈ 55.5 * 18.015
trueChemistryLab.volume — Function
volume(state::ChemicalState) -> NamedTupleReturn volume per phase (liquid, solid, gas, total).
Examples
julia> cs = ChemicalSystem([
Species("H2O"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLVENT),
Species("NaCl"; aggregate_state=AS_CRYSTAL),
]);
julia> state = ChemicalState(cs, [55.5u"mol", 0.05u"mol"]);
julia> volume(state).total isa AbstractQuantity
truevolume(state::ChemicalState, s::AbstractSpecies) -> Union{AbstractQuantity, Nothing}Return the volume contribution of species s as n × V⁰(T,P). Returns nothing if V⁰ is not available for s.
Examples
julia> cs = ChemicalSystem([Species("H2O"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLVENT)]);
julia> state = ChemicalState(cs, [55.5u"mol"]);
julia> volume(state, cs[1]) isa Union{AbstractQuantity, Nothing}
truevolume(state::ChemicalState, sym::AbstractString) -> Union{AbstractQuantity, Nothing}Return the volume contribution of the species identified by symbol sym. Returns nothing if V⁰ is not available.
Examples
julia> cs = ChemicalSystem([Species("H2O"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLVENT)]);
julia> state = ChemicalState(cs, [55.5u"mol"]);
julia> volume(state, "H2O") isa Union{AbstractQuantity, Nothing}
trueChemistryLab.pH — Function
pH(state::ChemicalState) -> Union{Float64, Nothing}Return the pH of the liquid phase, or nothing if H⁺ is absent.
Examples
julia> cs = ChemicalSystem([
Species("H2O"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLVENT),
Species("H+"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLUTE),
]);
julia> state = ChemicalState(cs, [55.5u"mol", 1e-7u"mol"]);
julia> pH(state) isa Union{Float64, Nothing}
trueChemistryLab.pOH — Function
pOH(state::ChemicalState) -> Union{Float64, Nothing}Return the pOH of the liquid phase, or nothing if OH⁻ is absent.
Examples
julia> cs = ChemicalSystem([
Species("H2O"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLVENT),
Species("OH-"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLUTE),
]);
julia> state = ChemicalState(cs, [55.5u"mol", 1e-7u"mol"]);
julia> pOH(state) isa Union{Float64, Nothing}
trueChemistryLab.porosity — Function
porosity(state::ChemicalState) -> Union{Float64, Nothing}Return the porosity (V_liquid + V_gas) / V_total, or nothing if total volume is zero.
Examples
julia> cs = ChemicalSystem([
Species("H2O"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLVENT),
Species("NaCl"; aggregate_state=AS_CRYSTAL),
]);
julia> state = ChemicalState(cs, [55.5u"mol", 0.05u"mol"]);
julia> porosity(state) isa Union{Float64, Nothing}
trueChemistryLab.saturation — Function
saturation(state::ChemicalState) -> Union{Float64, Nothing}Return the saturation V_liquid / (V_liquid + V_gas), or nothing if pore volume is zero.
Examples
julia> cs = ChemicalSystem([
Species("H2O"; aggregate_state=AS_AQUEOUS, class=SC_AQSOLVENT),
Species("NaCl"; aggregate_state=AS_CRYSTAL),
]);
julia> state = ChemicalState(cs, [55.5u"mol", 0.05u"mol"]);
julia> saturation(state) isa Union{Float64, Nothing}
true