optmat.gas.eos#

Number densities of the gases: the ideal gas, the real gas, and its inverse.

A refractivity or an n2 measured at a stated pressure and temperature is reduced either to the ideal-gas density at that state or to the real-gas density, depending on the paper. To compare measurements, the package turns each one into a per-particle quantity, which needs the number density the author actually meant.

Real-gas densities come from CoolProp’s Helmholtz-energy equations of state, imported lazily because CoolProp takes about a second to load. equation_of_state() returns a gas’s equation as an object with an identity: its forward law N = p / (Z k_B T), its inverse (the pressure at a number density and temperature), its speed of sound, its molar mass and its phase domain (OEP 1, section 4.2).

The phase domain. optmat is a library of gases. The forward law and its inverse share one domain: the gas below saturation (T < T_c, p < p_sigma(T)) and the supercritical fluid (T >= T_c, p <= p_max, the equation’s stated upper pressure), within the equation’s temperatures above its triple point. Wherever the fluid has a melting line in CoolProp, the domain also ends just below the melting pressure p_melt(T), which binds above the critical temperature for several gases (nitrogen to 284 K, argon to 254 K; TC-811). A state outside it, a liquid, a solid or a two-phase state among them, raises StateError.

The CODATA convention. The density is formed from Z and CODATA’s k_B rather than from the equation of state’s mass density, because each CoolProp equation carries the gas constant current when it was published: argon’s (Tegeler et al. 1999) and nitrogen’s use R = 8.31451 J/(mol K), which puts their mass densities 5.7e-6 away from the CODATA ideal gas at vanishing pressure. Z is dimensionless and free of that offset.

Module Attributes

EVALUATION_VERSION

The version of this module's evaluation code, in the identity of every model that evaluates through it; raised whenever the code changes its output (OEP 1, section 4.8).

ROUND_TRIP_TOLERANCE

The bound on |N(p(N, T), T) / N - 1| that the inverse guarantees.

SATURATION_MARGIN

How far below the vapour pressure the gas's domain ends, relative.

Functions

air_equation_of_state()

Return CoolProp's pseudo-pure dry air, the density of OEP 1's air models.

compressibility(gas, state)

Return the compressibility factor Z = p / (N k_B T) of the real gas.

equation_of_state(gas)

Return a gas's real-gas equation of state.

ideal_number_density(state)

Return the ideal-gas number density p / (k_B T).

number_density(gas, state, *[, ideal])

Return the number density of a pure gas.

pressure(gas, number_density, temperature, *)

Return the pressure of a pure gas at number densities and temperatures.

Classes

EquationOfState(material, fluid, reference, ...)

The real-gas equation of state of a gas, with its inverse and phase domain.

optmat.gas.eos.EVALUATION_VERSION: Final = 1#

The version of this module’s evaluation code, in the identity of every model that evaluates through it; raised whenever the code changes its output (OEP 1, section 4.8).

class optmat.gas.eos.EquationOfState(material, fluid, reference, backend, gas_constant, critical_temperature, maximum_pressure, temperature_range, *, status='user', status_reason='', modified=(), base='')[source]#

Bases: Identified

The real-gas equation of state of a gas, with its inverse and phase domain.

Attributes:
materialstr

The gas ("Ar") or mixture ("dry air (Lemmon 2000)") of the equation.

fluidstr

CoolProp’s name of the fluid.

referencestr

CoolProp’s reference key of the equation (Tegeler-JPCRD-1999 for argon).

backendstr

The backend and its version, such as CoolProp 8.0.0.

gas_constantfloat

The equation’s own gas constant, J/(mol K).

critical_temperaturefloat
maximum_pressurefloat

The equation’s stated upper pressure, Pa.

temperature_rangetuple of float

The equation’s temperatures, K.

statusstr

validated.

