Thermal#

注釈

The heat flux is positive when heat leaves a solid body, and negative when heat enters a solid body.

Solid Bodies

thermal.SolidBodyThermal(field, ...[, ...])

A thermal solid body.

thermal.SolidBodySurfaceHeatTransfer(field, ...)

A surface boundary condition for a thermal solid body.

thermal.SolidBodySurfaceRadiation(field, ...)

Radiative heat transfer on the surface of a thermal solid body.

thermal.SolidBodyHeatFlux(field[, heat_flux])

A thermal heat flux boundary condition for a thermal solid body.

Helpers

thermal.TimeStep(items[, time_old, time_new])

A time step item.

Detailed API Reference

class felupe.thermal.SolidBodyThermal(field, mass_density, specific_heat_capacity, thermal_conductivity, time_step=None, model=None, lumped_capacity=True)[ソース]#

ベースクラス: SolidBody

A thermal solid body.

パラメータ:
  • field (felupe.FieldContainer) -- The field container containing the temperature field.

  • mass_density (float) -- The mass density \(\rho\) of the material.

  • specific_heat_capacity (float) -- The specific heat capacity \(c_p\) of the material.

  • thermal_conductivity (float) -- The thermal conductivity \(k\) of the material.

  • time_step (float or None, optional) -- The time step \(\Delta t\) If None, the stationary solution will be calculated. If a float is provided, an implicit time integration scheme will be used. Default is None.

  • model (None or felupe.Laplace, optional) -- A model for the thermal conductivity. Default is None, which defaults to Laplace.

  • lumped_capacity (bool, optional) -- A flag to use a lumped instead of a consistent capacity matrix (default is True).

メモ

This class represents a thermal solid body, which is used to model heat conduction in a solid material. The thermal conductivity is modeled using the specified model, which defaults to the Laplace model. The time step is used to update the temperature field at each time step, and the capacity matrix is assembled based on the mass density and specific heat capacity of the material.

An implicit time integration scheme is used, where the stiffness matrix is updated at each time step to include the contribution from the capacity matrix. The force vector is also updated to include the contribution from the temperature rate, which is calculated as the difference between the new temperature and the old temperature divided by the time step, see Eq. (1).

(1)#\[ \begin{align}\begin{aligned}\boldsymbol{r} + \frac{\partial \boldsymbol{r}}{\partial \boldsymbol{T}} \delta \boldsymbol {T} = \boldsymbol{0}\\\boldsymbol{K} \delta \boldsymbol{T} &= -\boldsymbol{r}\\\boldsymbol{r} &= \boldsymbol{r}_{\text{conductivity}} + \boldsymbol{C} \frac{\boldsymbol{T} - \boldsymbol{T}_n}{\Delta t}\\\boldsymbol{K} &= \boldsymbol{K}_{\text{conductivity}} + \frac{\boldsymbol{C}}{\Delta t}\end{aligned}\end{align} \]

サンプル

>>> import felupe as fem
>>> import numpy as np
>>>
>>> mesh = fem.Rectangle(n=11)
>>> region = fem.RegionQuad(mesh)
>>> temperature = fem.Field(region, dim=1)
>>> field = fem.FieldContainer([temperature])
>>>
>>> boundaries = fem.BoundaryDict(
...     left=fem.Boundary(temperature, fx=0),
...     right=fem.Boundary(temperature, fx=1),
... )
>>>
>>> solid = fem.thermal.SolidBodyThermal(
...     field=field,
...     mass_density=1.0,  # kg/m^3
...     specific_heat_capacity=1.0,  # J / (kg K)
...     time_step=0.01,  # s
...     thermal_conductivity=1.0,  # W / (m K)
... )
>>> time = fem.thermal.TimeStep([solid])
>>> table = fem.math.linsteps([0, 1], num=10)
>>> ramp = {boundaries["right"]: 10 * table, time: 0.1 * table}
>>> step = fem.Step(items=[time, solid], ramp=ramp, boundaries=boundaries)
>>> job = fem.Job(steps=[step]).evaluate(
...     filename="result.xdmf",  # result file for Paraview
...     point_data={"Temperature": lambda field, substep: temperature.values},
...     point_data_default=False,
...     cell_data_default=False,
... )
>>>
>>> mesh.view(
...     point_data={"Temperature in °C": temperature.values}
... ).plot("Temperature in °C").show()
../_images/thermal-e3eeb9df40e1af7d_00_00.png
>>>
>>> mesh.view(
...     cell_data={"Heat Flux": solid.results.heat_flux[0][0].mean(axis=-2).T}
... ).plot("Heat Flux", component=0).show()
../_images/thermal-e3eeb9df40e1af7d_01_00.png
>>>
>>> flux = solid.heat_flux_boundary(
...     region=fem.RegionQuadBoundary(mesh, mask=mesh.x == 1.0),
...     integrate=True,
...     mean=True,
... )
>>> assert np.isclose(flux.round(1), -30.5)

