Submodels#

Submodels: the fluid, storage and coupling slots, the device-level energy, and the surface flux laws of the couplings.

class pytes.submodels.AdvectedFluid(param, fluid, flow_path, name='Heat transfer fluid')[source]#

Bases: BaseSubModel

Heat transfer fluid advected along the flow path, with its specific enthalpy h as the state (DESIGN D5). Per flow path,

A_flow rho dh/dt + mdot_path dh/dz = q', for 0 < z < Z,

where mdot_path is the mass flow rate per path and q' the heat the fluid gains per unit length of flow path ("Heat transfer fluid heat gain per unit length [W.m-1]", from the coupling). The inflow is at the inlet enthalpy h(T_in), and the outlet enthalpy is the value upwinding advects out of the last cell. Temperatures and other properties come from the fluid-property object at the state: T = T(h), and the outlet temperature is T(h_out).

The enthalpy flux mdot_path h is upwinded, at second order with the default spatial method (pytes.compat.fluid_spatial_method(), F-052). The inflow uses pytes.compat.upwind_inlet_value().

It also provides the flow as it is usually measured (issue #14): the volume flow rate of the whole device at the inlet density, mdot / rho(h_in), and its time integral, the pumped volume (a solver state, zero at the start); the mean velocity along the flow path, mdot_path / (A_flow rho(h)) (in a packed bed, the interstitial velocity); and the inlet-outlet temperature difference, T_in - T_out.

Parameters:
  • param (object) – The model’s parameters. Uses T_in (inlet temperature), mdot (mass flow rate of the whole device), T_ref, temperature_scale and temperature_reference (to scale the enthalpy like a temperature).

  • fluid (pytes.fluids.ConstantPropertyLiquid) – The fluid-property object.

  • flow_path (FlowPath) – The geometry of the flow paths.

energy_variable = 'Heat transfer fluid thermal energy [J]'#

Name of this submodel’s energy variable (see DeviceEnergy)

build()[source]#

Set the variables, equations and conditions of the submodel

uniform_energy(T)[source]#

Energy of the fluid in the whole device [J] at a uniform temperature T [K], relative to the fluid’s enthalpy reference.

class pytes.submodels.BaseSubModel(param, name=None)[source]#

Bases: BaseModel

A part of a model, with its inputs and outputs readable from the code.

Subclasses implement build(), which sets variables, rhs, algebraic, boundary_conditions, initial_conditions and events. A variable set by another submodel is read with coupled(), never by reaching into that submodel.

Besides the attributes below, the metadata is read from the code (DESIGN D3): requires, provides and parameters.

Parameters:
  • param (object) – The model’s parameters.

  • name (str, optional) – Name of the submodel.

Variables:
  • param (object) – The model’s parameters.

  • coupled_variables (dict) – The pybamm.CoupledVariable objects created by coupled(), by name (PyBaMM’s own record of the variables a model needs from other models).

  • assumptions (tuple of str) – Modelling assumptions, in a sentence each (for model cards).

build()[source]#

Set the variables, equations and conditions of the submodel

coupled(name, domain=None)[source]#

A variable set by another submodel, to be resolved when the model is built.

Parameters:
  • name (str) – Name of the variable.

  • domain (str or list of str, optional) – Its primary domain. The model checks it against the variable that provides it.

Returns:

pybamm.CoupledVariable

property requires#

Names of the variables this submodel needs from other submodels

property provides#

Names of the variables this submodel sets

property parameters#

Names of the parameters this submodel uses, read from its equations, conditions, variables and the scales of its states. Domain lengths are not among them: they enter through the model’s geometry (see pytes.BaseModel.geometry_parameters).

class pytes.submodels.DeviceEnergy(param, fluid_component, storage_components, name='Device energy')[source]#

Bases: BaseSubModel

Power and energies of the whole device, and its initial state.

  • Power: mdot (h_out - h_in), positive on discharge (DESIGN D8, D12).

  • Discharged energy: the time integral of the power, solved for by the solver so that it can be checked against the change in total thermal energy. Charged energy is its opposite, the net energy put in.

  • Throughputs (issue #14): the energy delivered while discharging, the time integral of max(P, 0), and the energy put in while charging, of max(-P, 0). Both only grow, and their difference is the discharged energy; their ratio over a cycle is its round-trip efficiency.

  • Energies: the storage thermal energy is the sum of the storage components’ energies, and the total thermal energy adds the fluid. Every energy is zero at the uniform state at the reference temperature (DESIGN D14).

  • Heat loss power: zero (there is no casing yet), positive for loss.

  • Storage temperatures (issue #14): the average over all the storage components, weighted by volume, over the whole device (“Storage average temperature [K]”) and over each cross-section of the flow path (“Storage cross-section average temperature [K]”). With one storage they equal its own averages; with several (the fins and the PCM of the mush model) they compare with a model that homogenises them.

  • Initial state: uniform at “Initial temperature [K]” (DESIGN D14). Each component starts at its equilibrium state at that temperature: for a sharp melting point, solid at the melting temperature; with a melting range, partly liquid inside it.

There is no state of charge (DESIGN D13). The energy between two uniform states is post-processing: see pytes.energy_between(), which uses uniform_energy().

Parameters:
  • param (object) – The model’s parameters. Uses T_init.

  • fluid_component (pytes.submodels.AdvectedFluid) – The fluid.

  • storage_components (list) – The storage submodels. Each has a label, a storage_geometry, an energy_variable and a uniform_energy(T) method, and provides “<label> average temperature [K]” and “<label> cross-section average temperature [K]”.

property components#

All the parts that hold heat, the storage components and then the fluid

uniform_energy(T)[source]#

Total thermal energy [J] of the uniform equilibrium state at T [K]. It contains integrals over the storage, so it must be discretised before it is evaluated.

build()[source]#

Set the variables, equations and conditions of the submodel

class pytes.submodels.EnthalpyStorage(param, material, geometry, label='Phase-change material', inner_condition='heat flux', heat_source=False, H_scale=None, H_reference=None)[source]#

Bases: BaseSubModel

Conduction in a storage material, by the enthalpy method.

Enthalpy H per unit volume, with T = H2T(H, states) from the material:

  • dH/dt = div(k(H) grad T) + S in the storage, with S an optional volumetric heat source, "<label> heat source [W.m-3]", from a coupling (heat_source),

  • zero flux on the outer side (a symmetry plane),

  • on the inner side, either a heat flux into the storage, "<label> boundary heat flux [W.m-2]", or a temperature, "<label> boundary temperature [K]", from a coupling (inner_condition).

The same submodel holds phase-change and sensible materials (DESIGN D5); only the former provide liquid-fraction variables. The state list is [H] plus the material’s internal states (none for the current materials, DESIGN D7).

It also provides its conductivity, “<label> thermal conductivity [W.m-1.K-1]”, and its volume-weighted average temperatures (issue #14): over the whole storage, “<label> average temperature [K]”, and over each cross-section of the flow path, “<label> cross-section average temperature [K]”, along the flow path (e.g. across the storage depth of a finned tube, or over a capsule in a packed bed).

Ledger couplings (DESIGN D6) take the heat that crossed the storage’s boundaries from "<label> conduction heating rate [W.m-3]", div(k grad T): its integral over the storage telescopes to the discrete boundary fluxes, with or without a heat source.

Parameters:
  • param (object) – The model’s parameters. Uses T_ref (reference temperature).

  • material (pytes.materials.PhaseChangeMaterial or pytes.materials.SensibleMaterial) – The storage material.

  • geometry (StorageGeometry) – The geometry of the storage.

  • label (str, optional) – Name of the material in variable names (default “Phase-change material”), e.g. “<label> enthalpy [J.m-3]”.

  • inner_condition (str, optional) – “heat flux” (default) or “temperature”.

  • heat_source (bool, optional) – Whether the storage has a volumetric heat source (default False).

  • H_scale (pybamm.Symbol, optional) – Scale and reference of the enthalpy variable (default: the material’s).

  • H_reference (pybamm.Symbol, optional) – Scale and reference of the enthalpy variable (default: the material’s).

property states#

The state variables, the enthalpy and then the material’s internal states

build()[source]#

Set the variables, equations and conditions of the submodel

uniform_energy(T)[source]#

Energy of this storage in the whole device [J] at a uniform temperature T [K], above the uniform state at the reference temperature.

class pytes.submodels.FinRootCoupling(param, fluid, label, geometry, flux_law=None, name='Fin root coupling')[source]#

Bases: WallCoupling

Fins whose roots are on the flow path wall, exchanging heat with the fluid.

The heat the fluid exchanges over one fin pitch of wall enters through the fin root alone, so the heat flux into the fin root is d_m / d_c times the surface flux law’s flux. The heat the fluid gains is taken from the fins’ discrete energy balance, as in WallCoupling, so energy is conserved exactly.

Parameters:
class pytes.submodels.FinStorageCoupling(param, pcm_label, pcm_geometry, fin_label='Fin', name='Fin-storage coupling')[source]#

Bases: BaseSubModel

A storage material between two fins, at the fin temperature where it touches a fin. The material may change phase or not: the coupling is the same.

The storage’s boundary temperature is the fin temperature. The heat the fin gains per unit fin volume is minus the heat the storage on both sides gains through the fin face, computed from the storage’s own discrete energy balance: -(2 / d_c) times the integral of its conduction heating rate across the half-gap (the flux at the midplane is zero). This telescopes to the discrete flux at the fin face, so energy is conserved exactly.

Parameters:
build()[source]#

Set the variables, equations and conditions of the submodel

class pytes.submodels.FlowPath(z, length, area, n_paths)[source]#

Bases: object

Geometry of the flow paths, as the fluid submodel sees it.

The device has n_paths identical flow paths in parallel, each of length length and flow area area. The fluid submodel describes one of them, on the domain "flow path" with coordinate z (DESIGN D12). Device totals are multiplied by n_paths.

Parameters:
class pytes.submodels.FluidState(h: Symbol, T: Symbol, mass_flow_rate: Symbol, p: Symbol | None = None)[source]#

Bases: object

The fluid side of a surface, as a surface flux law sees it (DESIGN D6). New fields may be added (e.g. for a refrigerant) without breaking existing laws, which read only the fields they need.

Variables:
  • h (pybamm.Symbol) – Specific enthalpy of the fluid [J.kg-1].

  • T (pybamm.Symbol) – Temperature of the fluid [K], fluid.T(h).

  • mass_flow_rate (pybamm.Symbol) – Mass flow rate through the whole device [kg.s-1]. A law built for a family converts it to the flow it needs (per tube, per unit area) from that family’s geometry.

  • p (pybamm.Symbol or None) – Pressure [Pa]; None while the models do not compute it.

class pytes.submodels.Gnielinski(radius, n_tubes=1)[source]#

Bases: TubeCorrelation

Fully developed flow in a smooth tube: the Gnielinski correlation in turbulent flow, the laminar Nusselt number at a uniform wall temperature, 3.66, below Re = 2300, and a linear interpolation between them in the transition, as in the VDI Heat Atlas (Gnielinski, “On heat transfer in tubes”, International Journal of Heat and Mass Transfer 63, 2013):

  • Nu = 3.66 for Re <= 2300;

  • Nu = (1 - g) 3.66 + g Nu_t(10^4), g = (Re - 2300) / (10^4 - 2300), for 2300 < Re < 10^4;

  • Nu = Nu_t(Re) for Re >= 10^4, with Nu_t = (f / 8) (Re - 1000) Pr / (1 + 12.7 sqrt(f / 8) (Pr^(2/3) - 1)) and the friction factor f = (0.79 ln(Re) - 1.64)^-2.

The entrance region and the variation of the properties between the bulk and the wall are neglected. The Nusselt number is continuous in Re; its slope is not, at Re = 2300 and 10^4. Registered as “Gnielinski” for the flow "tube".

nusselt_laminar = 3.66#

Laminar Nusselt number, fully developed flow at a uniform wall temperature

reynolds_transition = (2300, 10000.0)#

Reynolds numbers at which the transition starts and ends

nusselt_turbulent(Re, Pr)[source]#

The Gnielinski correlation, for Re >= 10^4

nusselt(Re, Pr)[source]#

The Nusselt number from the Reynolds and Prandtl numbers

class pytes.submodels.HeatTransferCoefficientOptions(flow)[source]#

Bases: Sequence

The values of a model’s “heat transfer coefficient” option: “constant”, then the names of the correlations registered for its flow geometry. They are read from CORRELATIONS when used, so a correlation registered after the model class was defined is allowed.

Parameters:

flow (str) – The flow geometry, "tube" or "packed bed".

flux_law(value, *geometry)[source]#

The surface flux law an option value selects.

Parameters:
  • value (str) – The option value, “constant” or a registered correlation.

  • *geometry (pybamm.Symbol) – The family’s geometry, passed to the correlation’s constructor.

Returns:

SurfaceFluxLaw

class pytes.submodels.Jeffreson(law, radius, conductivity, domain=None)[source]#

Bases: SurfaceFluxLaw

Newton’s law of cooling for a lumped sphere, with Jeffreson’s correction for the conduction resistance inside it (issue #5): the heat flux into the sphere is h_eff (T_f - T_s), with T_s the sphere’s (uniform) temperature and

1 / h_eff = 1 / h + R / (5 k), that is h_eff = h / (1 + Bi / 5), Bi = h R / k,

where h is the heat transfer coefficient of the law it corrects, R the sphere’s radius and k its conductivity (Jeffreson, “Prediction of breakthrough curves in packed beds: 1. Applicability of single parameter models”, AIChE Journal 18, 1972). The correction is exact for the slow variation of a sensible sphere; while a PCM melts or freezes inside the sphere it is an approximation, with k the conductivity at the sphere’s mean enthalpy.

Parameters:
  • law (NewtonCooling) – The law it corrects, which gives h (a constant coefficient or a Nusselt correlation).

  • radius (pybamm.Symbol) – The sphere’s radius R [m].

  • conductivity (str) – Name of the variable holding the sphere’s conductivity [W.m-1.K-1], e.g. “Phase-change material thermal conductivity [W.m-1.K-1]” from a pytes.submodels.LumpedStorage.

  • domain (str or list of str, optional) – Primary domain of that variable (default: none).

Raises:

TypeError – If law is not a NewtonCooling.

biot(fluid, fluid_state)[source]#

The Biot number of the sphere, h R / k

heat_transfer_coefficient(fluid, fluid_state)[source]#

The corrected coefficient h_eff [W.m-2.K-1]

heat_flux(fluid, fluid_state, T_s)[source]#

Heat flux [W.m-2] from the fluid into the storage surface.

Parameters:
  • fluid (object) – The fluid-property object, for properties at the fluid state.

  • fluid_state (FluidState) – The fluid’s state at the surface.

  • T_s (pybamm.Symbol) – Temperature of the storage surface [K].

Returns:

pybamm.Symbol – The heat flux, positive into the storage.

variables(fluid, fluid_state)[source]#

Those of the law it corrects, plus “Effective heat transfer coefficient [W.m-2.K-1]” and “Surface Biot number”

class pytes.submodels.LumpedGeometry(integrate, cross_section_integral, surface_to_volume, flow_path, averaged=False)[source]#

Bases: object

Geometry of a lumped storage: each storage element (e.g. a capsule) has a uniform temperature, so the storage has no spatial variable of its own (issue #5). It lives on the flow path, or nowhere when it is averaged along the flow path too.

Parameters:
  • integrate (callable) – Maps a symbol on the storage domains to its integral over the storage in the whole device [symbol units times m3].

  • cross_section_integral (callable) – Maps a symbol on the storage domains to its integral over the storage per unit length of flow path, for one flow path [symbol units times m2]. Used by ledger couplings.

  • surface_to_volume (pybamm.Symbol) – Surface area of a storage element over its volume [m-1], e.g. 3 / R for a sphere of radius R.

  • flow_path (pytes.submodels.FlowPath) – The flow path.

  • averaged (bool, optional) – Whether the storage is also averaged along the flow path ("storage along flow path": "averaged", DESIGN D4; default False): one element then stands for all of them, exchanging heat with the fluid averaged along the flow path.

property averaged#

Whether the storage is averaged along the flow path

property primary_domain#

the flow path, or none when averaged

Type:

The domain of the storage variables

property boundary_domain#

The domain of quantities on the element surface, that of the storage

property volume#

Volume of the storage in the whole device [m3]

property cross_section_volume#

Volume of the storage per unit length of flow path, for one flow path [m2]

class pytes.submodels.LumpedStorage(param, material, geometry, label='Phase-change material', H_scale=None, H_reference=None)[source]#

Bases: EnthalpyStorage

A storage whose elements each have a uniform temperature (a lumped capacitance, issue #5), by the enthalpy method.

Enthalpy H per unit volume, one value per element, with T = H2T(H, states) from the material: dH/dt = (S / V) q, with q the heat flux into an element through its surface, "<label> boundary heat flux [W.m-2]", from a coupling, and S / V the element’s surface area over its volume.

It provides the same variables as EnthalpyStorage, so that the couplings and the device energy work on either. Its “conduction heating rate” is (S / V) q, the volume average of div(k grad T) over an element, so a ledger coupling (DESIGN D6) takes exactly the heat the storage gains. The surface temperature is the element’s temperature. A surface flux law may use its conductivity, “<label> thermal conductivity [W.m-1.K-1]”, to correct for the conduction inside the element (e.g. pytes.submodels.Jeffreson).

Parameters:
  • param (object) – The model’s parameters. Uses T_ref (reference temperature).

  • material (pytes.materials.PhaseChangeMaterial or pytes.materials.SensibleMaterial) – The storage material.

  • geometry (LumpedGeometry) – The geometry of the storage.

  • label (str, optional) – Name of the material in variable names (default “Phase-change material”).

  • H_scale (pybamm.Symbol, optional) – Scale and reference of the enthalpy variable (default: the material’s).

  • H_reference (pybamm.Symbol, optional) – Scale and reference of the enthalpy variable (default: the material’s).

build()[source]#

Set the variables, equations and conditions of the submodel

class pytes.submodels.NewtonCooling(name='Heat transfer coefficient [W.m-2.K-1]', flow=None)[source]#

Bases: SurfaceFluxLaw

Newton’s law of cooling, h (T_f - T_s), with a constant heat transfer coefficient h.

Parameters:
  • name (str, optional) – Name of the coefficient parameter (default “Heat transfer coefficient [W.m-2.K-1]”).

  • flow (NusseltCorrelation, optional) – The flow geometry (e.g. a TubeCorrelation), for reporting the surface Reynolds and Prandtl numbers only (issue #14); it does not change the coefficient.

Variables:

coefficient (pybamm.Parameter) – The heat transfer coefficient [W.m-2.K-1].

flow = None#

The flow geometry for reporting, or None

heat_transfer_coefficient(fluid, fluid_state)[source]#

The heat transfer coefficient [W.m-2.K-1] at the fluid state.

Parameters:
  • fluid (object) – The fluid-property object.

  • fluid_state (FluidState) – The fluid’s state at the surface.

heat_flux(fluid, fluid_state, T_s)[source]#

Heat flux [W.m-2] from the fluid into the storage surface.

Parameters:
  • fluid (object) – The fluid-property object, for properties at the fluid state.

  • fluid_state (FluidState) – The fluid’s state at the surface.

  • T_s (pybamm.Symbol) – Temperature of the storage surface [K].

Returns:

pybamm.Symbol – The heat flux, positive into the storage.

variables(fluid, fluid_state)[source]#

The heat transfer coefficient, as “Heat transfer coefficient [W.m-2.K-1]”, and, given a flow geometry, the “Surface Reynolds number” and “Surface Prandtl number”

class pytes.submodels.NusseltCorrelation(length, area, n_paths=1)[source]#

Bases: NewtonCooling

Newton’s law of cooling with a heat transfer coefficient from a Nusselt number correlation, h = Nu k / L, with Nu a function of the Reynolds and Prandtl numbers (issue #6):

Re = mdot_path L / (A mu), Pr = mu c_p / k,

where mdot_path is the mass flow rate per flow path, L the characteristic length of the correlation, A the area its velocity is based on, and the properties mu, c_p and k come from the fluid-property object at the fluid state. The flow may run either way: the Reynolds number uses the flow’s magnitude.

Subclasses implement nusselt(). The correlation’s constants are part of it, so a correlation has no parameters of its own: the geometry comes from the family, through the constructor.

Parameters:
  • length (pybamm.Symbol) – The characteristic length L [m] (a hydraulic or particle diameter).

  • area (pybamm.Symbol) – The area A [m2] the velocity is based on, per flow path.

  • n_paths (pybamm.Symbol or float, optional) – Number of flow paths sharing the device’s mass flow rate (default 1).

reynolds(fluid, fluid_state)[source]#

The Reynolds number at the fluid state

prandtl(fluid, fluid_state)[source]#

The Prandtl number at the fluid state

nusselt(Re, Pr)[source]#

The Nusselt number from the Reynolds and Prandtl numbers

heat_transfer_coefficient(fluid, fluid_state)[source]#

The heat transfer coefficient [W.m-2.K-1] at the fluid state.

Parameters:
  • fluid (object) – The fluid-property object.

  • fluid_state (FluidState) – The fluid’s state at the surface.

variables(fluid, fluid_state)[source]#

The heat transfer coefficient, and the Reynolds, Prandtl and Nusselt numbers of the surface

class pytes.submodels.PackedBedCorrelation(radius, bed_area)[source]#

Bases: NusseltCorrelation

A Nusselt correlation for the flow through a packed bed (flow "packed bed", the packed-bed model): the characteristic length is the particle diameter and the velocity the superficial velocity, the mass flow rate over the whole bed cross-section. Subclasses implement nusselt().

Parameters:
  • radius (pybamm.Symbol) – The particle radius [m].

  • bed_area (pybamm.Symbol) – The bed cross-sectional area [m2], porosity not removed.

class pytes.submodels.PerAreaTotals(param, area, totals=('Power [W]', 'Discharged energy [J]', 'Storage thermal energy [J]', 'Total thermal energy [J]'), name='Per-area totals')[source]#

Bases: BaseSubModel

Device totals per unit of a reference area, as family-specific twins of the shared whole-device outputs (DESIGN D4): for each total "<name> [<unit>]", the variable "<name> per unit area [<unit>.m-2]".

Parameters:
  • param (object) – The model’s parameters.

  • area (pybamm.Symbol) – The reference area [m2], e.g. a bed cross-section.

  • totals (iterable of str, optional) – Names of the totals, each ending in “[W]” or “[J]” (default: power, discharged energy, storage and total thermal energy).

build()[source]#

Set the variables, equations and conditions of the submodel

class pytes.submodels.StorageGeometry(variable, integrate, cross_section_integral, inner='left', flow_path=None)[source]#

Bases: object

Geometry of a storage region.

The storage conducts heat along its primary spatial variable only. Its coordinate system (cartesian, cylindrical or spherical) is the geometry switch of DESIGN D5: the equations are the same, and only the geometric factor in the divergence changes.

Parameters:
  • variable (pybamm.SpatialVariable) – The primary spatial variable. Its domains are those of the storage variables.

  • integrate (callable) – Maps a symbol on the storage domains to its integral over the storage in the whole device [symbol units times m3].

  • cross_section_integral (callable) – Maps a symbol on the storage domains to its integral over the storage per unit length of flow path, for one flow path [symbol units times m2]. Used by ledger couplings.

  • inner (str, optional) – Side of the primary domain that exchanges heat (“left” or “right”, default “left”). The other side is a symmetry plane (zero flux).

  • flow_path (pytes.submodels.FlowPath, optional) – Given for a storage averaged along the flow path ("storage along flow path": "averaged", DESIGN D4): one storage cross-section stands for all of them, exchanging heat with the fluid averaged along the flow path. Its domains then exclude the flow path, and integrate multiplies by the flow path length.

property averaged#

Whether the storage is averaged along the flow path

property primary_domain#

The primary domain of the storage variables

property boundary_domain#

The primary domain of quantities on the inner boundary (the secondary domain)

property volume#

Volume of the storage in the whole device [m3]

property cross_section_volume#

Volume of the storage per unit length of flow path, for one flow path [m2]

gradient_from_heat_flux(heat_flux, k)[source]#

Normal gradient condition for a heat flux heat_flux [W.m-2] into the storage through the inner side, with conductivity k [W.m-1.K-1] there: -k dT/dn equals the flux, with n pointing into the storage.

class pytes.submodels.SurfaceFluxLaw[source]#

Bases: object

Base class of the surface flux laws.

Subclasses implement heat_flux(). Geometry a law needs (e.g. a hydraulic diameter, for a correlation) is passed to its constructor by the family; the fluid’s state, flow included, comes with each call as a FluidState. A law that needs a variable of another submodel (e.g. the storage conductivity, for Jeffreson) reads it as a pybamm.CoupledVariable listed in coupled_variables, which the coupling declares as its own requirements, so the model’s wiring checks see it.

Variables:

coupled_variables (dict) – The pybamm.CoupledVariable objects the law reads, by name (none by default).

heat_flux(fluid, fluid_state, T_s)[source]#

Heat flux [W.m-2] from the fluid into the storage surface.

Parameters:
  • fluid (object) – The fluid-property object, for properties at the fluid state.

  • fluid_state (FluidState) – The fluid’s state at the surface.

  • T_s (pybamm.Symbol) – Temperature of the storage surface [K].

Returns:

pybamm.Symbol – The heat flux, positive into the storage.

variables(fluid, fluid_state)[source]#

Variables the law adds to the coupling’s (e.g. its heat transfer coefficient), by name; none by default.

class pytes.submodels.TubeCorrelation(radius, n_tubes=1)[source]#

Bases: NusseltCorrelation

A Nusselt correlation for the flow inside tubes (flow "tube", the finned-tube models): the characteristic length is the tube diameter and the velocity the mean velocity in a tube. Subclasses implement nusselt().

Parameters:
  • radius (pybamm.Symbol) – The tube radius [m].

  • n_tubes (pybamm.Symbol or float, optional) – Number of tubes sharing the device’s mass flow rate (default 1).

class pytes.submodels.WakaoKaguei(radius, bed_area)[source]#

Bases: PackedBedCorrelation

Fluid to particle heat transfer in a packed bed: the correlation of Wakao, Kaguei and Funazkri (Chemical Engineering Science 34, 1979, 325-336), Nu = 2 + 1.1 Re^0.6 Pr^(1/3), with the particle diameter as the characteristic length and the superficial velocity in the Reynolds number. Fitted for 15 < Re < 8500. Registered as “Wakao-Kaguei” for the flow "packed bed".

nusselt(Re, Pr)[source]#

The Nusselt number from the Reynolds and Prandtl numbers

class pytes.submodels.WallCoupling(param, fluid, label, geometry, flux_law=None, flux_factor=1, name='Wall coupling')[source]#

Bases: BaseSubModel

A storage in direct contact with the flow path wall, exchanging heat with the fluid.

The heat flux into the storage is flux_factor times the surface flux law’s flux from the fluid state and the storage surface temperature T_s (by default h (T_f - T_s)). The heat the fluid gains is the heat the storage loses through its boundaries, computed from the storage’s own discrete energy balance: minus the integral of its conduction heating rate over the storage cross-section (the ledger, DESIGN D6). This telescopes to the discrete flux at the wall, so energy is conserved exactly, whatever the flux law or the conductivity. It is also the flux times the wall area: the storage’s wall condition uses the conductivity on the wall face, as its conduction does (F-056).

The coupling also provides the flux law’s own variables (e.g. “Heat transfer coefficient [W.m-2.K-1]”, see pytes.submodels.SurfaceFluxLaw.variables()), and requires the variables the law reads (pytes.submodels.SurfaceFluxLaw.coupled_variables).

For a storage averaged along the flow path (geometry.averaged), the flux law sees the fluid state averaged along the flow path, and the heat the fluid gains is spread uniformly along it; energy stays exact, as the storage integrates over the flow path length.

Parameters:
build()[source]#

Set the variables, equations and conditions of the submodel

pytes.submodels.register_correlation(name, nusselt, flow, replace=False)[source]#

Register a Nusselt correlation, so that the models of its flow geometry accept its name as a value of the “heat transfer coefficient” option.

The family supplies the geometry (see TubeCorrelation and PackedBedCorrelation) and the fluid-property object the properties, so a correlation is only its Nusselt number. Energy is conserved whatever the correlation (DESIGN D6); pytes.conformance.check_model() checks a model that uses it.

Parameters:
  • name (str) – The name of the correlation, the option value that selects it.

  • nusselt (callable or type) – A function nusselt(Re, Pr) of the Reynolds and Prandtl numbers, as PyBaMM symbols (so use pybamm.log, pybamm.sqrt, etc.), returning the Nusselt number; or a subclass of the flow’s correlation class implementing NusseltCorrelation.nusselt().

  • flow (str) – The flow geometry: "tube" (the finned-tube models) or "packed bed" (the packed-bed model).

  • replace (bool, optional) – Whether to replace a correlation registered earlier under the same name, e.g. when a notebook cell runs again (default False). A correlation shipped with PyTES cannot be replaced.

Returns:

type – The correlation class, a subclass of the flow’s correlation class.

Raises:
  • ValueError – If the flow is unknown, or the name is not a non-empty string, is “constant”, is a built-in correlation, or is already registered and replace is False.

  • TypeError – If nusselt is neither callable nor a subclass of the flow’s correlation class.

Examples

>>> import pytes
>>> pytes.submodels.register_correlation(
...     "Dittus-Boelter", lambda Re, Pr: 0.023 * Re**0.8 * Pr**0.4, flow="tube"
... )
>>> model = pytes.SharpFrontModel(
...     options={"heat transfer coefficient": "Dittus-Boelter"}
... )