General concepts » Ciarlet's definition of a finite element

The mathematical foundation of finite elements.

Introduction

The finite element method (FEM) is a powerful technique for numerically solving partial differential equations. At its heart lies the concept of a finite element, which provides a systematic way to construct piecewise-polynomial approximations on a mesh.

The most widely used formal definition of a finite element was introduced by Philippe G. Ciarlet. This definition provides a clean mathematical framework that separates three concerns:

  1. Geometry: on which shape is the element defined?
  2. Approximation: which polynomial space is used?
  3. Degrees of freedom: how are functions in the space uniquely determined?

This separation is precisely mirrored in Rodin's architecture: the Geometry module handles shapes, the Variational module defines polynomial spaces and DOFs, and the Assembly module puts them together.

The Ciarlet Triple

A finite element in the sense of Ciarlet is defined as a triple $ (K, P, \Sigma) $ where:

  • $ K $ is a geometric domain — a compact, connected subset of $ \mathbb{R}^d $ with nonempty interior (e.g. a triangle, tetrahedron, quadrilateral). This is also called the reference element. In Rodin, reference element geometry is defined by the Polytope::Type enumeration (Triangle, Tetrahedron, Quadrilateral, etc.).
  • $ P $ is a finite-dimensional function space defined on $ K $ — typically a space of polynomials of a certain degree. For instance, $ P = \mathbb{P}_k(K) $ , the space of polynomials of degree at most $ k $ , whose dimension is:

    \[ \dim \mathbb{P}_k(\mathbb{R}^d) = \binom{k + d}{d} \]

    For $ d = 2 $ : $ \dim \mathbb{P}_1 = 3 $ , $ \dim \mathbb{P}_2 = 6 $ . For $ d = 3 $ : $ \dim \mathbb{P}_1 = 4 $ , $ \dim \mathbb{P}_2 = 10 $ .

  • $ \Sigma = \{ \sigma_1, \sigma_2, \ldots, \sigma_n \} $ is a set of degrees of freedom (DOFs) — linear functionals $ \sigma_i : P \to \mathbb{R} $ — such that any function $ p \in P $ is uniquely determined by the values $ \sigma_1(p), \ldots, \sigma_n(p) $ .

The key requirement is that the DOFs must form a basis for the dual space $ P' $ . This means $ \dim(P) = n $ , and the map

\[ p \mapsto (\sigma_1(p), \ldots, \sigma_n(p)) \]

is an isomorphism from $ P $ to $ \mathbb{R}^n $ . Equivalently, if $ \sigma_i(p) = 0 $ for all $ i $ , then $ p = 0 $ . This property is called unisolvence.

Basis Functions

Given a Ciarlet triple $ (K, P, \Sigma) $ , there exists a unique set of basis functions $ \{ \phi_1, \ldots, \phi_n \} \subset P $ such that:

\[ \sigma_i(\phi_j) = \delta_{ij} \]

where $ \delta_{ij} $ is the Kronecker delta. This is called the nodal basis of the finite element. These basis functions are the shape functions that are used to represent any function in the finite element space.

Any function $ p \in P $ can then be written as:

\[ p = \sum_{i=1}^{n} \sigma_i(p) \, \phi_i \]

The values $ \sigma_i(p) $ are the degrees of freedom (DOF values) of $ p $ . In Rodin, these DOF values are stored as the coefficient vector of a GridFunction.

Common Finite Elements

P1 (Piecewise Linear) Elements

The simplest and most widely used finite element is the P1 element on a triangle:

  • $ K $ = a triangle with vertices $ a_1, a_2, a_3 $
  • $ P = \mathbb{P}_1(K) $ = polynomials of degree $ \leq 1 $ (i.e. $ p(x, y) = \alpha + \beta x + \gamma y $ ), dimension 3
  • $ \Sigma = \{ \sigma_1, \sigma_2, \sigma_3 \} $ where $ \sigma_i(p) = p(a_i) $ (point evaluations at vertices)

The basis functions are the barycentric coordinates $ \lambda_1, \lambda_2, \lambda_3 $ , satisfying $ \lambda_i(a_j) = \delta_{ij} $ . Each basis function is 1 at one vertex and 0 at the other two, varying linearly between them.

In Rodin, a P1 finite element space is created with:

P1 Vh(mesh);
// Number of DOFs = number of vertices
std::cout << Vh.getSize() << std::endl;