参考

felupe.thermal.TimeStep

A time step item.

felupe.thermal.SolidBodySurfaceHeatTransfer

A surface heat transfer boundary condition.

felupe.thermal.SolidBodySurfaceRadiation

A thermal radiation boundary condition.

felupe.thermal.SolidBodyHeatFlux

A thermal heat flux boundary condition.

heat_flux(field=None, **kwargs)[ソース]#
heat_flux_boundary(field=None, region=None, integrate=True, mean=True, **kwargs)[ソース]#

Calculate the heat flux or the integrated heat transfer rate on a boundary region.

パラメータ:
  • field (felupe.FieldContainer or None, optional) -- The field container with the temperature field as first field on which to calculate the heat flux. If None, a field will be created on the provided region and linked to the body's field (default is None).

  • region (felupe.RegionBoundary or None, optional) -- The boundary region on which to calculate the heat flux. If None, the heat flux will be calculated on the provided field's region (default is None).

  • integrate (bool, optional) -- If True, evaluate the integrated heat transfer rate. Note that if mean is also True, the mean heat flux over the boundary is returned. If mean is False, the integrated heat transfer rate is returned. Default is True.

  • mean (bool, optional) -- If True, return the mean heat flux over the boundary. If integrate is also True, the mean heat flux is calculated as the integrated heat transfer rate divided by the total area of the boundary. If integrate is False, the mean heat flux is calculated as the heat transfer rate per cell, divided by the area per cell. Default is True.

  • **kwargs -- Additional keyword arguments to be passed to the gradient function.

戻り値:

heat_flux -- The heat flux or heat transfer rate on the boundary.

戻り値の型:

numpy.ndarray or float

class felupe.thermal.SolidBodySurfaceHeatTransfer(field, coefficient, temperature)[ソース]#

ベースクラス: object

A surface boundary condition for a thermal solid body.

パラメータ:
  • field (felupe.FieldContainer) -- The field container with the temperature as first field.

  • coefficient (float) -- The convection coefficient \(h\) in W/(m^2 K).

  • temperature (float) -- The ambient temperature \(T_\infty\) in °C.

メモ

This class represents a boundary condition for a thermal solid body, which is used to model heat transfer (convection, radiation) at the boundary of a solid material. The coefficient is used to calculate the heat flux at the boundary based on the difference between the temperature at the boundary and the ambient temperature.

サンプル

>>> import felupe as fem
>>> import numpy as np
>>>
>>> mesh = fem.Rectangle(n=11)
>>> region = fem.RegionQuad(mesh)
>>> temperature = fem.Field(region, dim=1)
>>> field = fem.FieldContainer([temperature])
>>>
>>> region_heat_transfer = fem.RegionQuadBoundary(mesh, mask=mesh.x == 1.0)
>>> temperature_heat_transfer = fem.Field(region_heat_transfer, dim=1)
>>> field_heat_transfer = fem.FieldContainer([temperature_heat_transfer])
>>>
>>> boundaries = fem.BoundaryDict(
...     left=fem.Boundary(temperature, fx=0),
... )
>>>
>>> solid = fem.thermal.SolidBodyThermal(
...     field=field,
...     mass_density=1400.0,  # kg/m^3
...     specific_heat_capacity=1000.0,  # J/(kg*K)
...     time_step=720.0,  # s
...     thermal_conductivity=1.0,  # W/(m*K)
... )
>>> heat_transfer = fem.thermal.SolidBodySurfaceHeatTransfer(
...     field=field_heat_transfer,
...     coefficient=7.69,  # W/(m^2 K)
...     temperature=10.0,  # °C
... )
>>> time = fem.thermal.TimeStep([solid])
>>> table = fem.math.linsteps([0, 1], num=15)
>>> air_temperature = fem.math.linsteps([0, 40], num=15)  # air temperature
>>> coefficient = fem.math.linsteps([7.0, 8.0], num=15)  # heat transfer coeff.
>>> ramp = {
...     boundaries["left"]: 10 * table,  # surface temperature
...     time: 18000 * table,  # five hours
...     heat_transfer["temperature"]: air_temperature,
...     heat_transfer["coefficient"]: coefficient,
... }
>>> step = fem.Step(
...     items=[time, solid, heat_transfer], ramp=ramp, boundaries=boundaries
... )
>>> job = fem.Job(steps=[step]).evaluate()
>>>
>>> mesh.view(
...     point_data={"Temperature in °C": temperature.values}
... ).plot("Temperature in °C").show()
../_images/thermal-3f185f3284ee913f_00_00.png

