5  Review of Finite Element Approximation

Jog’s abstract formulation emphasizes the sequence from a finite-dimensional subspace to assembly, boundary conditions, solution, and postprocessing. Larson and Bengzon provide a complementary approximation and implementation viewpoint (Jog 1978; Larson and Bengzon 2010).

5.1 Galerkin approximation

Given a variational problem on \(V\), choose a finite-dimensional subspace

\[ \Vh\subset V. \]

The conforming Galerkin approximation is

\[ \text{find }\uh\in\Vh \quad\text{such that}\quad a(\uh,\vh)=\ell(\vh) \quad\forall\vh\in\Vh. \tag{5.1}\]

5.2 Basis functions and assembly

Let \(\{\phi_i\}_{i=1}^N\) be a basis for \(\Vh\) and write

\[ \uh=\sum_{j=1}^N U_j\phi_j. \]

Substitution into Equation 5.1 yields

\[ \mathbf{K}\mathbf{U}=\mathbf{F}, \]

where

\[ K_{ij}=a(\phi_j,\phi_i), \qquad F_i=\ell(\phi_i). \]

5.3 Reference elements and quadrature

The same implementation is reused over many physical elements by mapping from a reference element. Numerical quadrature is then used to evaluate element integrals.

5.4 A computed figure inside the chapter

The following cell is intentionally simple. Its purpose is to show how a computed result appears directly in the source and receives a cross-reference.

import numpy as np
import matplotlib.pyplot as plt

h = np.array([0.5, 0.25, 0.125, 0.0625])
error = 0.8 * h

plt.figure()
plt.loglog(h, error, "o-")
plt.xlabel(r"mesh size $h$")
plt.ylabel("error")
plt.grid(True, which="both")
plt.tight_layout()
plt.show()
Figure 5.1: Illustrative first-order convergence curve generated during the book build.

The figure can then be referenced normally as Figure 5.1. In the actual error-analysis chapter, the values will come from FEniCSx computations rather than from an illustrative array.

5.5 FEniCSx code in the same source

A FEniCSx cell can be executable once the course environment is installed. It is marked eval: false here so that this template remains portable.

from mpi4py import MPI
from dolfinx import fem, mesh

# Mesh and scalar Lagrange space
domain = mesh.create_unit_square(MPI.COMM_WORLD, 32, 32)
V = fem.functionspace(domain, ("Lagrange", 1))

The important design choice is that the mathematical object \(V_h\) is introduced first, and the FEniCSx object is then presented as its computational realization.

Example 5.1 (Mathematical objects and FEniCSx objects) A typical chapter will explicitly connect the mesh \(\Th\), finite element space \(V_h\), trial and test functions, variational forms, boundary conditions, and solver objects to their FEniCSx counterparts.