Thermodynamical functions
ChemistryLab.thermo_function_libraryChemistryLab.CallableChemistryLab.ThermoFunctionChemistryLab.ThermoFunctionChemistryLab.applyChemistryLab.calculate_molar_massChemistryLab.∂ChemistryLab.∫
ChemistryLab.Callable — Type
CallableAbstract base type for all callable thermodynamic functions.
ChemistryLab.ThermoFunction — Type
ThermoFunction{U,F,R} <: CallableRepresentation of a thermodynamic function with symbolic expression, variables, units, and reference conditions.
Fields
symexpr::Num: Symbolic expression of the thermodynamic functionvars::OrderedDict{Symbol,Num}: Dictionary of variables (symbols to symbolic expressions)unit::U: Unit of the function's outputfunc::F: Compiled function for evaluationref::R: Reference conditions dictionary
ChemistryLab.ThermoFunction — Type
ThermoFunction(expr::Union{Symbol,Expr}, params=Pair[], vars=[:T, :P, :t]; ref=[])Construct a ThermoFunction from an expression, parameters, variables, and reference conditions.
Arguments
expr: Symbol or expression (or key from thermofunctionlibrary)params: Parameter values as Pairsvars: Variable symbols (default: [:T, :P, :t, :x, :y, :z])ref: Reference conditions dictionary (default: ref=[:T => 298.15u"K", :P => 1u"bar", :t => 0u"s"])
It is possible to use or not units when defining parameters and reference values but in case of dimensioned quantities, the user should take care of the homogeneity of the expression consistently with parameters and variables units. However variables inside functions such as log, exp, cos... are assumed to be dimensionless (or better implicitly divided by a unit value in the International System of Units) so that it is possible to write log(T), exp(T), cos(T) while keeping T in Kelvins.
Examples
julia> expr = :(α + β * T + γ * log(T))
:(α + β * T + γ * log(T))
julia> params = [:α => 210.0u"J/K/mol", :β => 0.0u"J/mol/K^2", :γ => -3.07e6u"J/K/mol"]
3-element Vector{Pair{Symbol, Quantity{Float64, Dimensions{FRInt32}}}}:
:α => 210.0 m² kg s⁻² K⁻¹ mol⁻¹
:β => 0.0 m² kg s⁻² K⁻² mol⁻¹
:γ => -3.07e6 m² kg s⁻² K⁻¹ mol⁻¹
julia> vars = [:T]
1-element Vector{Symbol}:
:T
julia> tf = ThermoFunction(expr, params, vars; ref=[:T => 298.15u"K"])
210.0 - 3.07e6log(T) ♢ unit=[m² kg s⁻² K⁻¹ mol⁻¹] ♢ ref=[T=298.15 K]
julia> tf() # default evaluation at reference variable here Tref=298.15K
-1.7491411916797183e7 m² kg s⁻² K⁻¹ mol⁻¹
julia> tf(300.0u"K")
-1.7510402197194535e7 m² kg s⁻² K⁻¹ mol⁻¹
julia> tf(300.0)
-1.7510402197194535e7
julia> tf_nounits = ThermoFunction(expr, [:α => 210.0, :β => 0.0, :γ => -3.07e6], vars; ref=[:T => 298.15])
210.0 - 3.07e6log(T) ♢ unit=[] ♢ ref=[T=298.15]
julia> tf_nounits(300.0u"K")
-1.7510402197194535e7
julia> tf_nounits(300.)
-1.7510402197194535e7ChemistryLab.thermo_function_library — Constant
thermo_function_libraryDictionary of predefined thermodynamic function expressions.
Contents
:Cp: Heat capacity expression:CpoverT: Heat capacity divided by temperature:logKr: Logarithm of equilibrium constant
Examples
julia> thermo_function_library[:Cp]
:(a₀ + a₁ * T + a₂ / T ^ 2 + a₃ / √T + a₄ * T ^ 2 + a₅ * T ^ 3 + a₆ * T ^ 4 + a₇ / T ^ 3 + a₈ / T + a₉ * √T + a₁₀ * log(T))
julia> thermo_function_library[:CpoverT]
:(a₀ / T + a₁ + a₂ / T ^ 3 + a₃ / T ^ (3 / 2) + a₄ * T + a₅ * T ^ 2 + a₆ * T ^ 3 + a₇ / T ^ 4 + a₈ / T ^ 2 + a₉ / √T + (a₁₀ * log(T)) / T)
julia> thermo_function_library[:logKr]
:(A₀ + A₁ * T + A₂ / T + A₃ * log(T) + A₄ / T ^ 2 + A₅ * T ^ 2 + A₆ * √T)ChemistryLab.∂ — Function
∂(tf::ThermoFunction, var=collect(keys(tf.vars))[1])Compute the partial derivative of a thermodynamic function.
Arguments
var: Variable to differentiate with respect to (default: first variable)
Returns
- New ThermoFunction representing the derivative
Examples
julia> Cp = ThermoFunction(:Cp, [:a₀ => 210.0u"J/K/mol", :a₁ => 0.12u"J/mol/K^2", :a₂ => -3.07e6u"J*K/mol", :a₃ => 0.0u"J/mol/√K"]; ref=[:T => 298.15u"K", :P => 1u"bar"])
210.0 + 0.12T + -3.07e6 / (T^2) ♢ unit=[m² kg s⁻² K⁻¹ mol⁻¹] ♢ ref=[T=298.15 K, P=100000.0 m⁻¹ kg s⁻²]
julia> ∂(Cp)
0.12 + 6.14e6 / (T^3) ♢ unit=[m² kg s⁻² K⁻² mol⁻¹] ♢ ref=[T=298.15 K, P=100000.0 m⁻¹ kg s⁻²]
julia> rate = ThermoFunction(:((c₁+c₂*t)/(c₃+c₄*√t)), [:c₁ => 1.0, :c₂ => 2.0u"1/s", :c₃ => 3.0, :c₄ => 4.0u"1/√s"])
(1.0 + 2.0t) / (3.0 + 4.0sqrt(t)) ♢ unit=[] ♢ ref=[t=0.0 s]
julia> ∂(rate)(1u"h")
0.004165467097946903 s⁻¹ChemistryLab.∫ — Function
∫(tf::ThermoFunction, var=collect(keys(tf.vars))[1])Compute the integral of a thermodynamic function.
Arguments
var: Variable to integrate with respect to (default: first variable)
Returns
- New ThermoFunction representing the integral
Examples
julia> Cp = ThermoFunction(:Cp, [:a₀ => 210.0u"J/K/mol", :a₁ => 0.12u"J/mol/K^2", :a₂ => -3.07e6u"J*K/mol", :a₃ => 0.0u"J/mol/√K"]; ref=[:T => 298.15u"K", :P => 1u"bar"])
210.0 + 0.12T + -3.07e6 / (T^2) ♢ unit=[m² kg s⁻² K⁻¹ mol⁻¹] ♢ ref=[T=298.15 K, P=100000.0 m⁻¹ kg s⁻²]
julia> ∫Cp = ∫(Cp)
210.0T + 3.07e6 / T + 0.06(T^2) ♢ unit=[m² kg s⁻² mol⁻¹] ♢ ref=[T=298.15 K, P=100000.0 m⁻¹ kg s⁻²]
julia> ΔfH⁰_Tref = -2.72e6u"J/mol"
-2.72e6 m² kg s⁻² mol⁻¹
julia> ΔfH⁰ = (ΔfH⁰_Tref -∫Cp()) + ∫Cp
-2.798241935804469e6 + 210.0T + 3.07e6 / T + 0.06(T^2) ♢ unit=[m² kg s⁻² mol⁻¹] ♢ ref=[T=298.15 K, P=100000.0 m⁻¹ kg s⁻²]ChemistryLab.calculate_molar_mass — Function
calculate_molar_mass(atoms::AbstractDict{Symbol,T}) where {T<:Number} -> QuantityCalculate the molar mass from an atomic composition dictionary.
Arguments
atoms: dictionary mapping element symbols to stoichiometric coefficients.
Returns
- Molar mass as a Quantity in g/mol units.
Examples
julia> calculate_molar_mass(OrderedDict(:H => 2, :O => 1))
0.0180149999937744 kg mol⁻¹ChemistryLab.apply — Function
apply(func::Function, tf::ThermoFunction, args...; kwargs...)Apply a function to a thermodynamic function's expression.
Arguments
func: Function to applytf: ThermoFunctionargs...: Additional arguments for funckwargs...: Additional keyword arguments
Returns
- New ThermoFunction with transformed expression
Examples
julia> f = ThermoFunction(:(a+b*x), [:a=>3, :b=>2])
3 + 2x ♢ unit=[] ♢ ref=[x=0]
julia> apply(expand∘(x->x^2), f)
9 + 12x + 4(x^2) ♢ unit=[] ♢ ref=[x=0]apply(func::Function, f::Formula, args...; kwargs...) -> FormulaElement-wise apply func to all numeric components of f and to its charge. Quantities are handled, attempting to preserve dimensions when possible.
Examples
julia> result = apply(x -> x*2, Formula("H2O"));
julia> result[:H]
4apply(func::Function, s::S, args...; kwargs...) where {S<:AbstractSpecies} -> SApply a function element-wise to all numeric components and properties of a species.
Arguments
func: function to apply.s: source species.args...: additional arguments for func.kwargs...: keyword arguments (including potential overrides for name, symbol, etc.).
Returns
- New species with transformed values.
Handles Quantity types, attempting to preserve dimensions when possible.
apply(func::Function, r::Reaction{SR,TR,SP,TP}, args...; kwargs...) where {SR<:AbstractSpecies,TR<:Number,SP<:AbstractSpecies,TP<:Number}Apply a function to all species and coefficients in a reaction.
Arguments
func: function to apply to species and coefficientsr: reaction to transformargs...: additional arguments for funckwargs...: additional keyword arguments
Returns
- A new Reaction with transformed species and coefficients