参考

felupe.thermal.TimeStep

A time step item.

felupe.thermal.SolidBodyThermal

A thermal solid body for heat conduction.

update(temperature)[ソース]#
class felupe.thermal.SolidBodySurfaceRadiation(field, emissivity, temperature)[ソース]#

ベースクラス: object

Radiative heat transfer on the surface of a thermal solid body.

パラメータ:
  • field (felupe.FieldContainer) -- Field container with the temperature as first field.

  • emissivity (float) -- Emissivity \(\varepsilon\) of the surface (dimensionless, \(0 \le \varepsilon \le 1\)).

  • temperature (float) -- The ambient temperature \(T_\infty\) in °C.

メモ

This class represents a boundary condition for a thermal solid body, which is used to model radiative heat transfer at the boundary of a solid material. The emissivity is used to calculate the heat flux at the boundary based on the difference between the temperature at the boundary and the ambient temperature.

サンプル

>>> import felupe as fem
>>> import numpy as np
>>>
>>> mesh = fem.Rectangle(n=11)
>>> region = fem.RegionQuad(mesh)
>>> temperature = fem.Field(region, dim=1, values=20.0)
>>> field = fem.FieldContainer([temperature])
>>>
>>> region_radiation = fem.RegionQuadBoundary(mesh, mask=mesh.x == 1.0)
>>> temperature_radiation = fem.Field(region_radiation, dim=1)
>>> field_radiation = fem.FieldContainer([temperature_radiation])
>>>
>>> boundaries = fem.BoundaryDict(
...     left=fem.Boundary(temperature, fx=0, value=20.0),
... )
>>>
>>> solid = fem.thermal.SolidBodyThermal(
...     field=field,
...     mass_density=1400.0,  # kg / m^3
...     specific_heat_capacity=1000.0,  # J / (kg K)
...     time_step=720.0,  # s
...     thermal_conductivity=1.0,  # W / (m K)
... )
>>> radiation = fem.thermal.SolidBodySurfaceRadiation(
...     field=field_radiation,
...     emissivity=0.8,
...     temperature=20.0,  # °C
... )
>>> time = fem.thermal.TimeStep([solid])
>>> table = fem.math.linsteps([0, 1], num=15)
>>> air_temperature = fem.math.linsteps([20, 40], num=15)  # air temperature
>>> emissivity = fem.math.linsteps([0.6, 0.8], num=15)  # a value between 0 ... 1
>>> ramp = {
...     time: 18000 * table,  # five hours
...     radiation["temperature"]: air_temperature,
...     radiation["emissivity"]: emissivity,
... }
>>> step = fem.Step(
...     items=[time, solid, radiation], ramp=ramp, boundaries=boundaries
... )
>>> job = fem.Job(steps=[step]).evaluate()
>>>
>>> mesh.view(
...     point_data={"Temperature in °C": temperature.values}
... ).plot("Temperature in °C").show()
../_images/thermal-d03b2ad4db3aec41_00_00.png

参考

felupe.thermal.TimeStep

A time step item.

felupe.thermal.SolidBodyThermal

A thermal solid body for heat conduction.

update(temperature)[ソース]#
class felupe.thermal.SolidBodyHeatFlux(field, heat_flux=None)[ソース]#

ベースクラス: object

A thermal heat flux boundary condition for a thermal solid body.

パラメータ:
  • field (felupe.FieldContainer) -- Field container with the temperature as first field.

  • coefficient (float) -- Heat flux per unit area or volume \(q\) in W/m^2 or W/m^3.

メモ

This class represents a thermal heat flux boundary condition for a thermal solid body, which is used to model heat flux in or on the surface of a solid material. The heat flux coefficient is used to calculate the heat flux.

サンプル

This class can be used to model a heat flux on a surface of a thermal solid body. Here, the heat flux is applied on the right end face of a rectangular domain, while the left end face is kept at a constant temperature.