EVALUATES_THROUGH: ClassVar[tuple[str, ...]] = ('optmat.gas.eos',)#
EVALUATION_VERSION: ClassVar[int] = 1#
IDENTITY_KIND: ClassVar[str] = 'equation_of_state'#
backend: str#
compressibility(state)[source]#

Return the compressibility factor Z = p / (N k_B T).

Parameters:
stateState

Pressure and temperature, in the phase domain.

Returns:
float

Dimensionless; 1 for an ideal gas.

critical_temperature: float#
fluid: str#
gas_constant: float#
material: str#
maximum_pressure: float#
property molar_mass: float#

The molar mass the backend’s equation uses, kg/mol.

It is the mass of a mole in the backend’s mass-based quantities, its mass density and speed_of_sound(), and equals the gas’s molar_mass. The number densities do not use it (the CODATA convention). It is resolved from the backend, which fluid and backend fix, so it is not a field and is not in the identity. For air_equation_of_state() it is CoolProp’s pseudo-pure air, 0.02896546 kg/mol, not the 28.9586 g/mol Lemmon et al. (2000) print, the mean of their composition (TC-832).

Returns:
float

The molar mass, kg/mol.

Examples

>>> equation_of_state("Ar").molar_mass
0.039948
>>> air_equation_of_state().molar_mass
0.02896546
number_density(state)[source]#

Return the real-gas number density p / (Z k_B T), the forward law.

Parameters:
stateState

Pressure and temperature, in the phase domain.

Returns:
float

The number density, m^-3.

Examples

>>> from optmat.conditions import ONE_ATM_0C
>>> f"{equation_of_state('He').number_density(ONE_ATM_0C):.6e}"
'2.685349e+25'
phase_domain(temperature)[source]#

Return the pressures of the gas’s domain at a temperature.

Parameters:
temperaturefloat

K, within temperature_range, above its lower end (the triple point).

Returns:
tuple of float

(0, p_sigma(T) (1 - SATURATION_MARGIN)) below the critical temperature, its upper end excluded, and (0, p_max) at or above it, Pa; where CoolProp’s melting pressure, less 1e-5 of it, is lower, the upper end is that instead (nitrogen up to 284 K, argon up to 254 K; TC-811).

Raises:
StateError

Outside the equation’s temperatures, or at the triple point.

Examples

>>> low, high = equation_of_state("CO2").phase_domain(280.0)
>>> f"{high / 1e5:.2f} bar"
'41.61 bar'
>>> nitrogen = equation_of_state("N2")
>>> bool(nitrogen.phase_domain(280.0)[1] < nitrogen.maximum_pressure)
True
pressure(number_density, temperature)[source]#

Return the pressure at number densities and temperatures, the inverse law.

It solves p = N k_B T Z(p, T) on the phase domain, where N(p) rises strictly, so the root is unique, to ROUND_TRIP_TOLERANCE in N(p(N, T), T) / N (OEP 1, section 4.2). It keeps the CODATA convention: its N is number_density()’s, not the backend’s mass density.

Parameters:
number_densityarray_like or float

Number density, m^-3, > 0 (the vacuum limit is refused).

temperaturearray_like or float

K; broadcast against number_density.

Returns:
numpy.ndarray

Pa, the broadcast shape.

Raises:
StateError

At a non-positive density, a density the gas reaches only condensed, solid or above its equation’s pressure, or a temperature outside its range or at its triple point.

Examples

>>> from optmat.conditions import ONE_ATM_0C
>>> eos = equation_of_state("Ar")
>>> n = eos.number_density(ONE_ATM_0C)
>>> f"{float(eos.pressure(n, 273.15)):.4f}"
'101325.0000'
reference: str#
saturation_pressure(temperature)[source]#

Return the vapour pressure at a temperature below the critical one.

Parameters:
temperaturefloat

Temperature, K.

Returns:
float or None

p_sigma(T), Pa; None at or above the critical temperature.

speed_of_sound(state)[source]#

Return the real gas’s speed of sound.

Parameters:
stateState

