Ideal Gas Library for Engineering Thermodynamics in Julia
The IdealGasLib.jl package is a Ideal Gas Library for Engineering Thermodynamics in Julia
based on the EngThermBase.jl infrastructure.
The ideal gas type, idealGas is PREC-ision, EXAC-tness, and heat-capacity model
parameterized, so that in order to instantiate an ideal gas object, a heat capacity model object
must be instantiated first.
EngThermBase heat capacity model hooks include:
julia> using EngThermBase, TypeTree
julia> print.(TypeTree.tt(Heat));
Heat
├─ BivarHeat
├─ ConstHeat
├─ GenerHeat
└─ UnvarHeatThe heat models are thus classified by the amount of variable parameters, from zero (for the
ConstHeat model), to one (for the UnvarHeat model), to two (for the BivarHeat model), to
any (for the GenerHeat model).
The available IdealGasLib heat capacity model is of an all-temperature, constant specific
heats one suitable for ideal gases, therefore, when the library is loaded, the Heat model tree
becomes:
julia> using IdealGasLib
julia> print.(TypeTree.tt(Heat));
Heat
├─ BivarHeat
├─ ConstHeat
│ └─ nobleGasHeat
├─ GenerHeat
└─ UnvarHeatThus demosntrating that it hooks the nobleGasHeat model under ConstHeat Heat model, which
is a subtype of MODEL:
julia> supertype(Heat)
MODELS{𝗽, 𝘅} where {𝗽, 𝘅}Moreover, the IdealGasLib also hooks under EngThermBase.Substance models:
julia> using EngThermBase, TypeTree
julia> print.(TypeTree.tt(Medium));
Medium
└─ Substance
julia> using IdealGasLib
julia> print.(TypeTree.tt(Medium));
Medium
└─ Substance
└─ idealGasThe ideal noble gas heat model is a constant-specific-heat for all temperatures. There are no explicit bounds in temperature included in this model's implementation.
The model is instantiated with a mandatory (i) molar molecular mass, of type m_amt{𝕡,𝕩,MO} where {𝕡,𝕩}, a mandatory (ii) molar specific heat at constant pressure, of type cpamt{𝕡,𝕩,MO} where {𝕡,𝕩}, and optional [iii] reference temperature, T_amt{𝕡,𝕩} where {𝕡,𝕩}, and [iv]
reference pressure, P_amt{𝕡,𝕩} where {𝕡,𝕩}, and [v] molar specific entropy at the reference
state, s_amt{𝕡,𝕩,MO} where {𝕡,𝕩}.
The following is a nobleGasHeat instantiation for water vapor, based on tabulated values of
M, and cp, in a mass base, in which the value of M is explicitly and manually used prior
to the instantiation, so as to change the specific heat base, from MA to MO:
julia> wMass = m_(18.015, MO)
M₆₄: 18.015 kg/kmol
julia> wSpHt = cp(1.8723, MA) * wMass
c̄p₆₄: 33.729 kJ/K/kmol
julia> wHeat = nobleGasHeat(wMass, wSpHt)
noble-cp(T):
c̄p₆₄: 33.729 kJ/K/kmol
M₆₄: 18.015 kg/kmol
T₆₄: 298.15 K
P₆₄: 101.35 kPa
s̄₆₄: 0.0000 kJ/K/kmolOwing to EngThermBase functionality, the molecular mass of any molecule on Earth can be
accurately calculated from standard values of elemental isotope mass and abundance fractions,
usig the following syntax:
julia> m_(molParse("H2O")) # Water, with default element atomic masses
M₃₂: (18.015 ± 0.00033106) kg/kmol
julia> typeof(ans)
m_amt{Float32, MM, MO}
julia> m_(molParse("C8H18"), EngThermBase.atoM_64) # Octane, with 64-bit element atomic masses
M₆₄: (114.23 ± 0.0065229) kg/kmol
julia> typeof(ans)
m_amt{Float64, MM, MO}
julia> m_amt{Float32,EX}(m_(molParse("C2H5(OH)"))) # Ethanol, converted to 32-bit, EXact base
M₃₂: 46.068 kg/kmol
julia> typeof(ans)
m_amt{Float32, EX, MO}Except for the idealGas objects to deal vith, most if not
all other thermodynamic behavior, i.e., the "caloric" side, meaning energy and entropy
quantities are (almost) implemented based on the heat model, thus:
julia> [ @eval ( $FUN(wHeat, T_(1000)) ) for FUN in (:cp, :cv, :ga, :u_, :h_, :Pr, :vr) ]
7-element Vector{AMOUNTS{Float64, EX}}:
cp₆₄: 1.8723 kJ/K/kg
cv₆₄: 1.4108 kJ/K/kg
γ₆₄: 1.3271 –
u₆₄: 990.15 kJ/kg
h₆₄: 1451.7 kJ/kg
Pr₆₄: 135.54 –
vr₆₄: 20.055 –
julia> [ @eval ( $FUN(wHeat, T_(1000), P_(100)) ) for FUN in (:s_, ) ]
1-element Vector{s_amt{Float64, EX, MA}}:
s₆₄: 2.2720 kJ/K/kg
julia> T1 = T_(1000)
T₆₄: 1000.0 K
julia> P1 = P_(100)
P₆₄: 100.00 kPa
julia> u_(wHeat, T1) - T1 * s_(wHeat, T1, P1)
a₆₄: -1281.8 kJ/kg
julia> ans / T1
j₆₄: 1.2818 kJ/K/kg
julia> h_(wHeat, T1) - T1 * s_(wHeat, T1, P1)
g₆₄: -820.29 kJ/kg
julia> ans / T1
y₆₄: 0.82029 kJ/K/kgThe example above illustrates that, despite Helmholtz, Massieu, Gibbs, and Plank functions not being directly implemented just yet, their values can be obtained by applying their definitions, as shown.
Once underlying heat models are understood, idealGases are simple and easy to instantiate, as
they only require a name and a chemical formula, beyond the heat model. This makes it possible
to have a substance modeled in different ways, as it is common in engineering thermodynamics.
It is possible to pick a heat model from a tiny library, implemented in this package, as follows:
julia> using IdealGasLib
julia> He = idealGas("Helium", "He", HEAT[:He][Float32][MM])
idealGas{Float32, MM, nobleGasHeat{Float32, MM}}("Helium", "He", noble-cp(T):
c̄p₃₂: (20.786 ± 0.000037500) kJ/K/kmol
M₃₂: (4.0026 ± 0.0000020000) kg/kmol
T₃₂: (298.15 ± 0.000000000000056843) K
P₃₂: (101.35 ± 0.000000000000014211) kPa
s̄₃₂: (0.0000 ± 0.0000) kJ/K/kmol)Here, the HEAT variable is a dictionary of noble gas models parameterized by dictionary keys,
so that HEAT[:He][Float32][MM] points to the 32-bit precision, MM (i.e., measurements)
exactness noble gas heat model of constant specific heat for Helium. The output explicitly
states the 32-bit precision, as well as each quantity's uncertainties, after the "±" sign.
Once the ideal gas model is instantiated,
julia> P_(He, T_(300), v_(1, MA))
P₃₂: (623.18 ± 0.0011666) kPa
julia> T_(He, P_(500), v_(1, MA))
T₃₂: (240.70 ± 0.00045059) K
julia> v_(He, T_(300), P_(500))
v₃₂: (1.2464 ± 0.0000023332) m³/kg
julia> v_(He, T_(300), P_(500), MO)
v̄₃₂: (4.9887 ± 0.0000090000) m³/kmol
The functions are quite versatile, accepting arguments in a different order, provided that the
idealGas model is always the first argument, while the (optional) BASE, if required, is
always the last argument, so the following also work:
julia> v_(He, P_(500), T_(300), MO)
v̄₃₂: (4.9887 ± 0.0000090000) m³/kmol
julia> TPstate = TPPair(P_(500), T_(300))
TPPair{Float64, EX}(T₆₄: 300.00 K, P₆₄: 500.00 kPa)
julia> v_(He, TPstate, MO)
v̄₃₂: (4.9887 ± 0.0000090000) m³/kmol
Moreover, functions implemented for the underlying heat model also have idealGas versions:
julia> [ @eval ( $FUN(He, T_(1000)) ) for FUN in (:cp, :cv, :ga, :u_, :h_, :Pr, :vr) ]
7-element Vector{AMOUNTS{Float32, MM}}:
cp₃₂: (5.1932 ± 0.0000097216) kJ/K/kg
cv₃₂: (3.1159 ± 0.0000058330) kJ/K/kg
γ₃₂: (1.6667 ± 0.00000000000022352) –
u₃₂: (2186.9 ± 0.0040939) kJ/kg
h₃₂: (4264.2 ± 0.0079825) kJ/kg
Pr₃₂: (20.602 ± 0.0000000061399) –
vr₃₂: (131.94 ± 0.000011573) –
Prof. C. Naaktgeboren, PhD. Lattes.
Federal University of Technology, Paraná (site), Guarapuava Campus.
NaaktgeborenC <dot!> PhD {at!} gmail [dot!] com
This project is licensed under the MIT license.
How to cite this project:
@Misc{2023-NaaktgeborenC-IdealGasLib,
author = {C. Naaktgeboren},
title = {{IdealGasLib.jl} -- Ideal Gas Library for Engineering Thermodynamics in Julia},
howpublished = {Online},
month = {September},
year = {2023},
journal = {GitHub repository},
publisher = {GitHub},
url = {https://github.com/JEngTherm/IdealGasLib.jl},
note = {release 0.2.1 of 24-03-12},
}