>>> import felupe as fem
>>>
>>> mesh = fem.Rectangle(n=11)
>>> region = fem.RegionQuad(mesh)
>>> temperature = fem.Field(region, dim=1)
>>> field = fem.FieldContainer([temperature])
>>>
>>> region_flux = fem.RegionQuadBoundary(mesh, mask=mesh.x == 1.0)
>>> temperature_flux = fem.Field(region_flux, dim=1)
>>> field_flux = fem.FieldContainer([temperature_flux])
>>>
>>> boundaries = fem.BoundaryDict(
...     left=fem.Boundary(temperature, fx=0),
... )
>>>
>>> solid = fem.thermal.SolidBodyThermal(
...     field=field,
...     mass_density=1.0,  # kg/m^3
...     specific_heat_capacity=1.0,  # J / (kg K)
...     time_step=0.01,  # s
...     thermal_conductivity=1.0,  # W / (m K)
... )
>>> heat_flux = fem.thermal.SolidBodyHeatFlux(
...     field=field_flux,
...     heat_flux=1.0,  # W / m^2
... )
>>> time = fem.thermal.TimeStep([solid])
>>> table = fem.math.linsteps([0, 1], num=10)
>>> ramp = {
...     time: 0.1 * table,
...     heat_flux: 10 * table,
... }
>>> step = fem.Step(
...     items=[time, solid, heat_flux], ramp=ramp, boundaries=boundaries
... )
>>> job = fem.Job(steps=[step]).evaluate()
>>>
>>> mesh.view(
...     point_data={"Temperature in °C": temperature.values}
... ).plot("Temperature in °C").show()
../_images/thermal-d8e19b220ae5367d_00_00.png

It is also possible to model a heat flux in the volume of a thermal solid body, or in other words, a volumetric heat source / heat sink.

>>> import felupe as fem
>>>
>>> mesh = fem.Rectangle(n=11)
>>> region = fem.RegionQuad(mesh)
>>> temperature = fem.Field(region, dim=1)
>>> field = fem.FieldContainer([temperature])
>>>
>>> boundaries = fem.BoundaryDict(
...     left=fem.Boundary(temperature, fx=0),
...     right=fem.Boundary(temperature, fx=1),
...     bottom=fem.Boundary(temperature, fy=0),
...     top=fem.Boundary(temperature, fy=1),
... )
>>>
>>> solid = fem.thermal.SolidBodyThermal(
...     field=field,
...     mass_density=1.0,  # kg / m^3
...     specific_heat_capacity=1.0,  # J / (kg K)
...     time_step=0.01,  # s
...     thermal_conductivity=1.0,  # W / (m K)
... )
>>> heat_flux = fem.thermal.SolidBodyHeatFlux(
...     field=field,
...     heat_flux=1.0,  # W / m^3
... )
>>> time = fem.thermal.TimeStep([solid])
>>> table = fem.math.linsteps([0, 1], num=10)
>>> ramp = {
...     time: 0.1 * table,
...     heat_flux: -10 * table,  # heat source
... }
>>> step = fem.Step(
...     items=[time, solid, heat_flux], ramp=ramp, boundaries=boundaries
... )
>>> job = fem.Job(steps=[step]).evaluate()
>>>
>>> mesh.view(
...     point_data={"Temperature in °C": temperature.values}
... ).plot("Temperature in °C").show()
../_images/thermal-e3b39d43ee448b78_00_00.png

参考

felupe.thermal.TimeStep

A time step item.

felupe.thermal.SolidBodyThermal

A thermal solid body for heat conduction.

update(heat_flux)[ソース]#
class felupe.thermal.TimeStep(items, time_old=0.0, time_new=None)[ソース]#

ベースクラス: object

A time step item.

パラメータ:

メモ

This class is used to update the time step for each item in the list of items. The time step is calculated as the difference between the new time and the old time, and is assigned to each item in the list.

注釈

It is important to include this TimeStep item in a step as first item, so that the time step is updated before the thermal solid body is evaluated.

サンプル

>>> import felupe as fem
>>>
>>> mesh = fem.Rectangle(n=11).triangulate()
>>> region = fem.RegionTriangle(mesh)
>>> temperature = fem.Field(region, dim=1)
>>> field = fem.FieldContainer([temperature])
>>>
>>> solid = fem.thermal.SolidBodyThermal(
...     field,
...     mass_density=1.0,
...     specific_heat_capacity=1.0,
...     thermal_conductivity=1.0,
... )
>>>
>>> time = fem.thermal.TimeStep(items=[solid])
>>> table = fem.math.linsteps([0, 1], num=100)
>>>
>>> step = fem.Step(items=[time, solid], ramp={time: table})

参考

felupe.thermal.SolidBodyThermal

A thermal solid body.

update(time_new)[ソース]#