kipe.fenicsx.examples.heat module

Heat equation in dolfinx, as a minimal kipe forward solver for FEniCSx.

\[\partial_t u - \kappa \Delta u = a \sin(\pi x) \sin(\pi y) \quad \text{in } (0, 1)^2, \qquad u = 0 \text{ on the boundary}, \qquad u(0) = 0,\]

with P1 elements and backward Euler. The exact solution is

\[u(t) = \frac{a}{2\pi^2\kappa} \left(1 - e^{-2\pi^2\kappa t}\right) \sin(\pi x) \sin(\pi y),\]

so the diffusivity \(\kappa\) and the source amplitude \(a\) can both be identified from a time series of \(u\): early on, \(u\) grows like \(a t\); the approach to the steady state \(a / (2\pi^2\kappa)\) reveals \(\kappa\).

The state is one field, u, distributed over the MPI ranks: each rank holds the values of its owned degrees of freedom. The public members of Solver, together with FieldSpec, are the complete kipe interface, including the FEniCSx capability Solver.function_space(); the private methods are the model. This module is fully independent of kipe.

type kipe.fenicsx.examples.heat.NDArray_f64 = NDArray[float64]
type kipe.fenicsx.examples.heat.State = dict[str, NDArray_f64]
type kipe.fenicsx.examples.heat.Parameters = dict[str, float]
class kipe.fenicsx.examples.heat.FieldSpec(local_size: int, kind: Literal['distributed', 'replicated'] = 'distributed')[source]

Bases: object

Layout of one state field on the current MPI rank.

local_size: int

its owned degrees of freedom.

Type:

Number of entries of the field held by this rank

kind: Literal['distributed', 'replicated'] = 'distributed'

each entry is owned by exactly one rank.

Type:

distributed

class kipe.fenicsx.examples.heat.Solver(n: int = 16, dt: float = 0.01, kappa: float = 0.1, a: float = 1.0, comm: mpi4py.MPI.Comm = mpi4py.MPI.COMM_WORLD)[source]

Bases: object

Heat equation on the unit square with P1 elements and backward Euler.

Parameters:
  • n – number of cells per side of the unit square (2 n^2 triangles)

  • dt – time step size

  • kappa – nominal value of the diffusivity \(\kappa\)

  • a – nominal value of the source amplitude \(a\)

  • comm – communicator over which the mesh is distributed

property state_spec: dict[str, FieldSpec]

one distributed field, u.

Type:

Names and layout of the state fields

nominal_parameters() → Parameters[source]

Return the estimable parameters and their nominal values.

Returns:

parameter name -> nominal value dict (a new dict)

initial_state() → tuple[float, State][source]

Return the start time and the initial state.

Returns:

  • start time t0 = 0

  • initial state \(u = 0\)

propagate(t0: float, t1: float, state: State, parameters: Parameters) → State[source]

Propagate the state from t0 to t1 with backward Euler steps.

Parameters:
  • t0 – time of state

  • t1 – target time

  • state – state at t0

  • parameters – parameter values for this call, overriding the nominal values

Returns:

state at t1

Raises:

ValueError – if t1 - t0 is not a positive multiple of dt

function_space(field: str) → dolfinx.fem.FunctionSpace[source]

Return the function space of a state field, for samplers on meshes.

Parameters:

field – name of the state field

Returns:

the function space whose owned degrees of freedom hold the field’s entries

Raises:

KeyError – if there is no such field