Pressure and temperature, in the phase domain.

Returns:
float

The speed of sound, m/s.

temperature_range: tuple[float, float]#
optmat.gas.eos.ROUND_TRIP_TOLERANCE: Final = 1e-12#

The bound on |N(p(N, T), T) / N - 1| that the inverse guarantees.

optmat.gas.eos.SATURATION_MARGIN: Final = 1e-05#

How far below the vapour pressure the gas’s domain ends, relative.

CoolProp’s pressure-temperature solve refuses pressures within 1e-6 of the vapour pressure, so the domain stops just short of it.

optmat.gas.eos.air_equation_of_state()[source]#

Return CoolProp’s pseudo-pure dry air, the density of OEP 1’s air models.

Lemmon et al. (2000) fit dry air as one fluid of the composition N2 0.7812, O2 0.2096, Ar 0.0092 (lemmon_2000, TC-741), with the unlike-pair interactions in it: 0.1 % in density (k = 2) up to 873 K and 70 MPa.

Returns:
EquationOfState

The equation, for the material "dry air (Lemmon 2000)".

Examples

>>> air_equation_of_state().reference
'Lemmon-JPCRD-2000'
optmat.gas.eos.compressibility(gas, state)[source]#

Return the compressibility factor Z = p / (N k_B T) of the real gas.

Parameters:
gasGas or str

The species.

stateState

Pressure and temperature, in the phase domain.

Returns:
float

The dimensionless compressibility factor; 1 for an ideal gas.

Examples

>>> from optmat.conditions import ONE_ATM_0C
>>> f"{compressibility('He', ONE_ATM_0C):.5f}"
'1.00053'
optmat.gas.eos.equation_of_state(gas)[source]#

Return a gas’s real-gas equation of state.

Parameters:
gasGas or str

The species.

Returns:
EquationOfState

CoolProp’s Helmholtz-energy equation of the gas, with its identity.

Raises:
StateError

For a species without an equation of state (ozone).

Examples

>>> equation_of_state("Ar").reference
'Tegeler-JPCRD-1999'
optmat.gas.eos.ideal_number_density(state)[source]#

Return the ideal-gas number density p / (k_B T).

Parameters:
stateState

Pressure and temperature.

Returns:
float

Number density in m^-3.

Examples

>>> from optmat.conditions import ONE_ATM_0C
>>> f"{ideal_number_density(ONE_ATM_0C):.6e}"
'2.686780e+25'
optmat.gas.eos.number_density(gas, state, *, ideal=False)[source]#

Return the number density of a pure gas.

Parameters:
gasGas or str

The species.

stateState

Pressure and temperature.

idealbool, optional

If True, return the ideal-gas density p / (k_B T); otherwise (the default) the real-gas density p / (Z k_B T) of equation_of_state().

Returns:
float

Number density in m^-3.

Raises:
StateError

For a real-gas density of a species without an equation of state (ozone), or at a state outside its phase domain: a condensed or solid state is refused, not returned.

Examples

>>> from optmat.conditions import ONE_ATM_0C
>>> n_real = number_density("Xe", ONE_ATM_0C)
>>> n_ideal = number_density("Xe", ONE_ATM_0C, ideal=True)
>>> bool(n_real > n_ideal)  # xenon is attractive at 0 degrees C: Z < 1
True
optmat.gas.eos.pressure(gas, number_density, temperature, *, ideal=False)[source]#

Return the pressure of a pure gas at number densities and temperatures.

Parameters:
gasGas or str

The species.

number_densityarray_like or float

Number density, m^-3, > 0.

temperaturearray_like or float

Temperature, K.

idealbool, optional

If True, N k_B T; otherwise (the default) the inverse of the real-gas law, EquationOfState.pressure().

Returns:
numpy.ndarray

Pa.

Examples

>>> f"{float(pressure('Ar', 2.5e25, 294.0, ideal=True)):.2f}"
'101477.70'