Species
Species is a composite type (introduced by the keyword struct) and is defined by a human-readable name, a chemical symbol/notation, an underlying Formula object holding composition, charge, and string representations, a physical state aggregate_state, a species class, as well as an extensible map of custom properties (molar mass, thermodynamic data, etc.)
struct Species{T<:Number} <: AbstractSpecies
name::String
symbol::String
formula::Formula{T}
aggregate_state::AggregateState
class::Class
properties::OrderedDict{Symbol,PropertyType}
endaggregate_statedenotes the state of the species (solid, liquid, gas) for which the possible keywords areAS_AQUEOUS,AS_CRYSTAL,AS_GASandAS_UNDEFclassdefines the role played by the species in the solution. The possible keywords areSC_AQSOLVENT,SC_AQSOLUTE,SC_COMPONENT,SC_GASFLUIDandSC_UNDEFpropertiesrefers to the set of properties intrinsic to the species. These properties are detailed below.
Species construction
Species can be created from:
- a
Formula
fH2O = Formula("H2O")
H2O = Species(fH2O)Species{Int64}
name: H2O
symbol: H2O
formula: H2O ◆ H₂O
atoms: H => 2, O => 1
charge: 0
aggregate_state: AS_UNDEF
class: SC_UNDEF
properties: M = 0.0180149999937744 kg mol⁻¹- a string
HSO4⁻ = Species("HSO₄⁻")Species{Int64}
name: HSO₄⁻
symbol: HSO₄⁻
formula: HSO₄⁻ ◆ HSO4-
atoms: H => 1, S => 1, O => 4
charge: -1
aggregate_state: AS_UNDEF
class: SC_UNDEF
properties: M = 0.09706399996645676 kg mol⁻¹- a dictionary
CO2 = Species(Dict(:C => 1, :O => 2))Species{Int64}
name: CO₂
symbol: CO₂
formula: CO2 ◆ CO₂
atoms: O => 2, C => 1
charge: 0
aggregate_state: AS_UNDEF
class: SC_UNDEF
properties: M = 0.04400899998479143 kg mol⁻¹To add a charge when creating species with a dictionary, you must add, after the dictionary, the value of the charge (charge is considered an argument of the composite type).
CO2 = Species(Dict(:Si => 1, :O => 3), -2)Species{Int64}
name: SiO₃-2
symbol: SiO₃-2
formula: SiO3-2 ◆ SiO₃-2
atoms: Si => 1, O => 3
charge: -2
aggregate_state: AS_UNDEF
class: SC_UNDEF
properties: M = 0.0760819999737077 kg mol⁻¹Keyword arguments such as name, symbol, aggregate_state, class can be added during construction.
fH₂O = Formula("H2O")
H₂O = Species(fH₂O; name="Water", symbol="H₂O@", aggregate_state=AS_AQUEOUS, class=SC_AQSOLVENT)Species{Int64}
name: Water
symbol: H₂O@
formula: H2O ◆ H₂O
atoms: H => 2, O => 1
charge: 0
aggregate_state: AS_AQUEOUS
class: SC_AQSOLVENT
properties: M = 0.0180149999937744 kg mol⁻¹And symbol accept unicode characters.
CO₂ = Species(Dict(:C=>1, :O=>2); name="Carbon dioxide", symbol="CO₂⤴", aggregate_state=AS_GAS, class=SC_GASFLUID)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⁻¹Comparison between species (or cemspecies) are done by comparing atoms, aggregatestate and class. In the example below, vapour is not equal to H₂O since *aggregatestate* and class are different despite atoms are identical.
vapour = Species("H2O"; name="Vapour", symbol="H₂O⤴", aggregate_state=AS_GAS, class=SC_GASFLUID)
vapour == H₂OYou will also have noticed that a calculation of the molar mass of the species is systematically carried out.
Species properties
The molar mass is systematically calculated and integrated into the species properties. The heat capacity function is also integrated as a predefined function of the Species structure. This function is expressed as follows:
\[{C_p}^° = a_0 + a_1 T + a_2 T^{−2} + a_3 T^{−0.5}\]
Other species properties are open and left to the discretion of users. We can of course imagine that these properties could contain thermodynamic properties such as the Gibbs energy of formation or even the entropy variation, these properties themselves being temperature dependent. These properties must nevertheless respect one of the following types: Number, AbstractVector{<:Number}, Function, AbstractString.
Imagine, for example, that we wanted to construct the $CO_2$ molecule with some of its thermodynamic properties. The Gibbs energy of formation of this species is equal to $-394.39\; KJ/mol$. This property, intrinsic to the species, can be added simply as follows:
using DynamicQuantities, ModelingToolkit
CO₂.ΔfG⁰ = -394.39u"kJ/mol"-394390.0 m² kg s⁻² mol⁻¹Heat capacity, on the other hand, is introduced in the following way:
coeffs = [:a₀ => 44.22u"J/K/mol", :a₁ => 0.0088u"J/mol/K^2", :a₂ => -861.904e6u"J*K/mol", :a₃ => 0.0u"J/mol/√K"]
CO₂.Cp = ThermoFunction(:Cp, coeffs; ref=[:T=>298.15u"K", :P=>1u"bar"])44.22 + 0.0088T + -8.61904e8 / (T^2) ♢ unit=[m² kg s⁻² K⁻¹ mol⁻¹] ♢ ref=[T=298.15 K, P=100000.0 m⁻¹ kg s⁻²]By default, the call of $C_p$ function return the value of the function for a temperature equal to $T_{ref}$.
CO₂.Cp()Other functions can be added to species. For example, we can add a rate to the CO2 species:
CO₂.rate = ThermoFunction(:((c₁+c₂*t)/(c₃+c₄*√t)), [:c₁ => 1.0, :c₂ => 2.0u"1/s", :c₃ => 3.0, :c₄ => 4.0u"1/√s"])
CO₂.rate(1u"s")0.42857142857142855