Source code for stream.physical_models.heat_transfer_coefficient.laminar

"""Laminar Single Phase Heat Transfer Coefficient"""

import numpy as np

from stream.physical_models.dimensionless import Pr, Re_mdot
from stream.substances import Liquid
from stream.units import KgPerS, Meter, Meter2, Value, WPerM2K

#: For parallel plates in laminar flow, the Nusselt number is constant,
#: depending on the boundary conditions. See
#: J. H. Lienhard IV, J. H. Lienhard V, "A HEAT TRANSFER TEXTBOOK",
#: 3rd ed., ch. 7.5, p. 373
FIXED_TEMPS, FIXED_FLUXES, ONE_FIXED_FLUX_ONE_ADIABATIC = 7.541, 8.235, 5.385


[docs] def constant_Nusselt_h_spl(*, coolant: Liquid, Dh: Meter, nu: float = FIXED_FLUXES, **_) -> WPerM2K: r"""A :class:`~.SinglePhaseLiquidHTC` for constant :func:`~.Nu` Number: math:`h = \text{Nu}k/D_h` Parameters ---------- coolant: Liquid Properties of the coolant. Dh: Meter Hydraulic diameter. nu: float Nusselt Number. Default is :const:`FIXED_FLUXES` Returns ------- Watts per Meter squared degrees Kelvin Heat transfer coefficient """ return coolant.conductivity * nu / Dh
[docs] def Marco_Han_Nusselt(aspect_ratio: float) -> Value: """ For the case of laminar flow in rectangular ducts, an approximation to an analytical solution by Marco and Han is provided (reported error is +-0.03%). [#kakac]_ This is useful for ducts of case 1, where the channel is heated from all sides. Parameters ---------- aspect_ratio: float channel_depth / channel_width (less than 1) Returns ------- Nu: float The Nusselt number (Nu) Examples -------- >>> Marco_Han_Nusselt(0.) 8.235 >>> Marco_Han_Nusselt(0.2) 5.991134842079999 References ---------- .. [#kakac] S. Kakac, R. K. Shah, W. Wung, "Handbook of Single-Phase Convective Heat-transfer" ch. 3 """ assert 0.0 <= aspect_ratio <= 1.0, f"{aspect_ratio = } must be non-negative and less than 1" return FIXED_FLUXES * ( 1.0 - 2.0421 * aspect_ratio + 3.853 * aspect_ratio**2 - 2.4765 * aspect_ratio**3 + 1.0578 * aspect_ratio**4 - 0.1861 * aspect_ratio**5 )
[docs] def two_sided_heating_nusselt(aspect_ratio: Value, nu0: float = FIXED_FLUXES) -> Value: """Nusselt number for channels heated from two sides. For the case of laminar flow in rectangular ducts, an approximation to an analytical solution is given in case 3 of Kakac [#kakac_two_side]_ Parameters ---------- aspect_ratio: float channel_depth / channel_width (0<=x<=1) nu0: float The nusselt value for an infinitely wide channel compared to its depth. Defaults to the fully developed value. Returns ------- Nu: float The Nusselt number (Nu) Examples -------- >>> two_sided_heating_nusselt(0.) 8.235 The answer should conform with the results Shah & London give from Schmidt in their table 44 [#Shah_two_side]_ >>> alpha = np.array([0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 1.0]) >>> vtable44 = np.array([8.235, 7.248, 6.561, 5.997, 5.555, 5.203, 4.662, 4.094]) >>> np.allclose(two_sided_heating_nusselt(alpha), vtable44, rtol=1.1e-2) True References ---------- .. [#kakac_two_side] S. Kakac, R. K. Shah, W. Wung, "Handbook of Single-Phase Convective Heat-transfer" ch. 3 .. [#Shah_two_side] R.K. Shah and A.L. London, Laminar flow forced convection in ducts, A source book for compact heat exchanger analytical data, Academic Press 1978, New York, San Francisco, London, Chapter VII, Rectangular ducts, Section 3, Page 206, Table 44. """ return nu0 * ( 1.0 - 1.4122 * aspect_ratio + 2.3473 * aspect_ratio**2 - 2.8983 * aspect_ratio**3 + 2.0629 * aspect_ratio**4 - 0.6077 * aspect_ratio**5 )
[docs] def fully_developed_laminar_h_spl(*, coolant: Liquid, Dh: Meter, aspect_ratio: float, **_) -> WPerM2K: """A :class:`~.SinglePhaseLiquidHTC` relying on :func:`Marco_Han_Nusselt` Parameters ---------- coolant: Liquid Properties of the coolant. Dh: Meter Hydraulic diameter. aspect_ratio: float in [0,1] The aspect ratio of the channel. Returns ------- Watts per Meter squared degrees Kelvin Heat transfer coefficient """ return coolant.conductivity * two_sided_heating_nusselt(aspect_ratio) / Dh
def _nusselt_coefficient_developing(x: Value) -> Value: r"""Developing flow nusselt number at infinitely wide rectangular channels. Taken from Shah & London [#Shah_develop]_ , who recommend them for being convenient apporixmations. Also appears in TERMIC [#TERMIC_dev]_. According to Shah & London, the errors compared to their Table 34 of directly computed values should be less than 0.2% for :math:`x \leq 6\cdot 10^{-5}`, 0.6% for :math:`6\cdot 10{^-5} < x \leq 2\cdot 10^{-4}`, 0.8% for :math:`2\cdot 10^{-4} < x \leq 10^{-3}` and 0.6% for :math:`x > 10^{-3}`. It turns out to be slightly larger than those values overall, and about 10x times higher for :math:`2\cdot 10^{-4} < x \leq 10^{-3}` This is tested in the examples for this function. Examples -------- >>> x = _xstar_table34 >>> v = _nusselt_coefficient_developing(x) >>> r1 = x <= 6e-5 >>> r2 = (6e-5 < x) & (x <= 2e-4) >>> r3 = (2e-4 < x) & (x <= 1e-3) >>> r4 = x > 1e-3 >>> areclose = [np.allclose(v[m], _nuxh_table34[m], rtol=rtol) # type: ignore ... for m, rtol in zip((r1, r2, r3, r4), (3e-3, 7e-3, 6.2e-2, 7e-3))] >>> all(areclose) True References ---------- .. [#Shah_develop] R.K. Shah and A.L. London, Laminar flow forced convection in ducts, A source book for compact heat exchanger analytical data, Academic Press 1978, New York, San Francisco, London, Chapter VI, Parallel plates, Section C, Page 182, Equations 317-319. .. [#TERMIC_dev] P. Abbate, TERMIC V4.1: A Program for the Thermal-Hydraulic Analysis of a MTR Core in Forced Convection, Vol 1: Models and Correlations, Rev 3, Pages 14-15, Nuclear Engineering Division, INVAP, December 2003 """ return np.where( x <= 2e-4, 1.49 * x ** (-1 / 3), np.where( x <= 1e-3, (1.49 * (x ** (-1 / 3))) - 0.4, 8.235 + 8.68 * np.exp(-164 * x) * ((1e3 * x) ** -0.506), ), ) _xstar_table34 = np.array( sum( [[j * 10 ** (-i) for j in (1, 1.5, 2, 3, 4, 5, 6, 7, 8, 9)] for i in [6, 5, 4, 3, 2]], start=[], ) + [0.1, 0.15, 0.2] ) _nuxh_table34 = np.array( [ 148.773, 129.944, 118.049, 103.110, 93.673, 86.954, 81.824, 77.724, 74.339, 71.477, 69.011, 60.292, 54.787, 47.880, 43.521, 40.419, 38.054, 36.165, 34.607, 33.290, 32.153, 28.154, 25.636, 22.488, 20.512, 19.133, 18.050, 17.205, 16.511, 15.928, 15.427, 13.681, 12.604, 11.299, 10.516, 9.9878, 9.6085, 9.3249, 9.1073, 8.9374, 8.8031, 8.4393, 8.3107, 8.2458, 8.2368, 8.2355, ] + 7 * [8.2353] ) def _worsoe_schmidt_leveque_type(x): r"""Worsoe-Schmidt's Leveque-type similarity solution for the Nusselt number at low xstar. Shah [#Shah_worsoe]_ computed those for :math:`10^{-6} \leq x \leq 10^{-3}`, and they should be up to 5 digits accurate with the proper solution for :math:`5\cdot 10^{-4} \leq x \leq 5\cdot 10^{-3}` and at most 0.08% off for :math:`5\cdot 10^{-5} \leq x \leq 10^{-2}`. Examples -------- Table 34 (for :math:`x \leq 10^{-4}`) was supposed to be computed using this equation, so it should be accurate there. >>> m = _xstar_table34 <= 1e-4 >>> np.allclose(_worsoe_schmidt_leveque_type(_xstar_table34[m]), _nuxh_table34[m], rtol=1e-4) True References ---------- .. [#Shah_worsoe] R.K. Shah and A.L. London, Laminar flow forced convection in ducts, A source book for compact heat exchanger analytical data, Academic Press 1978, New York, San Francisco, London, Chapter VI, Parallel plates, Section C, Page 182, Equation 316 """ xt = x ** (1 / 3) repv = ( 0.670960978 * xt + 0.159064137 * (xt**2) + 0.12012 * x + 0.12495 * (xt**4) + 0.15602 * (xt**5) + 0.22176 * (x**2) + 0.34932 * (xt**7) - 4 * x ) return 1 / repv def _nusselt_coefficient_interp_developing(x: Value) -> Value: r"""Nusselt coefficient for developing heated flow and fully develop hydraulics, by interpolation of data. In Shah & London [#Shah_interp]_, table 34 includes pre-computed data for :math:`10^{-6} \leq x \leq 0.2`. These are supposed to be accurate representations of an analytic solution for :math:`x > 10^{-4}`, and of Equation 316 (an approximate solution, see :func:`._worsoe_schmidt_leveque_type`) otherwise. This function is more exact than :func:`._nusselt_coefficient_developing` but slightly slower. The other one is used by default in our code, and its error is checked against the tabulated values directly in its tests. See Also -------- :func:`._nusselt_coefficient_developing` An analytic approximation to this function. :func:`._worsoe_schmidt_leveque_type` The underlying function for vanishingly small x. References ---------- .. [#Shah_interp] R.K. Shah and A.L. London, Laminar flow forced convection in ducts, A source book for compact heat exchanger analytical data, Academic Press 1978, New York, San Francisco, London, Chapter VI, Parallel plates, Section C, Page 181, Table 34 """ return np.where( x < _xstar_table34[0], _worsoe_schmidt_leveque_type(x), np.interp(x, _xstar_table34, _nuxh_table34, right=8.2353), )
[docs] def developing_laminar_h_spl( *, coolant: Liquid, mdot: KgPerS, A: Meter2, Dh: Meter, develop_length: Meter, aspect_ratio: float, **_, ) -> WPerM2K: """A :class:`~.SinglePhaseLiquidHTC` relying on A Nusselt number definition for thermally developing flow. [#Shah]_ This includes a correction for the channel being finite in size. These equations are valid for Reynolds<2100. [#TERMIC]_ References ---------- .. [#Shah] R.K. Shah and A.L. London, Laminar flow forced convection in ducts, A source book for compact heat exchanger analytical data, Academic Press 1978, New York, San Francisco, London, Chapter VI, Parallel plates, Section C, Page 181, Table 34. .. [#TERMIC] P. Abbate, TERMIC V4.1: A Program for the Thermal-Hydraulic Analysis of a MTR Core in Forced Convection, Vol 1: Models and Correlations, Rev 3, Pages 14-15, Nuclear Engineering Division, INVAP, December 2003 Parameters ---------- coolant: Liquid Properties of the coolant. mdot: KgPerS Mass flow rate. A: Meter2 Flow area. Dh: Meter Hydraulic diameter. develop_length: Meter Distance from channel entrance. aspect_ratio: float in [0,1] The aspect ratio of the channel. Returns ------- Watts per Meter squared degrees Kelvin Heat transfer coefficient """ re = Re_mdot(mdot=mdot, A=A, L=Dh, mu=coolant.viscosity) pr = Pr(coolant.specific_heat, coolant.viscosity, coolant.conductivity) x_star = develop_length / Dh / re / pr / (6 - 5 * np.exp(-0.75 * aspect_ratio / 0.3257)) nudev = _nusselt_coefficient_developing(x_star) nusselt = two_sided_heating_nusselt(aspect_ratio, nudev) return nusselt * coolant.conductivity / Dh