#
# Mush model of the finned-tube family
#
"""Finned-tube model that resolves the fins and the PCM between them."""
import pybamm
from ...submodels import (
DeviceEnergy,
EnthalpyStorage,
FinRootCoupling,
FinStorageCoupling,
StorageGeometry,
)
from .base_finned_tube import BaseFinnedTubeModel
[docs]
class MushModel(BaseFinnedTubeModel):
"""
Finned-tube model that resolves the fins and the PCM separately. Heat flows from the
tube wall along annular fins ("storage depth") and from the fins into the PCM between
them ("fin gap"), at each point along the tube.
The PCM only exchanges heat with the fins: it does not touch the tube wall, and heat
flows through it only across the gap between two fins (in ``x``), not radially or along
the tube. By symmetry, only half the gap is modelled, from the fin surface
(``x = d_c / 2``) to the midplane (``x = d_m / 2``). The PCM uses the properties of the
PCM on its own (:class:`pytes.materials.PureMaterial`).
Submodels:
- "fluid": :class:`pytes.submodels.AdvectedFluid`;
- "storage": :class:`pytes.submodels.EnthalpyStorage` of the PCM across the half-gap
(cartesian);
- "fins": :class:`pytes.submodels.EnthalpyStorage` of the fin metal, radially along
the fins (cylindrical);
- "coupling": :class:`pytes.submodels.FinRootCoupling`, the fluid and the fin roots;
- "fin-PCM coupling": :class:`pytes.submodels.FinStorageCoupling`;
- "device energy": :class:`pytes.submodels.DeviceEnergy`.
Parameters
----------
name : str, optional
The name of the model.
options : dict, optional
The model's options; see :class:`BaseFinnedTubeModel`.
Attributes
----------
x : pybamm.SpatialVariable
Distance from the fin centreline [m], from half the fin thickness to half the fin
pitch, in the "fin gap" domain.
"""
def __init__(self, name="Mush model", options=None):
super().__init__(name=name, options=options)
[docs]
def set_spatial_variables(self):
super().set_spatial_variables()
self.x = pybamm.SpatialVariable(
"x",
domains=self.storage_domains("fin gap", "storage depth"),
coord_sys="cartesian",
)
[docs]
def set_submodels(self):
param = self.param
x, y = self.x, self.y
# The PCM between two fins spans x in [d_c / 2, d_m / 2] (by symmetry), so
# integrating over x and multiplying by 2 / d_m gives the PCM per unit length of
# the fin pitch
def integrate_pcm(symbol):
return param.N_tubes * self.integrate_over_tube(
2 / param.d_m * pybamm.Integral(symbol, x)
)
def pcm_cross_section(symbol):
return pybamm.Integral(2 / param.d_m * pybamm.Integral(symbol, x), y)
# The fins take up a fraction delta of the annulus
def integrate_fin(symbol):
return param.N_tubes * self.integrate_over_tube(param.delta * symbol)
def fin_cross_section(symbol):
return pybamm.Integral(param.delta * symbol, y)
fluid = self.fluid_submodel()
# When averaged, the fin-PCM unit is averaged along the tube: the fins and the PCM
# stay separate submodels, and only the fins exchange heat with the fluid
pcm_geometry = StorageGeometry(x, integrate_pcm, pcm_cross_section)
pcm = EnthalpyStorage(
param, param.pcm, pcm_geometry, inner_condition="temperature"
)
fin_geometry = StorageGeometry(
y, integrate_fin, fin_cross_section, flow_path=self.storage_flow_path()
)
# The fin metal is a sensible material, its enthalpy scaled like the temperatures
fins = EnthalpyStorage(
param,
param.metal,
fin_geometry,
label="Fin",
heat_source=True,
H_scale=param.metal.rho_c_p * param.temperature_scale,
H_reference=param.metal.T2H(param.temperature_reference),
)
self.submodels["fluid"] = fluid
self.submodels["storage"] = pcm
self.submodels["fins"] = fins
self.submodels["coupling"] = FinRootCoupling(
param, param.fluid, fins.label, fin_geometry, flux_law=self.flux_law()
)
self.submodels["fin-PCM coupling"] = FinStorageCoupling(
param, pcm.label, pcm_geometry, fins.label
)
self.submodels["device energy"] = DeviceEnergy(param, fluid, [pcm, fins])
@property
def default_geometry(self):
"""
That of :class:`BaseFinnedTubeModel`, plus the half-gap between two fins (``x``
from half the fin thickness to half the fin pitch)
"""
geometry = super().default_geometry
geometry["fin gap"] = {
self.x: {"min": self.param.d_c / 2, "max": self.param.d_m / 2}
}
return geometry
@property
def default_var_pts(self):
"""
Number of mesh points in each spatial variable. 10 points in ``x`` change the
outlet temperature by about 0.02 K and are about 4 times faster. Along the tube,
against 80 points, 20 give 0.061 K on average in the outlet temperature and 0.11 %
in the stored energy for the default discharge (F-052)
"""
return {self.x: 20, self.y: 20, self.z: 20}