The P1 class constructs one DOF per mesh vertex, producing a space of continuous piecewise linear functions that is $ H^1 $ -conforming.

P0 (Piecewise Constant) Elements

An even simpler element is the P0 element, used for discontinuous quantities:

  • $ K $ = a polytope (triangle, tetrahedron, etc.)
  • $ P = \mathbb{P}_0(K) $ = constant functions, dimension 1
  • $ \Sigma = \{ \sigma_1 \} $ where $ \sigma_1(p) $ is the value of the constant, often defined as the average over $ K $

In Rodin:

P0 Wh(mesh);
// Number of DOFs = number of cells
std::cout << Wh.getSize() << std::endl;

The P0 class constructs one DOF per mesh cell. Functions in P0 are discontinuous across cell boundaries, making this space a subspace of $ L^2(\Omega) $ (not $ H^1 $ ).

Higher-Order Elements (H1<k>)

For polynomial degree $ k \geq 2 $ , additional DOFs are placed on edges and (for $ k \geq 3 $ ) on cell interiors. For example, the P2 element on a triangle has:

  • $ K $ = a triangle
  • $ P = \mathbb{P}_2(K) $ = quadratic polynomials, dimension 6
  • $ \Sigma $ = point evaluations at the 3 vertices and 3 edge midpoints

In Rodin, higher-order elements are provided by the H1<k> class:

// Quadratic (P2) finite element space
H1 Vh(std::integral_constant<size_t, 2>{}, mesh);

The polynomial order $ k $ is a compile-time template parameter.

From Local to Global

The Ciarlet definition describes a local finite element on a single reference cell $ \hat{K} $ . To construct a global finite element space on an entire mesh $ \mathcal{T}_h $ , we:

  1. Define a reference element $ (\hat{K}, \hat{P}, \hat{\Sigma}) $
  2. Map it to each physical cell $ K \in \mathcal{T}_h $ using a geometric transformation $ F_K : \hat{K} \to K $ . In Rodin, the Jacobian of this transformation is accessible through Point::getJacobian().
  3. Assemble local DOFs into global DOFs, enforcing inter-element continuity conditions at shared entities (vertices, edges, faces)

The result is a finite-dimensional subspace $ V_h $ of the function space in which we seek our approximate solution.

The assembly of local DOFs into global DOFs is handled automatically when you create a finite element space. For example, P1 Vh(mesh) constructs the global DOF numbering by identifying vertex-based DOFs on shared mesh vertices.

Conformity

Different types of inter-element continuity give rise to different types of conforming finite element spaces:

ConformityContinuity requirementTypical useRodin class
$ H^1 $ -conformingContinuous across element boundariesScalar PDEs (Poisson, heat)P1, H1
$ H(\mathrm{div}) $ -conformingNormal component continuousMixed methods, fluid flow—
$ H(\mathrm{curl}) $ -conformingTangential component continuousElectromagnetics—
$ L^2 $ (no conformity)No continuity requiredDiscontinuous Galerkin, indicatorsP0

Rodin currently provides $ H^1 $ -conforming elements (P1, H1) and $ L^2 $ elements (P0). The P1 and H1 spaces produce global functions that are continuous across element boundaries: values at shared vertices (and shared edge/face DOFs for higher order) are identified.

Connection to Rodin

In Rodin, the Ciarlet definition is realized through the interaction of several classes:

Ciarlet componentMathematical objectRodin class
$ K $ Reference element geometryPolytope + Polytope::Type
$ P $ Local polynomial spaceDefined internally by P0, P1, H1
$ \Sigma $ Degrees of freedomDOF numbering managed by the finite element space class
$ V_h $ Global finite element spaceThe space object itself (e.g. P1 Vh(mesh))
$ u_h \in V_h $ Discrete functionGridFunction
$ u $ (unknown)Trial functionTrialFunction
$ v $ (weight)Test functionTestFunction
// The mesh provides the cells K and the geometric transformations F_K
Mesh mesh;
mesh = mesh.UniformGrid(Polytope::Type::Triangle, {16, 16});

// P1 defines the local element (K, P1, point evaluations at vertices)
// and assembles them into a global space Vh
P1 Vh(mesh);

// Trial and test functions live in this global space
TrialFunction u(Vh);
TestFunction  v(Vh);

See Also