Fluid¶
Working fluid interface and equation of state implementations.
Fluid is the interface for computing thermodynamic properties of a
working fluid, so that flow fields can be manipulated independently of the
underlying equation of state. The abstraction separates thermodynamic relations
from the flow solver and is the type other modules and downstream code accept;
extending to a new real-gas or tabulated model is a matter of subclassing it.
Two implementations are provided: PerfectFluid, for ideal gases with
constant specific heats, and RealFluid, a thermodynamically consistent
real gas built from a fitted entropy surface. Coefficients for the latter are
produced offline by ember.realgas_fit.
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. Storage of the actual flow solution is the responsibility of a Block.
Get and set methods¶
The 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 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})\) 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
change_datum, which returns a new instance with the same properties but
shifted datum. The current datum is accessible via
P_dtm and T_dtm attributes.
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, 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],
rho_ref\(V_\mathrm{ref}\,\): velocity [m/s],
V_ref\(R_\mathrm{ref}\,\): gas constant [J/kg/K],
Rgas_ref
and the class forms the following derived reference scales:
\(p_\mathrm{ref} = \rho_\mathrm{ref} V_\mathrm{ref}^2\,\): dynamic pressure [Pa],
P_ref\(u_\mathrm{ref} = V_\mathrm{ref}^2\,\): specific energy [J/kg],
u_ref\(T_\mathrm{ref} = V_\mathrm{ref}^2 / R_\mathrm{ref}\,\): temperature [K],
T_ref\((\rho V)_\mathrm{ref} = \rho_\mathrm{ref} V_\mathrm{ref}\,\): mass flux [kg/m2/s],
rhoV_ref
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 meters: viscosity is divided by \(\rho_\mathrm{ref} V_\mathrm{ref}\) and conductivity by \(\rho_\mathrm{ref} V_\mathrm{ref} R_\mathrm{ref}\), which are the two scalings that leave the Prandtl number \(\mu c_p / \kappa\) dimensionless. Scaling the transport properties on their own, to sweep Reynolds number at a fixed flow field, is what Fluid.change_visc() is for.
We can get a new instance with different reference scales using the Fluid.change_ref() method.
- class fluid.Fluid(rho_ref=1.0, V_ref=1.0, Rgas_ref=1.0)[source]¶
The equation-of-state interface: density and internal energy to and from other thermodynamic properties.
PerfectFluidandRealFluidimplement it; the rest of the codebase and downstream code accept aFluidand never test which. See the module documentation above for the \((\rho, u)\) convention, the datum state and the reference scales.Every
get_*method takes(rho, u, out=None)— density and internal energy, broadcastable against each other — and returns one array of the broadcast shape, optionally written intoout(the NumPyout=convention). Everyset_x_ymethod takes the two named properties, likewise broadcastable, and returns(rho, u). Outputs are single precision when the inputs are. With non-unity reference scales all quantities in and out are non-dimensional; transport properties are then only quasi-dimensional (seeget_mu()).Property inputs must be physically valid — pressures, temperatures and densities positive, every value finite. This layer does not check;
ember.block.Block.set_P_T()and its siblings are the validated entry points.A new equation of state is a subclass implementing the abstract methods below;
from_dict()then reconstructs it by class name.Thermodynamic state
get_P(rho, u[, out])Static pressure.
get_T(rho, u[, out])Static temperature.
get_h(rho, u[, out])Specific enthalpy, relative to the datum (see Datum state).
get_s(rho, u[, out])Specific entropy, relative to the datum (see Datum state).
get_a(rho, u[, out])Speed of sound.
get_cp(rho, u[, out])Specific heat at constant pressure.
get_cv(rho, u[, out])Specific heat at constant volume.
get_gamma(rho, u[, out])Ratio of specific heats, \(c_p / c_v\).
get_Rgas(rho, u[, out])Specific gas constant.
Setters (return
(rho, u))set_P_T(P, T)Density and internal energy from pressure and temperature.
set_P_h(P, h)Density and internal energy from pressure and specific enthalpy.
set_P_s(P, s)Density and internal energy from pressure and specific entropy.
set_P_rho(P, rho)Density and internal energy from pressure and density.
set_h_s(h, s)Density and internal energy from specific enthalpy and entropy.
set_rho_s(rho, s)Density and internal energy from density and specific entropy.
set_T_s(T, s)Density and internal energy from temperature and specific entropy.
set_T_rho(T, rho)Density and internal energy from temperature and density.
Partial derivatives
get_dhdP_rho(rho, u[, out])Derivative of enthalpy with respect to pressure at constant density.
get_dhdrho_P(rho, u[, out])Derivative of enthalpy with respect to density at constant pressure.
get_dsdP_rho(rho, u[, out])Derivative of entropy with respect to pressure at constant density.
get_dsdrho_P(rho, u[, out])Derivative of entropy with respect to density at constant pressure.
get_dudP_rho(rho, u[, out])Derivative of internal energy with respect to pressure at constant density.
get_dudrho_P(rho, u[, out])Derivative of internal energy with respect to density at constant pressure.
Transport
get_mu(rho, u[, out])Quasi-dimensional dynamic viscosity, mu / (rho_ref * V_ref) [m].
get_kappa(rho, u[, out])Quasi-dimensional thermal conductivity, kappa / (rho_ref * V_ref * Rgas_ref) [m].
get_Pr(rho, u[, out])Prandtl number, \(\mu c_p / \kappa\).
Batched evaluation and factories
get_P_h_T(rho, u[, out_P, out_h, out_T])Pressure, enthalpy and temperature together, from density and energy.
from_dict(data)Build a fluid from a dict written by
to_dict().to_dict()Return a portable record of this fluid, ready for
from_dict().change_datum(P_dtm, T_dtm)Return a new instance with datum shifted to (P_dtm, T_dtm).
change_ref([rho_ref, V_ref, Rgas_ref])Return a new instance with different reference scales.
change_visc(scale_visc)Return a new instance with the viscosity scaled by a factor.
- classmethod from_dict(data)[source]¶
Build a fluid from a dict written by
to_dict().Called on
Fluidit dispatches on thetypekey, so a saved fluid can be read back without the caller knowing which equation of state wrote it. Called on a concrete class it checks thattypenames that class, so loading the wrong file is an error rather than a constructor failure several arguments deep.
- abstractmethod set_h_s(h, s)[source]¶
Density and internal energy from specific enthalpy and entropy.
- abstractmethod set_P_h(P, h)[source]¶
Density and internal energy from pressure and specific enthalpy.
- abstractmethod set_P_s(P, s)[source]¶
Density and internal energy from pressure and specific entropy.
- abstractmethod set_rho_s(rho, s)[source]¶
Density and internal energy from density and specific entropy.
- abstractmethod set_T_s(T, s)[source]¶
Density and internal energy from temperature and specific entropy.
- abstractmethod get_dhdP_rho(rho, u, out=None)[source]¶
Derivative of enthalpy with respect to pressure at constant density.
- abstractmethod get_dhdrho_P(rho, u, out=None)[source]¶
Derivative of enthalpy with respect to density at constant pressure.
- abstractmethod get_dsdP_rho(rho, u, out=None)[source]¶
Derivative of entropy with respect to pressure at constant density.
- abstractmethod get_dsdrho_P(rho, u, out=None)[source]¶
Derivative of entropy with respect to density at constant pressure.
- abstractmethod get_dudP_rho(rho, u, out=None)[source]¶
Derivative of internal energy with respect to pressure at constant density.
- abstractmethod get_dudrho_P(rho, u, out=None)[source]¶
Derivative of internal energy with respect to density at constant pressure.
- abstractmethod get_h(rho, u, out=None)[source]¶
Specific enthalpy, relative to the datum (see Datum state).
- abstractmethod get_kappa(rho, u, out=None)[source]¶
Quasi-dimensional thermal conductivity, kappa / (rho_ref * V_ref * Rgas_ref) [m].
Conductivity and viscosity are the two transport properties an equation of state owns; the Prandtl number relating them is a derived quantity whichever of the three a given fluid happens to store.
- abstractmethod get_mu(rho, u, out=None)[source]¶
Quasi-dimensional dynamic viscosity, mu / (rho_ref * V_ref) [m].
- get_P_h_T(rho, u, out_P=None, out_h=None, out_T=None)[source]¶
Pressure, enthalpy and temperature together, from density and energy.
A batched form of
get_P(),get_h()andget_T(), for callers that want all three from the same state – the solver does, once per Runge-Kutta stage. Evaluating them separately re-readsrhoanduthree times, and for most equations of state the three share nearly all of their work.Deliberately NOT abstract: this base implementation simply delegates to the three single-property methods, so every fluid – present or future – is correct without implementing anything. A subclass may override it with a fused evaluation purely as an optimisation, and is not obliged to.
PerfectFluiddoes.- Parameters:
rho (array_like) – Density [kg/m³].
u (array_like) – Specific internal energy [J/kg].
out_P (ndarray, optional) – Pre-allocated output arrays.
out_h (ndarray, optional) – Pre-allocated output arrays.
out_T (ndarray, optional) – Pre-allocated output arrays.
- Returns:
(P, h, T).- Return type:
tuple of ndarray
- abstractmethod get_s(rho, u, out=None)[source]¶
Specific entropy, relative to the datum (see Datum state).
- abstractmethod change_datum(P_dtm, T_dtm)[source]¶
Return a new instance with datum shifted to (P_dtm, T_dtm).
A pure factory: the returned fluid carries the same properties on the new datum, and no field values are transformed. To move a stored flow field onto another datum, pass the new fluid to
ember.block.Block.set_fluid(), which reads the state out through the old fluid and re-expresses it through the new one.Note that
T_dtm = 0is not representable: the datum setsu = s = 0simultaneously, and entropy carries a \(\ln(T/T_\mathrm{dtm})\) term that is singular there.
- abstractmethod change_ref(rho_ref=None, V_ref=None, Rgas_ref=None)[source]¶
Return a new instance with different reference scales.
A pure factory, like
change_datum(): the fitted or stored properties are untouched, only the scales the non-dimensionalisation uses. An omitted scale keeps this instance’s value, so a call need name only the scales that change. See Reference scales.- Parameters:
rho_ref (float, optional) – New reference density, velocity and gas constant. Any left out keep their current value.
V_ref (float, optional) – New reference density, velocity and gas constant. Any left out keep their current value.
Rgas_ref (float, optional) – New reference density, velocity and gas constant. Any left out keep their current value.
- Returns:
fluid_new – New fluid instance with the same properties on the new scales.
- Return type:
- abstractmethod change_visc(scale_visc)[source]¶
Return a new instance with the viscosity scaled by a factor.
A pure factory in the manner of
change_datum(): nothing else about the fluid moves, and no field values are transformed. Sweeping Reynolds number is what this is for — the geometry, the boundary conditions and the thermodynamics all stay put, and only the transport scale changes.The thermal conductivity scales by the same factor, leaving the Prandtl number where it was, so the Peclet number follows the Reynolds number.
The scaling is relative to this fluid, so the factors of a chain of calls multiply together.
- to_dict()[source]¶
Return a portable record of this fluid, ready for
from_dict().The dict holds plain floats, strings and nested lists only, so it can be written with
jsonor a plain YAML dumper and read by anything. That is the point of it: aRealFluidsurface costs a CoolProp table and an offline fit to produce, and until now the only way to keep one was to pickle the grid it happened to be attached to.Everything the constructor takes is included, the reference scales and the datum among them, so the round trip is exact. A fluid reloaded into another run therefore arrives with the scales of the run that wrote it;
change_ref()is how to move it onto new ones.- Returns:
data – Constructor arguments plus a
typekey naming the class.- Return type:
- property P_dtm¶
Datum pressure \(p_\mathrm{dtm}\) where \(u = s = 0\) [Pa].
User-selectable as discussed in Datum state.
- 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 rho_ref¶
Reference density for nondimensionalisation, \(\rho_\mathrm{ref}\) [kg/m³].
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 T_dtm¶
Datum temperature \(T_\mathrm{dtm}\) where \(u = s = 0\) [K].
User-selectable as discussed in Datum state.
- 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 u_ref¶
Reference specific energy for nondimensionalisation, \(u_\mathrm{ref}\) [J/kg].
See Reference scales; derived from
\[u_\mathrm{ref} = V_\mathrm{ref}^2\]
- property V_ref¶
Reference velocity for nondimensionalisation, \(V_\mathrm{ref}\) [m/s].
User-specified; see Reference scales.
- class 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.
Methods:
set_h_s(h, s)Density and internal energy from specific enthalpy and entropy.
set_P_h(P, h)Density and internal energy from pressure and specific enthalpy.
set_P_rho(P, rho)Density and internal energy from pressure and density.
set_P_s(P, s)Density and internal energy from pressure and specific entropy.
set_P_T(P, T)Density and internal energy from pressure and temperature.
set_rho_s(rho, s)Density and internal energy from density and specific entropy.
set_T_rho(T, rho)Density and internal energy from temperature and density.
set_T_s(T, s)Density and internal energy from temperature and specific entropy.
get_a(rho, u[, out])Speed of sound from density and internal energy.
get_cp(rho, u[, out])Specific heat at constant pressure (constant for a perfect gas).
get_cv(rho, u[, out])Specific heat at constant volume (constant for a perfect gas).
get_dhdP_rho(rho, u[, out])Derivative of specific enthalpy with respect to pressure at constant density.
get_dhdrho_P(rho, u[, out])Derivative of specific enthalpy with respect to density at constant pressure.
get_dsdP_rho(rho, u[, out])Derivative of specific entropy with respect to pressure at constant density.
get_dsdrho_P(rho, u[, out])Derivative of specific entropy with respect to density at constant pressure.
get_dudP_rho(rho, u[, out])Derivative of specific internal energy with respect to pressure at constant density.
get_dudrho_P(rho, u[, out])Derivative of specific internal energy with respect to density at constant pressure.
get_gamma(rho, u[, out])Ratio of specific heats (constant for a perfect gas).
get_h(rho, u[, out])Specific enthalpy from density and internal energy.
get_kappa(rho, u[, out])Thermal conductivity (constant for a perfect gas).
get_mu(rho, u[, out])Dynamic viscosity (constant for a perfect gas).
get_P(rho, u[, out])Pressure from density and internal energy.
get_P_h_T(rho, u[, out_P, out_h, out_T])Batched evaluation of pressure, enthalpy and temperature.
get_Pr(rho, u[, out])Prandtl number (constant for a perfect gas).
get_Rgas(rho, u[, out])Specific gas constant (constant for a perfect gas).
get_s(rho, u[, out])Specific entropy from density and internal energy.
get_T(rho, u[, out])Temperature from density and internal energy.
change_datum(P_dtm, T_dtm)Return a new instance with datum shifted to (P_dtm, T_dtm).
change_ref([rho_ref, V_ref, Rgas_ref])Return a new instance with different reference scales.
change_visc(scale_visc)Scale the stored constant
mu(andkappawith it).- 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\),
\[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 definition of internal energy,
\[\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 definition of internal energy,
\[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_kappa(rho, u, out=None)[source]¶
Thermal conductivity (constant for a perfect gas).
\[\kappa = \frac{\mu c_p}{\mathit{Pr}}\]If reference scales are set, then this method returns a quasi-dimensional conductivity 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:
kappa – Thermal conductivity [W/m/K].
- 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_P_h_T(rho, u, out_P=None, out_h=None, out_T=None)[source]¶
Batched evaluation of pressure, enthalpy and temperature.
The base class calls
get_P(),get_h()andget_T()in sequence, so this method is an optional override for subclasses that can compute all three in a single pass over the state. The CFD solver calls this method once per Runge-Kutta stage, so a fused evaluation can save time.- Parameters:
rho (array_like) – Density [kg/m³].
u (array_like) – Specific internal energy [J/kg].
out_P (ndarray, optional) – Pre-allocated output arrays.
out_h (ndarray, optional) – Pre-allocated output arrays.
out_T (ndarray, optional) – Pre-allocated output arrays.
- Returns:
(P, h, T).- Return type:
tuple of 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]¶
Return a new instance with datum shifted to (P_dtm, T_dtm).
A pure factory: the returned fluid carries the same properties on the new datum, and no field values are transformed. To move a stored flow field onto another datum, pass the new fluid to
ember.block.Block.set_fluid(), which reads the state out through the old fluid and re-expresses it through the new one.Note that
T_dtm = 0is not representable: the datum setsu = s = 0simultaneously, and entropy carries a \(\ln(T/T_\mathrm{dtm})\) term that is singular there.
- change_ref(rho_ref=None, V_ref=None, Rgas_ref=None)[source]¶
Return a new instance with different reference scales.
A pure factory, like
change_datum(): the fitted or stored properties are untouched, only the scales the non-dimensionalisation uses. An omitted scale keeps this instance’s value, so a call need name only the scales that change. See Reference scales.- Parameters:
rho_ref (float, optional) – New reference density, velocity and gas constant. Any left out keep their current value.
V_ref (float, optional) – New reference density, velocity and gas constant. Any left out keep their current value.
Rgas_ref (float, optional) – New reference density, velocity and gas constant. Any left out keep their current value.
- Returns:
fluid_new – New fluid instance with the same properties on the new scales.
- Return type:
- change_visc(scale_visc)[source]¶
Scale the stored constant
mu(andkappawith it).See
Fluid.change_visc()for the contract.
- class fluid.RealFluid(alpha, beta, delta, gamma, rho_lim, u_lim, Rgas, mu_c, kappa_c, scale_visc=1.0, P_dtm=None, T_dtm=None, rho_ref=1.0, V_ref=1.0, Rgas_ref=1.0)[source]¶
Bases:
FluidReal gas defined by a fitted entropy surface.
Implements the thermodynamically consistent equation of state of Wheeler [1]. A polynomial surface is fitted offline to the compressibility factor and integrated analytically to give entropy; temperature and pressure are then derived from that one surface rather than fitted separately, so the thermodynamic relations between them hold exactly. Use
ember.realgas_fitto produce the coefficients.The consistency is the point. An interpolated lookup table satisfies its own tabulated values but not the relations between them, and the resulting mismatch acts like a non-equilibrium process, creating spurious entropy wherever gradients are steep. Wheeler shows a 62k-point table was needed to bring turbine entropy rise within 1.4 percent of this method.
Evaluation¶
Everything descends from the entropy surface and its partials, via the combined first and second law \(\mathrm{d}u = T\,\mathrm{d}s + (p/\rho^2)\,\mathrm{d}\rho\):
\[T = \left[\left(\frac{\partial s}{\partial u}\right)_\rho\right]^{-1}, \qquad p = -\rho^2 T \left(\frac{\partial s}{\partial \rho}\right)_u\]The inverse
set_*methods have no closed form and are solved by Newton iteration; seeset_P_rho()andset_P_T().Domain of validity¶
The polynomials mean nothing outside the box they were fitted over, so
rho_limandu_limare enforced: iterates are clamped to the box, and a solve that cannot meet its tolerance, or that returns no number at all, raises rather than returning a state the fit does not describe.A density passed in rather than solved for – by
set_rho_s(),set_P_rho()andset_T_rho()– is checked against the box before the iteration starts. Nothing later could catch it: the fitted surface extrapolates smoothly, so the solve would converge on a state that is self-consistent with a polynomial nobody fitted out there.Transport properties¶
Viscosity and conductivity are fitted surfaces of their own, in the same normalised coordinates as \(Z\) and produced by the same offline tool. They are independent least-squares fits and take no part in the consistency argument above — nothing relates them to entropy, and neither is ever differentiated. Each is normalised by its value at the centre of the fit box, which
mu_candkappa_ccarry, so the coefficients are of order unity. The Prandtl number is not stored;get_Pr()derives it from the two surfaces and the specific heat.The solver reads both surfaces at every node:
mu_ndandkappa_ndare nodal fields, and the viscous kernel takes them as such.- type alpha:
array_like
- param alpha:
Two-dimensional Legendre coefficients of the compressibility factor \(Z(\hat\rho, \hat u)\) [–], in density and internal energy each scaled onto \([-1, 1]\) by the fit-box bounds.
- type alpha:
array_like
- type beta:
array_like
- param beta:
One-dimensional Legendre coefficients of \(s/R\) along the reference isochor, the one through the centre of the density box.
- type beta:
array_like
- type delta:
array_like
- param delta:
Two-dimensional Legendre coefficients of the viscosity surface [–], normalised by
mu_c.- type delta:
array_like
- type gamma:
array_like
- param gamma:
Two-dimensional Legendre coefficients of the conductivity surface [–], normalised by
kappa_c.- type gamma:
array_like
- type rho_lim:
tuple
- param rho_lim:
(min, max)density bounds of the fit box [kg/m³].- type rho_lim:
tuple
- type u_lim:
tuple
- param u_lim:
(min, max)internal energy bounds of the fit box [J/kg], on the same datum as the databetawas fitted to.- type u_lim:
tuple
- type Rgas:
float
- param Rgas:
Specific gas constant [J/kg/K]. Converts the two dimensionless coefficient arrays into entropy, and is what
get_Rgas()reports.- type Rgas:
float
- type mu_c:
float
- param mu_c:
Dynamic viscosity at the centre of the fit box [kg/m/s], the scale the
deltasurface is normalised by.- type mu_c:
float
- type kappa_c:
float
- param kappa_c:
Thermal conductivity at the centre of the fit box [W/m/K], the scale the
gammasurface is normalised by.- type kappa_c:
float
- type scale_visc:
float, optional
- param scale_visc:
Factor multiplying the viscosity, for sweeping Reynolds number without touching the fit; see
change_visc().- type scale_visc:
float, optional
- type P_dtm:
float, optional
- param P_dtm:
Datum pressure where u = 0 and s = 0 [Pa]. Must lie in the fit box. Defaults to this fluid’s own pressure at the centre of that box, which is inside it by construction; see Datum state.
- type P_dtm:
float, optional
- type T_dtm:
float, optional
- param T_dtm:
Datum temperature where u = 0 and s = 0 [K]. Must lie in the fit box. Defaults to the temperature at the same point. Either may be given on its own, the other still defaulting.
- type T_dtm:
float, optional
- type rho_ref:
float, optional
- param rho_ref:
Reference density for non-dimensionalisation.
- type rho_ref:
float, optional
- type V_ref:
float, optional
- param V_ref:
Reference velocity for non-dimensionalisation.
- type V_ref:
float, optional
- type Rgas_ref:
float, optional
- param Rgas_ref:
Reference gas constant for non-dimensionalisation.
- type Rgas_ref:
float, optional
Methods:
set_h_s(h, s)Density and internal energy from specific enthalpy and entropy.
set_P_h(P, h)Density and internal energy from pressure and specific enthalpy.
set_P_rho(P, rho)Density and internal energy from pressure and density.
set_P_s(P, s)Density and internal energy from pressure and specific entropy.
set_P_T(P, T)Density and internal energy from pressure and temperature.
set_rho_s(rho, s)Density and internal energy from density and specific entropy.
set_T_rho(T, rho)Density and internal energy from temperature and density.
set_T_s(T, s)Density and internal energy from temperature and specific entropy.
get_a(rho, u[, out])Speed of sound from density and internal energy.
get_cp(rho, u[, out])Specific heat at constant pressure from density and internal energy.
get_cv(rho, u[, out])Specific heat at constant volume from density and internal energy.
get_dhdP_rho(rho, u[, out])Derivative of specific enthalpy with respect to pressure at constant density.
get_dhdrho_P(rho, u[, out])Derivative of specific enthalpy with respect to density at constant pressure.
get_dsdP_rho(rho, u[, out])Derivative of specific entropy with respect to pressure at constant density.
get_dsdrho_P(rho, u[, out])Derivative of specific entropy with respect to density at constant pressure.
get_dudP_rho(rho, u[, out])Derivative of specific internal energy with respect to pressure at constant density.
get_dudrho_P(rho, u[, out])Derivative of specific internal energy with respect to density at constant pressure.
get_gamma(rho, u[, out])Isentropic exponent from density and internal energy.
get_h(rho, u[, out])Specific enthalpy from density and internal energy.
get_kappa(rho, u[, out])Thermal conductivity from the fitted transport surface.
get_mu(rho, u[, out])Dynamic viscosity from the fitted transport surface.
get_P(rho, u[, out])Pressure from density and internal energy.
get_P_h_T(rho, u[, out_P, out_h, out_T])Batched evaluation of pressure, enthalpy and temperature.
get_Pr(rho, u[, out])Prandtl number, derived from the two transport surfaces.
get_Rgas(rho, u[, out])Specific gas constant (a constant property of the species).
get_s(rho, u[, out])Specific entropy from density and internal energy.
get_T(rho, u[, out])Temperature from density and internal energy.
change_datum(P_dtm, T_dtm)Shift the datum.
change_ref([rho_ref, V_ref, Rgas_ref])Rescale.
change_visc(scale_visc)Scale the two fitted transport surfaces together --- there is no stored viscosity, only a polynomial in \((\rho, u)\).
Attributes:
Density bounds of the fit box \(\rho/\rho_\mathrm{ref}\) [--].
Internal energy bounds of the fit box \(u/u_\mathrm{ref}\) [--].
- set_h_s(h, s)[source]¶
Density and internal energy from specific enthalpy and entropy.
Solved by two-dimensional Newton iteration; see
set_P_T().- 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.
Solved by two-dimensional Newton iteration; see
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.
Density is already known, so this is a scalar Newton solve for the internal energy satisfying \(p(\rho, u) = p\), seeded from the companion perfect gas. The residual is monotone in \(u\), since heating at constant volume raises pressure.
This is on the per-step nonreflecting boundary path, so it is solved for the whole array at once rather than node by node.
- 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.
Solved by two-dimensional Newton iteration; see
set_P_T().- 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.
Neither variable is known directly, so both are found together by Newton iteration on the 2x2 system \(p(\rho, u) = p\), \(T(\rho, u) = T\), with the Jacobian assembled analytically from the entropy surface and inverted in closed form.
Conditioning degrades near the critical point, where \((\partial p/\partial\rho)_T \rightarrow 0\) and the Jacobian determinant vanishes. That is physical rather than numerical – pressure and temperature stop being independent coordinates on the saturation line – and lies outside any sensible fit box, but it will surface as a convergence failure rather than a wrong answer.
- 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.
A scalar Newton solve for the internal energy satisfying \(s(\rho, u) = s\). The residual is monotone in \(u\) because \((\partial s/\partial u)_\rho = 1/T > 0\), so convergence is assured from any starting point in the box.
This is on the per-step nonreflecting boundary path, so it is solved for the whole array at once rather than node by node.
- 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.
A scalar Newton solve for the internal energy satisfying \(T(\rho, u) = T\). The residual is monotone in \(u\) because the specific heat at constant volume is positive.
- 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.
Solved by two-dimensional Newton iteration; see
set_P_T().- 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.
\[a = \sqrt{k\, p / \rho}\]where \(k\) is the isentropic exponent of
get_gamma(). Note this is the isentropic exponent and not the ratio of specific heats, which for a real gas is a different number.- 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 from density and internal energy.
Obtained from the specific heat at constant volume and the ratio of the isentropic and isothermal density derivatives of pressure,
\[\frac{c_p}{c_v} = \frac{(\partial p/\partial\rho)_s}{(\partial p/\partial\rho)_T}\]- 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 from density and internal energy.
\[c_v = \left(\frac{\partial u}{\partial T}\right)_\rho\]evaluated by inverting the temperature derivative, which comes from the second derivative of the entropy surface.
- 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.
\[\left.\frac{\partial h}{\partial p}\right|_\rho = \left.\frac{\partial u}{\partial p}\right|_\rho + \frac{1}{\rho}\]- 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.
\[\left.\frac{\partial h}{\partial \rho}\right|_p = \left.\frac{\partial u}{\partial \rho}\right|_p - \frac{p}{\rho^2}\]- 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.
Obtained by chain rule through internal energy at fixed density,
\[\left.\frac{\partial s}{\partial p}\right|_\rho = \frac{(\partial s/\partial u)_\rho}{(\partial p/\partial u)_\rho}\]- 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.
\[\left.\frac{\partial s}{\partial \rho}\right|_p = \left.\frac{\partial s}{\partial \rho}\right|_u + \left.\frac{\partial s}{\partial u}\right|_\rho \left.\frac{\partial u}{\partial \rho}\right|_p\]- 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.
The reciprocal of the pressure derivative taken directly from the surface,
\[\left.\frac{\partial u}{\partial p}\right|_\rho = \left[\left.\frac{\partial p}{\partial u}\right|_\rho\right]^{-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.
\[\left.\frac{\partial u}{\partial \rho}\right|_p = -\frac{(\partial p/\partial \rho)_u}{(\partial p/\partial u)_\rho}\]- 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]¶
Isentropic exponent from density and internal energy.
\[k = \frac{\rho}{p}\left.\frac{\partial p}{\partial \rho}\right|_s\]This is the exponent that governs acoustics and the characteristic decomposition, and it is what
get_a()uses. For a real gas it is not the ratio of specific heats \(c_p/c_v\), which is available separately fromget_cp()andget_cv(); the two coincide only when the specific heats are constant.- Parameters:
rho (array_like) – Density [kg/m³].
u (array_like) – Specific internal energy [J/kg].
out (ndarray, optional) – Pre-allocated output array.
- Returns:
gamma – Isentropic exponent [–].
- Return type:
ndarray
- get_h(rho, u, out=None)[source]¶
Specific enthalpy from density and internal energy.
\[h = u + p/\rho\]Enthalpy carries an offset dependent on the arbitrary datum state where \(u = s = 0\); only changes in \(h\) 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:
h – Specific enthalpy [J/kg].
- Return type:
ndarray
- get_kappa(rho, u, out=None)[source]¶
Thermal conductivity from the fitted transport surface.
One polynomial evaluation and nothing else: unlike pressure and temperature, conductivity is not derived from the entropy surface and so needs none of its derivatives.
If reference scales are set, then this method returns a quasi-dimensional conductivity 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:
kappa – Thermal conductivity [W/m/K].
- Return type:
ndarray
- get_mu(rho, u, out=None)[source]¶
Dynamic viscosity from the fitted transport surface.
As
get_kappa(), and scaled byscale_visc.- 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 combined first and second law, at constant internal energy,
\[p = -\rho^2 T \left(\frac{\partial s}{\partial \rho}\right)_u\]- 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_P_h_T(rho, u, out_P=None, out_h=None, out_T=None)[source]¶
Batched evaluation of pressure, enthalpy and temperature.
All three come from the same entropy partials, so evaluating them together costs barely more than any one of them, where the base class would walk the polynomial surface three times. The solver calls this once per Runge-Kutta stage.
A float32 call with all three outputs supplied – which is what the solver makes – goes to a Fortran kernel instead. Anything else falls back to the numpy body below rather than to the base class: that body is already fused, and three separate calls would be three times the work.
- Parameters:
rho (array_like) – Density [kg/m³].
u (array_like) – Specific internal energy [J/kg].
out_P (ndarray, optional) – Pre-allocated output arrays.
out_h (ndarray, optional) – Pre-allocated output arrays.
out_T (ndarray, optional) – Pre-allocated output arrays.
- Returns:
(P, h, T).- Return type:
tuple of ndarray
- get_Pr(rho, u, out=None)[source]¶
Prandtl number, derived from the two transport surfaces.
\[\mathit{Pr} = \frac{\mu c_p}{\kappa}\]Nothing here is stored: viscosity and conductivity are what this fluid is given, and the ratio of the two is a property of the state like any other. It is also the most expensive of the three, the specific heat costing the second derivatives of the entropy surface, so a caller after a heat flux wants
get_kappa()rather than this.- 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 (a constant property of the species).
Note that for a real gas this is not \(p/(\rho T)\), which is larger by the compressibility factor.
- 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.
Evaluated directly from the fitted surface: an isochor polynomial in internal energy, less the analytic density integral of the compressibility factor.
Entropy is defined relative to the arbitrary datum state where \(u = s = 0\); 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.
From the combined first and second law, at constant density,
\[T = \left[\left(\frac{\partial s}{\partial u}\right)_\rho\right]^{-1}\]- 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]¶
Shift the datum. The fitted coefficients are untouched — the datum enters only through the affine constants composed at construction, so there is no refit. See
Fluid.change_datum().
- change_ref(rho_ref=None, V_ref=None, Rgas_ref=None)[source]¶
Rescale. No refit, as for
change_datum(); seeFluid.change_ref().
- change_visc(scale_visc)[source]¶
Scale the two fitted transport surfaces together — there is no stored viscosity, only a polynomial in \((\rho, u)\).
See
Fluid.change_visc()for the contract.
- property rho_lim_nd¶
Density bounds of the fit box \(\rho/\rho_\mathrm{ref}\) [–].
The constructor takes the box in SI, but
get_*andset_*work in non-dimensional units, so this is the form a caller needs to check that a state is in range. Outside these bounds the fitted polynomials are meaningless and theset_*solves will refuse to converge.
- property u_lim_nd¶
Internal energy bounds of the fit box \(u/u_\mathrm{ref}\) [–].
As
rho_lim_nd, and additionally shifted onto this fluid’s datum: the constructor’su_limis on whatever datum the coefficients were fitted against, whereasget_*andset_*take internal energy measured fromP_dtm,T_dtm. Changing the datum moves these bounds even though the underlying box is unchanged.