Temperature#

Definition of a temperature field or problem is essential for hydrogen transport and FESTIM as a whole, since diffusivities, solubilities and reaction rates all depend on it. Regardless of how you define the temperature of the problem, it is passed (in Kelvin) to the temperature attribute of the festim.HydrogenTransportProblem object.

Analytical expressions#

The temperature can be defined as a constant value in Kelvin (K):

my_model.temperature = 300

Temperature can also be defined as a function of time and/or space. For example:

\[T = 300 + 2 x + 3 t\]

would be passed to FESTIM as:

my_model.temperature = lambda x, t: 300 + 2 * x[0] + 3 * t

Note

Only the arguments x and t can be used. Spatial coordinates can be referred to by their indices, such as x[0], x[1], and x[2], regardless of the coordinate system used.

More complex expressions are written with ufl functions. For instance:

\[T = 300 + 100 \exp(-x) \ \sin(t)\]

would be passed to FESTIM as:

import ufl

my_model.temperature = lambda x, t: 300 + 100 * ufl.exp(-x[0]) * ufl.sin(t)

Conditional expressions are also possible. For a function of time only, a plain Python conditional works:

my_model.temperature = lambda t: 400 if t < 10 else 300

For a function of space, use ufl.conditional:

import ufl

my_model.temperature = lambda x: ufl.conditional(ufl.lt(x[0], 0.5), 400, 300)

Note

A function of t only is evaluated once per time step and must return a number, so plain Python conditionals can be used. A function of x is evaluated symbolically on the mesh and must use ufl operators (ufl.conditional, ufl.exp…) rather than Python conditionals or numpy functions.

From a heat transfer solver#

Temperature can also be obtained by solving the heat equation (see the theory guide). Users can define heat transfer problems using festim.HeatTransferProblem. It takes the same kind of arguments as festim.HydrogenTransportProblem: a mesh, subdomains, boundary conditions, sources, exports and settings. The materials of the volume subdomains must define thermal_conductivity, and for transient problems density and heat_capacity too.

import festim as F

tungsten = F.Material(
    D_0=4.1e-7,
    E_D=0.39,
    thermal_conductivity=170,
    density=19300,
    heat_capacity=130,
)
my_volume = F.VolumeSubdomain1D(id=1, borders=[0, 1e-3], material=tungsten)
left = F.SurfaceSubdomain1D(id=1, x=0)
right = F.SurfaceSubdomain1D(id=2, x=1e-3)

my_heat_model = F.HeatTransferProblem(
    mesh=F.Mesh1D(vertices=[0, 2.5e-4, 5e-4, 7.5e-4, 1e-3]),
    subdomains=[my_volume, left, right],
    boundary_conditions=[
        F.HeatFluxBC(subdomain=left, value=1e7),
        F.FixedTemperatureBC(subdomain=right, value=373),
    ],
    settings=F.Settings(atol=1e-8, rtol=1e-10, transient=False),
)

Heat transfer boundary conditions (festim.FixedTemperatureBC, festim.HeatFluxBC) and heat sources (festim.HeatSource) can be applied to the heat transfer problem.

For transient problems, an initial condition is required (see Initial conditions):

my_heat_model.initial_condition = F.InitialTemperature(value=300, volume=my_volume)
my_heat_model.settings = F.Settings(
    atol=1e-8, rtol=1e-10, final_time=10, stepsize=0.1
)

Steady-state temperature#

If the temperature field does not evolve in time, the heat transfer problem is solved first and its solution is passed to the hydrogen transport problem as a dolfinx.fem.Function:

my_heat_model.initialise()
my_heat_model.run()

my_model.temperature = my_heat_model.u

Note

For this to work, both problems must be defined on the same mesh object (pass the same festim.Mesh instance to both). Problems defined on different meshes can only be coupled with festim.CoupledTransientHeatTransferHydrogenTransport (see below).

Coupled transient problems#

When the temperature and the hydrogen concentrations must evolve together, the two problems are coupled with festim.CoupledTransientHeatTransferHydrogenTransport. Both problems must be transient and have the same final_time; the coupled problem takes care of stepping them together and of passing the temperature to the hydrogen transport problem.

coupled_model = F.CoupledTransientHeatTransferHydrogenTransport(
    heat_problem=my_heat_model,
    hydrogen_problem=my_model,
)

coupled_model.initialise()
coupled_model.run()

The two problems can be defined on different meshes, in which case the temperature is interpolated onto the mesh of the hydrogen transport problem at each time step.

Note

Coupled problems are not yet supported with festim.HydrogenTransportProblemDiscontinuous.

From a checkpoint file#

Temperature can also be read from a checkpoint file written by a previous simulation (see Checkpoints), with festim.read_function_from_file():

my_model.temperature = F.read_function_from_file(
    filename="temperature.bp", name="f", timestamp=10.0, mesh=my_model.mesh.mesh
)

Note

The file must have been written by a festim.TemperatureExport with format="checkpoint". The name argument is the name of the function in the file: for a festim.HeatTransferProblem this is the name of its solution my_heat_model.u.name, which is "f" unless you rename it before running. Files in the visualisation formats ("vtx", "vtkhdf", "xdmf") cannot be read back.