"""Several flow properties and equations are given here, including
dimensionless parameters and corresponding correlations"""
import numpy as np
from numba import njit
from stream.units import (
Celsius,
JPerKgK,
KgPerM3,
KgPerS,
Meter,
Meter2,
MPerS,
MPerS2,
PaS,
PerC,
Value,
WPerM2K,
WPerMK,
)
from stream.units import (
g as local_gravity,
)
__all__ = ["flow_regimes", "Gr", "Nu", "Pe", "Pr", "Ra", "Re", "Re_mdot"]
[docs]
@njit
def Re(rho: KgPerM3, u: MPerS, L: Meter, mu: PaS) -> Value:
r"""
The Reynolds number (Re) is defined as the ratio between inertial forces
and viscous forces. :math:`\text{Re} = \rho u L / \mu`
Parameters
----------
rho: KgPerM3
fluid density
u: MPerS
characteristic or equivalent velocity
L: Meter
characteristic or equivalent length
mu: PaS
dynamic viscosity of the fluid
Returns
-------
Re: Value
The Reynolds number
Examples
--------
>>> Re(rho=0., u=1., L=1., mu=1.)
0.0
>>> Re(rho=1., u=np.arange(-2, 3), L=1., mu=1.)
array([2., 1., 0., 1., 2.])
>>> Re(rho=1., u=1., L=1., mu=np.inf)
0.0
"""
return rho * np.abs(u) * L / mu
[docs]
@njit
def Re_mdot(mdot: KgPerS, A: Meter2, L: Meter, mu: PaS) -> Value:
r"""
The Reynolds number (Re) is defined as the ratio between inertial forces
and viscous forces. If :math:`\dot{m} = \rho uA` is known,
one may write :math:`\text{Re} = \dot{m}(L / A) / \mu`
Parameters
----------
mdot: KgPerS
fluid mass current
A: Meter2
flow area
L: Meter
characteristic or equivalent length
mu: PaS
dynamic viscosity of the fluid
Returns
-------
Re: Value
The Reynolds number
Examples
--------
>>> Re_mdot(mdot=1., A=1., L=1., mu=1.)
1.0
>>> Re_mdot(mdot=-1., A=1., L=1., mu=1.)
1.0
>>> Re_mdot(mdot=0., A=1., L=1., mu=1.)
0.0
"""
return np.abs(mdot) * L / (A * mu)
[docs]
@njit
def Pr(cp: JPerKgK, mu: PaS, k: WPerMK) -> Value:
r"""
The Prandtl number (Pr) is defined as the ratio between viscous
diffusivity and thermal diffusivity. :math:`\text{Pr} = c_p \mu / k`
Parameters
----------
cp: JPerKgK
specific heat of the fluid
mu: PaS
dynamic viscosity of the fluid
k: WPerMK
thermal conductivity of the fluid
Returns
-------
Pr: Value
The Prandtl number
Examples
--------
>>> Pr(cp=0.5, mu=0.1, k=50)
0.001
"""
return cp * mu / k
[docs]
@njit
def Nu(h: WPerM2K, L: Meter, k: WPerMK) -> Value:
r"""
The Nusselt number (Nu) is defined as the ratio between convective and
conductive heat transfer across the boundary. :math:`\text{Nu} = hL/k`
Parameters
----------
h: WPerM2K
heat transfer coefficient
L: Meter
characteristic or equivalent length
k: WPerMK
thermal conductivity of the fluid
Returns
-------
Nu: Value
The Nusselt number
Examples
--------
>>> Nu(h=1., L=1., k=1.)
1.0
"""
return h * L / k
[docs]
@njit
def Pe(rho: KgPerM3, v: MPerS, L: Meter, cp: JPerKgK, k: WPerMK) -> Value:
r"""
The Peclet number (Pe) is defined as the ratio between advective and
diffusive transport rates. For heat transfer, it is the product of
:math:`\text{Pe} = \text{Re}\text{Pr}`
Parameters
----------
rho: KgPerM3
fluid density
v: MPerS
characteristic or equivalent velocity
L: Meter
characteristic or equivalent length
cp: JPerKgK
specific heat of the fluid
k: WPerMK
thermal conductivity of the fluid
Returns
-------
Pe: Value
The Peclet Number
Examples
--------
>>> Pe(rho=1., v=1., L=1., cp=1., k=1.)
1.0
"""
return Re(rho=rho, u=v, L=L, mu=1.0) * Pr(cp=cp, k=k, mu=1.0)
[docs]
@njit
def Gr(
rho: KgPerM3,
mu: PaS,
beta: PerC,
T: Celsius,
Twall: Celsius,
Dh: Meter,
g: MPerS2 = local_gravity,
) -> Value:
r"""The Grashof number (Gr) is an approximation of the ratio of buoyancy to viscous
forces.
For vertical flat plates:
.. math:: \text{Gr} = \rho^2 g\beta (T_\text{wall}-T_\text{bulk})\frac{L_h^3}{\mu^2}
Parameters
----------
rho: KgPerM3
fluid density
mu: PaS
dynamic viscosity of the fluid
beta: PerC
fluid thermal expansion coefficient
T: Celsius
fluid bulk temperature
Twall: Celsius
wall\surface temperature
Dh: Meter
Hydraulic diameter
g: MPerS2
Gravitational acceleration constant
Returns
-------
Gr: Value
The Grashof Number
Examples
--------
>>> Gr(rho=1, mu=1, beta=1, T=50, Twall=50, Dh=1)
0.0
"""
return rho**2 * g * beta * (Twall - T) * Dh**3 / mu**2
[docs]
@njit
def Ra(
rho: KgPerM3,
mu: PaS,
cp: JPerKgK,
k: WPerMK,
beta: PerC,
T: Celsius,
Twall: Celsius,
Dh: Meter,
g: MPerS2 = local_gravity,
) -> Value:
r"""The Rayleigh number (Ra) is associated with heat transfer for natural convection.
At low values, heat transfer is primarily conductive, and at high values it is
primarily convective. :math:`\text{Ra} = \text{Gr}\text{Pr}`
Parameters
----------
rho: KgPerM3
fluid density
mu: PaS
dynamic viscosity of the fluid
cp: JPerKgK
specific heat of the fluid
k: WPerMK
thermal conductivity of the fluid
beta: PerC
fluid thermal expansion coefficient
T: Celsius
fluid bulk temperature
Twall: Celsius
wall\surface temperature
Dh: Meter
Hydraulic diameter
g: MPerS2
Gravitational acceleration constant
Returns
-------
Ra: Value
The Rayleigh Number
Examples
--------
>>> Ra(rho=1, mu=1, cp=1, k=1, beta=1, T=50, Twall=50, Dh=1)
0.0
"""
return Gr(rho, mu, beta, T, Twall, Dh, g) * Pr(cp, mu, k)
[docs]
@njit
def flow_regimes(re: np.ndarray, bounds: tuple[Value, Value]) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
"""
Turbulent, Laminar and Interim regimes are determined by the Reynolds No.
Parameters
----------
re: np.ndarray
Reynolds numbers vector
bounds: tuple[Value, Value]
boundaries depicting transition between the aforementioned regimes,
such that:
- Re <= bounds[0] is considered laminar.
- bounds[0] < Re <= bounds[1] is considered interim.
- bounds[1] < Re is considered turbulent.
Returns
-------
Numpy masks: tuple[np.ndarray, np.ndarray, np.ndarray]
Laminar, Interim, Turbulent
Examples
--------
>>> a, b, c = flow_regimes(np.arange(5), (2, 3))
>>> a
array([ True, True, True, False, False])
>>> b
array([False, False, False, True, False])
>>> c
array([False, False, False, False, True])
"""
laminar = re <= bounds[0]
interim = (bounds[0] < re) * (re <= bounds[1])
turbulent = bounds[1] < re
return laminar, interim, turbulent