Fluid¶
Working fluid interface and equation of state implementations.
This module defines an interface for computing thermodynamic properties of working fluids enabling manipulations, of flow fields independent of the underlying equations of state. The abstraction cleanly separates thermodynamic relations from the flow solver, allowing easy extension to real gas models or tabulated properties.
Currently, the only implementation of the interface is PerfectFluid for ideal gases with
constant specific heats.
A fluid instance is immutable and only stores intrinsic fluid properties that never change, such as specific heats for a perfect gas, or the fluid species for a real fluid. These must passed into the constructor on initialisation.
Get and set methods¶
The chosen basic state variables are density and internal energy, \((\rho, u)\), because these are the most natural in a conservative computational fluid dynamics solver. An equation of state must provide two types of methods: get_? and set_?_?.
set_x_y(x,y): Take thermodynamic properties \((x, y)\) and return \((\rho, u)\).
get_z(rho, u, out=None): Take \((rho, u)\) and return thermodynamic property \(z\).
All methods support both scalar and array inputs, where the inputs must be broadcastable against each other. The output will have the broadcasted shape. Constructor inputs are cast to single-precision floats, and outputs will remain single-precision if all inputs are single-precision. Supplying an out keyword argument to get_? methods allows the output to be written into a pre-allocated array, following NumPy conventions, which may improve performance by avoiding temporary array allocations.
Datum state¶
Only changes in internal energy, enthalpy, and entropy are physically meaningful, therefore we have the freedom to set the physical state at which these properties are zero to improve numerics and reduce precision errors due to subtracting two large floats. We define a thermodynamic datum \((p_\mathrm{dtm}, T_\mathrm{dtm})\) is where \(u = s = 0\) simultaneously. Enthalpy at the datum is not zero because of the pressure term in \(h = u + p/\rho\).
It is possible to shift the datum state of a fluid instance using the change_datum method, which returns a new instance with the same properties but shifted datum. The current datum is accessible via the P_dtm and T_dtm attributes. So the following code simply returns an identical copy of the original fluid instance:
fluid.change_datum(fluid.P_dtm, fluid.T_dtm)
Reference scales¶
The constructors for fluid instances take optional reference scales for non-dimensionalisation, which default to unity such that all quantities are in SI units. If reference scales are provided, then internally the class uses them to form a consistent system of non-dimensional quantities, and all inputs and outputs are taken as non-dimensional. The advantage of setting reference scales is improved numerical precision when working with non-dimensional quantities all of order unity.
The user specifies:
\(\rho_\mathrm{ref}\,\): density [kg/m3]
\(V_\mathrm{ref}\,\): velocity [m/s]
\(R_\mathrm{ref}\,\): gas constant [J/kg/K]
and the class forms the following derived reference scales:
\(p_\mathrm{ref} = \rho V_\mathrm{ref}^2\,\): dynamic pressure [Pa]
\(u_\mathrm{ref} = V_\mathrm{ref}^2\,\): specific energy [J/kg]
\(T_\mathrm{ref} = V_\mathrm{ref}^2 / R_\mathrm{ref}\,\): temperature [K].
Equations of state are unchanged when all quantities are scaled consistently. For example, taking the ideal gas law \(p = \rho R T\) and dividing through by the reference pressure \(\rho_\mathrm{ref} V_\mathrm{ref}^2\) gives
Transport properties such as viscosity and thermal conductivity are an exception to this scaling, and would require an additional reference length to make fully non-dimensional. So when references are provided, transport properties have dimensions of [m].
We can get a new instance with different reference scales using the PerfectFluid.change_ref() method.
- class ember.fluid.PerfectFluid(cp, gamma, mu, Pr, P_dtm=100000.0, T_dtm=300.0, rho_ref=1.0, V_ref=1.0, Rgas_ref=1.0)[source]¶
Bases:
_FluidPerfect gas with constant specific heats.
- Parameters:
cp (float) – Specific heat at constant pressure [J/kg/K].
gamma (float) – Ratio of specific heats [–].
mu (float) – Dynamic viscosity [kg/m/s].
Pr (float) – Prandtl number [–].
P_dtm (float, optional) – Datum pressure where u = 0 and s = 0 [Pa].
T_dtm (float, optional) – Datum temperature where u = 0 and s = 0 [K].
rho_ref (float, optional) – Reference density for non-dimensionalisation.
V_ref (float, optional) – Reference velocity for non-dimensionalisation.
Rgas_ref (float, optional) – Reference gas constant for non-dimensionalisation.
- set_h_s(h, s)[source]¶
Density and internal energy from specific enthalpy and entropy.
Temperature is recovered from \(h\), then pressure from \(s\) , then \(\rho\) and \(u\) follow from
set_P_T():\[T = \frac{h}{c_p} + \frac{T_\mathrm{dtm}}{\gamma}, \qquad p = p_\mathrm{dtm} \exp\!\left(\frac{c_p\ln(T/T_\mathrm{dtm}) - s}{R}\right)\]- Parameters:
h (array_like) – Specific enthalpy [J/kg].
s (array_like) – Specific entropy [J/kg/K].
- Returns:
rho (ndarray) – Density [kg/m³].
u (ndarray) – Specific internal energy [J/kg].
- set_P_h(P, h)[source]¶
Density and internal energy from pressure and specific enthalpy.
Temperature is recovered from \(h = c_p T - R T_\mathrm{dtm}\):
\[T = \frac{h}{c_p} + \frac{T_\mathrm{dtm}}{\gamma}\]Then \(\rho\) and \(u\) follow from
set_P_T().- Parameters:
P (array_like) – Pressure [Pa].
h (array_like) – Specific enthalpy [J/kg].
- Returns:
rho (ndarray) – Density [kg/m³].
u (ndarray) – Specific internal energy [J/kg].
- set_P_rho(P, rho)[source]¶
Density and internal energy from pressure and density.
Temperature follows from the ideal gas law, giving:
\[u = c_v\!\left(\frac{p}{\rho R} - T_\mathrm{dtm}\right)\]- Parameters:
P (array_like) – Pressure [Pa].
rho (array_like) – Density [kg/m³].
- Returns:
rho (ndarray) – Density [kg/m³] (returned unchanged).
u (ndarray) – Specific internal energy [J/kg].
- set_P_s(P, s)[source]¶
Density and internal energy from pressure and specific entropy.
Inverting the Gibbs relation gives temperature, then \(\rho\) and \(u\) follow from
set_P_T():\[T = T_\mathrm{dtm} \exp\!\left(\frac{s + R\ln(p/p_\mathrm{dtm})}{c_p}\right)\]- Parameters:
P (array_like) – Pressure [Pa].
s (array_like) – Specific entropy [J/kg/K].
- Returns:
rho (ndarray) – Density [kg/m³].
u (ndarray) – Specific internal energy [J/kg].
- set_P_T(P, T)[source]¶
Density and internal energy from pressure and temperature.
From the ideal gas law and the calorific equation of state:
\[\rho = \frac{p}{RT}, \qquad u = c_v(T - T_\mathrm{dtm})\]- Parameters:
P (array_like) – Pressure [Pa].
T (array_like) – Temperature [K].
- Returns:
rho (ndarray) – Density [kg/m³].
u (ndarray) – Specific internal energy [J/kg].
- set_rho_s(rho, s)[source]¶
Density and internal energy from density and specific entropy.
Inverting the entropy relation for a perfect gas at fixed density gives temperature directly:
\[T = T_\mathrm{dtm} \exp\!\left(\frac{s}{c_v} + (\gamma-1)\ln\!\frac{\rho}{\rho_\mathrm{dtm}}\right)\]where \(\rho_\mathrm{dtm} = p_\mathrm{dtm}/(R T_\mathrm{dtm})\), then:
\[u = c_v(T - T_\mathrm{dtm})\]- Parameters:
rho (array_like) – Density [kg/m³].
s (array_like) – Specific entropy [J/kg/K].
- Returns:
rho (ndarray) – Density [kg/m³] (returned unchanged).
u (ndarray) – Specific internal energy [J/kg].
- set_T_rho(T, rho)[source]¶
Density and internal energy from temperature and density.
From the calorific equation of state:
\[u = c_v(T - T_\mathrm{dtm})\]- Parameters:
T (array_like) – Temperature [K].
rho (array_like) – Density [kg/m³].
- Returns:
rho (ndarray) – Density [kg/m³] (returned unchanged).
u (ndarray) – Specific internal energy [J/kg].
- set_T_s(T, s)[source]¶
Density and internal energy from temperature and specific entropy.
Inverting the Gibbs relation gives pressure, then \(\rho\) and \(u\) follow from
set_P_T():\[p = p_\mathrm{dtm} \exp\!\left(\frac{c_p\ln(T/T_\mathrm{dtm}) - s}{R}\right)\]- Parameters:
T (array_like) – Temperature [K].
s (array_like) – Specific entropy [J/kg/K].
- Returns:
rho (ndarray) – Density [kg/m³].
u (ndarray) – Specific internal energy [J/kg].
- get_a(rho, u, out=None)[source]¶
Speed of sound from density and internal energy.
For a perfect gas, \(a^2 = \gamma R T\), combined with the definition of internal energy \(u = c_v (T - T_\mathrm{dtm})\) gives
\[a = \sqrt{\gamma R \left(\frac{u}{c_v} + T_\mathrm{dtm}\right)}\]- Parameters:
rho (array_like) – Density [kg/m³].
u (array_like) – Specific internal energy [J/kg].
out (ndarray, optional) – Pre-allocated output array.
- Returns:
a – Speed of sound [m/s].
- Return type:
ndarray
- get_cp(rho, u, out=None)[source]¶
Specific heat at constant pressure (constant for a perfect gas).
\[c_p = \frac{\gamma R}{\gamma - 1}\]- Parameters:
rho (array_like) – Density [kg/m³].
u (array_like) – Specific internal energy [J/kg].
out (ndarray, optional) – Pre-allocated output array.
- Returns:
cp – Specific heat at constant pressure [J/kg/K].
- Return type:
ndarray
- get_cv(rho, u, out=None)[source]¶
Specific heat at constant volume (constant for a perfect gas).
\[c_v = \frac{R}{\gamma - 1} = \frac{c_p}{\gamma}\]- Parameters:
rho (array_like) – Density [kg/m³].
u (array_like) – Specific internal energy [J/kg].
out (ndarray, optional) – Pre-allocated output array.
- Returns:
cv – Specific heat at constant volume [J/kg/K].
- Return type:
ndarray
- get_dhdP_rho(rho, u, out=None)[source]¶
Derivative of specific enthalpy with respect to pressure at constant density.
From \(h = \gamma u + R T_\mathrm{dtm}\) and \(p = \rho R T\), differentiating at constant \(\rho\):
\[\left.\frac{\partial h}{\partial p}\right|_\rho = \frac{\gamma}{\rho(\gamma-1)}\]- Parameters:
rho (array_like) – Density [kg/m³].
u (array_like) – Specific internal energy [J/kg].
out (ndarray, optional) – Pre-allocated output array.
- Returns:
dhdP_rho – Derivative \((\partial h/\partial p)_\rho\) [m³/kg].
- Return type:
ndarray
- get_dhdrho_P(rho, u, out=None)[source]¶
Derivative of specific enthalpy with respect to density at constant pressure.
From \(h = c_p T\) and the ideal gas law \(T = p / (\rho R)\), differentiating at constant \(p\):
\[\left.\frac{\partial h}{\partial \rho}\right|_p = -\frac{c_p T}{\rho}\]- Parameters:
rho (array_like) – Density [kg/m³].
u (array_like) – Specific internal energy [J/kg].
out (ndarray, optional) – Pre-allocated output array.
- Returns:
dhdrho_P – Derivative \((\partial h/\partial \rho)_p\) [J·m³/kg²].
- Return type:
ndarray
- get_dsdP_rho(rho, u, out=None)[source]¶
Derivative of specific entropy with respect to pressure at constant density.
From the Gibbs relation for a perfect gas, differentiating at constant \(\rho\) (so \(T \propto p\)):
\[\left.\frac{\partial s}{\partial p}\right|_\rho = \frac{c_v}{p}\]- Parameters:
rho (array_like) – Density [kg/m³].
u (array_like) – Specific internal energy [J/kg].
out (ndarray, optional) – Pre-allocated output array.
- Returns:
dsdP_rho – Derivative \((\partial s/\partial p)_\rho\) [J/kg/K/Pa].
- Return type:
ndarray
- get_dsdrho_P(rho, u, out=None)[source]¶
Derivative of specific entropy with respect to density at constant pressure.
From the Gibbs relation for a perfect gas, differentiating at constant \(p\) (so \(T \propto 1/\rho\)):
\[\left.\frac{\partial s}{\partial \rho}\right|_p = -\frac{c_p}{\rho}\]- Parameters:
rho (array_like) – Density [kg/m³].
u (array_like) – Specific internal energy [J/kg].
out (ndarray, optional) – Pre-allocated output array.
- Returns:
dsdrho_P – Derivative \((\partial s/\partial \rho)_p\) [J·m³/kg²/K].
- Return type:
ndarray
- get_dudP_rho(rho, u, out=None)[source]¶
Derivative of specific internal energy with respect to pressure at constant density.
From \(u = c_v(T - T_\mathrm{dtm})\) and \(p = \rho R T\), differentiating at constant \(\rho\):
\[\left.\frac{\partial u}{\partial p}\right|_\rho = \frac{1}{\rho(\gamma-1)}\]- Parameters:
rho (array_like) – Density [kg/m³].
u (array_like) – Specific internal energy [J/kg].
out (ndarray, optional) – Pre-allocated output array.
- Returns:
dudP_rho – Derivative \((\partial u/\partial p)_\rho\) [m³/kg].
- Return type:
ndarray
- get_dudrho_P(rho, u, out=None)[source]¶
Derivative of specific internal energy with respect to density at constant pressure.
From \(u = c_v(T - T_\mathrm{dtm})\) and \(T = p/(\rho R)\), differentiating at constant \(p\):
\[\left.\frac{\partial u}{\partial \rho}\right|_p = -\frac{p}{\rho^2(\gamma-1)}\]- Parameters:
rho (array_like) – Density [kg/m³].
u (array_like) – Specific internal energy [J/kg].
out (ndarray, optional) – Pre-allocated output array.
- Returns:
dudrho_P – Derivative \((\partial u/\partial \rho)_p\) [J·m³/kg²].
- Return type:
ndarray
- get_gamma(rho, u, out=None)[source]¶
Ratio of specific heats (constant for a perfect gas).
\[\gamma = \frac{c_p}{c_v}\]- Parameters:
rho (array_like) – Density [kg/m³].
u (array_like) – Specific internal energy [J/kg].
out (ndarray, optional) – Pre-allocated output array.
- Returns:
gamma – Ratio of specific heats [–].
- Return type:
ndarray
- get_h(rho, u, out=None)[source]¶
Specific enthalpy from density and internal energy.
Using the definitions of enthalpy \(h = u + p/\rho\), internal energy \(u = c_v(T-T_\mathrm{dtm})\), and the ideal gas law \(p = \rho R T\) gives
\[h = \gamma u + R T_\mathrm{dtm}\]Enthalpy carries an offset dependent on the arbitrary datum state where \(u = s = 0\) at \((p_\mathrm{dtm}, T_\mathrm{dtm})\); only changes in \(h\) are physically meaningful, so \(h \neq c_p T\). See Datum state.
- Parameters:
rho (array_like) – Density [kg/m³].
u (array_like) – Specific internal energy [J/kg].
out (ndarray, optional) – Pre-allocated output array.
- Returns:
h – Specific enthalpy [J/kg].
- Return type:
ndarray
- get_mu(rho, u, out=None)[source]¶
Dynamic viscosity (constant for a perfect gas).
If reference scales are set, then this method returns a quasi-dimensional viscosity in units of [m] — see Reference Scales for details.
- Parameters:
rho (array_like) – Density [kg/m³].
u (array_like) – Specific internal energy [J/kg].
out (ndarray, optional) – Pre-allocated output array.
- Returns:
mu – Dynamic viscosity [kg/m/s].
- Return type:
ndarray
- get_P(rho, u, out=None)[source]¶
Pressure from density and internal energy.
From the ideal gas law and the definition of internal energy for a perfect gas, \(u = c_v (T - T_\mathrm{dtm})\)
\[p = \rho R \left(\frac{u}{c_v} + T_\mathrm{dtm}\right)\]- Parameters:
rho (array_like) – Density [kg/m³].
u (array_like) – Specific internal energy [J/kg].
out (ndarray, optional) – Pre-allocated output array.
- Returns:
P – Pressure [Pa].
- Return type:
ndarray
- get_Pr(rho, u, out=None)[source]¶
Prandtl number (constant for a perfect gas).
\[\mathit{Pr} = \frac{\mu c_p}{\kappa}\]- Parameters:
rho (array_like) – Density [kg/m³].
u (array_like) – Specific internal energy [J/kg].
out (ndarray, optional) – Pre-allocated output array.
- Returns:
Pr – Prandtl number [–].
- Return type:
ndarray
- get_Rgas(rho, u, out=None)[source]¶
Specific gas constant (constant for a perfect gas).
\[R = c_p - c_v = \frac{(\gamma - 1)\, c_p}{\gamma}\]- Parameters:
rho (array_like) – Density [kg/m³].
u (array_like) – Specific internal energy [J/kg].
out (ndarray, optional) – Pre-allocated output array.
- Returns:
R – Specific gas constant [J/kg/K].
- Return type:
ndarray
- get_s(rho, u, out=None)[source]¶
Specific entropy from density and internal energy.
Using the Gibbs relation for a perfect gas, with the datum state \((p_\mathrm{dtm}, T_\mathrm{dtm})\) defining zero entropy
\[s = c_p \ln\!\frac{T}{T_\mathrm{dtm}} - R \ln\!\frac{p}{p_\mathrm{dtm}}\]where \(T = u/c_v + T_\mathrm{dtm}\) and \(p = \rho R T\).
Entropy is defined relative to the arbitrary datum state where \(u = s = 0\) at \((p_\mathrm{dtm}, T_\mathrm{dtm})\); only changes in \(s\) are physically meaningful. See Datum state.
- Parameters:
rho (array_like) – Density [kg/m³].
u (array_like) – Specific internal energy [J/kg].
out (ndarray, optional) – Pre-allocated output array.
- Returns:
s – Specific entropy [J/kg/K].
- Return type:
ndarray
- get_T(rho, u, out=None)[source]¶
Temperature from density and internal energy.
Rearranging the definition of internal energy for a perfect gas \(u = c_v (T - T_\mathrm{dtm})\) gives
\[T = \frac{u}{c_v} + T_\mathrm{dtm}\]- Parameters:
rho (array_like) – Density [kg/m³].
u (array_like) – Specific internal energy [J/kg].
out (ndarray, optional) – Pre-allocated output array.
- Returns:
T – Temperature [K].
- Return type:
ndarray
- change_datum(P_dtm, T_dtm)[source]¶
Get a new
PerfectFluidwith shifted datum.The new instance will have zero internal energy and entropy at the specified pressure and temperature.
- Parameters:
- Returns:
fluid_new – New fluid instance with shifted and entropy datum.
- Return type:
- change_ref(rho_ref=None, V_ref=None, Rgas_ref=None)[source]¶
Make a new
PerfectFluidwith different reference scales.Omitted reference scales default to the current instance’s reference scales, so only the scales that need to be changed must be specified.
- Parameters:
- Returns:
fluid_new – New fluid instance with the same properties but different reference scales.
- Return type:
- property P_dtm¶
Datum pressure \(p_\mathrm{dtm}\) where \(u = s = 0\) [Pa].
- property P_ref¶
Reference pressure for nondimensionalisation, \(p_\mathrm{ref}\) [Pa].
See Reference scales; derived from
\[p_\mathrm{ref} = \rho_\mathrm{ref} V_\mathrm{ref}^2\]
- property Rgas_ref¶
Reference gas constant for nondimensionalisation, \(R_\mathrm{ref}\) [J/kg/K].
User-specified; see Reference scales.
- property T_dtm¶
Datum temperature \(T_\mathrm{dtm}\) where \(u = s = 0\) [K].
- property T_ref¶
Reference temperature for nondimensionalisation, \(T_\mathrm{ref}\) [K].
See Reference scales; derived from
\[T_\mathrm{ref} = V_\mathrm{ref}^2 / R_\mathrm{ref}\]
- property V_ref¶
Reference velocity for nondimensionalisation, \(V_\mathrm{ref}\) [m/s].
User-specified; see Reference scales.
- property rhoV_ref¶
Reference mass flux for nondimensionalisation, \((\rho V)_\mathrm{ref}\) [kg/m²/s].
See Reference scales; derived from
\[(\rho V)_\mathrm{ref} = \rho_\mathrm{ref} V_\mathrm{ref}\]
- property rho_ref¶
Reference density for nondimensionalisation, \(\rho_\mathrm{ref}\) [kg/m³].
User-specified; see Reference scales.
- property u_ref¶
Reference specific energy for nondimensionalisation, \(u_\mathrm{ref}\) [J/kg].
See Reference scales; derived from
\[u_\mathrm{ref} = V_\mathrm{ref}^2\]