Thermodynamical functions

ChemistryLab.ThermoFunctionType
ThermoFunction{U,F,R} <: Callable

Representation of a thermodynamic function with symbolic expression, variables, units, and reference conditions.

Fields

  • symexpr::Num: Symbolic expression of the thermodynamic function
  • vars::OrderedDict{Symbol,Num}: Dictionary of variables (symbols to symbolic expressions)
  • unit::U: Unit of the function's output
  • func::F: Compiled function for evaluation
  • ref::R: Reference conditions dictionary
source
ChemistryLab.ThermoFunctionType
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 Pairs
  • vars: 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"])
Warning

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.7510402197194535e7
Note

Note that ThermoFunction can be used as a functor i.e. can apply on a dimensioned or dimensionless value, which respectively returns a dimensioned or dimensionless result. The default argument(s) is (are) the reference one(s).

source
ChemistryLab.thermo_function_libraryConstant
thermo_function_library

Dictionary 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)
source
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⁻¹
source
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⁻²]
source
ChemistryLab.calculate_molar_massFunction
calculate_molar_mass(atoms::AbstractDict{Symbol,T}) where {T<:Number} -> Quantity

Calculate 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⁻¹
source
ChemistryLab.applyFunction
apply(func::Function, tf::ThermoFunction, args...; kwargs...)

Apply a function to a thermodynamic function's expression.

Arguments

  • func: Function to apply
  • tf: ThermoFunction
  • args...: Additional arguments for func
  • kwargs...: 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]
source
apply(func::Function, f::Formula, args...; kwargs...) -> Formula

Element-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]
4
source
apply(func::Function, s::S, args...; kwargs...) where {S<:AbstractSpecies} -> S

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

source
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 coefficients
  • r: reaction to transform
  • args...: additional arguments for func
  • kwargs...: additional keyword arguments

Returns

  • A new Reaction with transformed species and coefficients
source