ASF

Numerical Analysis via Discrete Exterior Calculus

April 4, 2026|
A
A

0. Why geometry matters for computation

Numerical analysis is the art of replacing continuous objects with finite ones and controlling the error. Derivatives become differences, integrals become sums, differential equations become linear systems. The standard toolkit for making these replacements (finite differences, finite elements, spectral methods) was developed over three centuries, and each tool comes with its own convergence theorems, its own stability conditions, and its own failure modes.

This article presents a different perspective. The classical tools are all, in a precise sense, incomplete versions of a single geometric construction: discrete exterior calculus (DEC). When a classical method works, it is because it accidentally preserves some fragment of the geometric structure of the underlying continuous problem. When it fails, the failure can be diagnosed as a geometric structure violation. DEC preserves all of this structure by construction.

To make this claim tangible, we begin with a failure.

0.1. The Poisson equation from physics

Consider a thin metal plate lying flat in the plane . The plate occupies a bounded region , and its edges are held at fixed temperatures. Heat flows from hot to cold. After waiting long enough, the temperature distribution reaches a steady state where nothing changes. What equation governs this steady state?

Two physical facts are sufficient. The first is Fourier's law: heat flux is proportional to the negative temperature gradient. If is the temperature at position , the heat flux vector is

where is the thermal conductivity (a material property we can set to 1 without loss of generality). Heat flows from high temperature to low temperature, in the direction of steepest descent.

The second is conservation of energy: in steady state, the net heat flux out through the boundary of any sub-region equals the total heat generated inside it. For a sub-region with boundary curve , this is

where is the outward unit normal to , is the arc length element along the boundary, is the area element, and is the heat source density (energy generated per unit area per unit time). The symbol denotes a closed line integral: an integral taken along a curve that forms a closed loop (here, the boundary of the sub-region). It is computed exactly like an ordinary line integral, but the circle emphasises that the path returns to its starting point.

The bridge between this integral statement and a pointwise equation is the divergence theorem. Since our thin plate lives in , we state the theorem in this setting first, then generalise.

Theorem (The divergence theorem in ).

For a smooth vector field on a bounded region with piecewise smooth boundary ,

The left side sums how much the field "spreads out" at each point; the right side measures the total outward flow through the boundary curve. In , this is often called Green's theorem in the flux form.

Applying the divergence theorem to [eq:conservation] with , and noting that the equation holds for every sub-region , we conclude that the integrand itself must vanish:

The operator is called the Laplacian. Writing for the unknown function (since this equation appears far beyond heat conduction), we obtain the Poisson equation:

This derivation generalises immediately to . The same argument (a flux law plus conservation plus the divergence theorem) produces the Poisson equation in any dimension, provided we use the correct form of the divergence theorem.

Theorem (The divergence theorem in ).

Let be a bounded region in with piecewise smooth boundary , and let be a smooth vector field on . Then

where is the divergence, is the -dimensional volume element on , is the -dimensional surface element on , and is the outward unit normal. The closed integral is taken over the entire boundary, which is an -dimensional closed surface (it has no boundary of its own).

The key point is that the boundary is always one dimension lower than the region , and the theorem relates an integral over the interior to an integral over this lower-dimensional boundary.

Remark (The divergence theorem by dimension).

The general statement [eq:divergence-thm-eq] specialises as follows:

. The region is an interval , whose boundary is the pair of points (a 0-dimensional "surface"). The outward normals are at and at . The theorem reduces to the fundamental theorem of calculus: .

. The boundary is a closed curve (1-dimensional). The volume element is the area element , the surface element is the arc length element . This is the case we used for the thin plate.

. The boundary is a closed surface (2-dimensional). The theorem is the classical divergence theorem of Gauss: .

The Poisson equation in is then

In the Laplacian is ; in it adds . When (no sources), the equation reduces to Laplace's equation , and the solution is called a harmonic function.

Remark (The Poisson equation beyond heat).

The derivation above used heat conduction, but the Poisson equation governs far more. In electrostatics, is the electric potential and is the charge density (divided by the permittivity). In Newtonian gravity, is the gravitational potential and is the mass density. In each case, the structure is identical: a flux law (Fourier, Gauss, Newton) combined with conservation (divergence theorem) produces [eq:poisson-intro]. The Poisson equation is the universal equation for potential fields generated by sources.

0.2. The five-point stencil

To solve [eq:poisson-intro] on a computer, we need to approximate the Laplacian with a finite number of operations. The oldest and most natural approach is finite differences. Place a uniform rectangular grid over the domain with spacing in both directions. At each interior grid point , approximate the second derivatives using the Taylor expansion:

and similarly for . Adding the two gives the five-point stencil for the discrete Laplacian:

The five-point stencil: centre node u_{i,j} with weight -4, connected to four neighbours each with weight +1
The five-point stencil for the discrete Laplacian. The centre node carries weight ; each of its four axis-aligned neighbours carries weight . All five nodes lie at spacing on a uniform rectangular grid.

This approximation is accurate, meaning the error between and at each grid point is bounded by a constant times , provided is sufficiently smooth.

Remark (A note on big notation).

We write as to mean that there exists a constant (independent of ) such that for all sufficiently small . For instance, means "bounded by a constant times ." This notation captures the rate at which a quantity shrinks as the mesh is refined: shrinks four times faster than when the mesh spacing is halved. We use this notation throughout the article to state convergence rates.

On a square domain with interior grid points per side, the discrete Poisson equation is a sparse linear system of equations in unknowns, solvable in operations via fast methods.

For rectangular domains, this works beautifully. The trouble begins when the domain is not rectangular.

0.3. The failure on an L-shaped domain

Consider the L-shaped domain formed by removing the upper-right quadrant from the unit square: . This domain has a re-entrant corner at the origin, where the interior angle is .

The exact solution to the Laplace equation on this domain (with appropriate boundary conditions) has a singularity at the re-entrant corner. In polar coordinates centred at the origin, the leading term of the solution behaves as

The exponent means the gradient diverges as near the corner. The solution is continuous but not smooth.

Now apply the five-point stencil [eq:five-point] to this domain. Two things go wrong:

  1. Staircase boundary. The rectangular grid cannot represent the re-entrant corner exactly. Grid points near the corner are either inside the domain or outside it, and the corner itself falls between grid lines. The discrete domain is a staircase approximation that introduces an geometric error at every boundary cell.

  2. Regularity failure. The five-point stencil's error estimate requires (four continuous derivatives). But the exact solution has unbounded derivatives at the corner. The stencil does not know this: it treats the corner the same as any interior point, and the local error there is much larger than .

The result is a computed solution that is globally degraded. The convergence rate drops from to roughly , and the error contaminates the entire domain, not just the neighbourhood of the corner. Refining the grid helps, but much more slowly than the theory for smooth problems predicts.

This is not a minor inconvenience. Non-rectangular domains with corners and curved boundaries are the rule in applications, not the exception. The L-shaped domain is the simplest possible example of a universal problem: the rectangular grid imposes a geometry on the computation that may have nothing to do with the geometry of the problem.

The question this article answers is: what geometric structure did the rectangular grid destroy, and how do we build numerical methods that preserve it? The answer involves replacing the rectangular grid with a simplicial complex, replacing sampled function values with cochains, and replacing the Laplacian with the Hodge Laplacian. We begin with the simplicial complex.

1. Simplicial complexes

The rectangular grid is a special case of a more general idea: dividing a domain into simple geometric pieces. The trouble with rectangles is that they are rigid. They cannot conform to curved boundaries without staircase artifacts, and they impose a preferred set of coordinate directions that may have nothing to do with the problem. Triangles (and their higher-dimensional analogues) are flexible: any domain in can be triangulated, with the mesh conforming exactly to the boundary. This section develops the combinatorial machinery for working with triangulations.

1.1. Simplices

The starting point is the simplest possible geometric building block: the generalisation of a triangle to arbitrary dimensions. To define it, we first need the notion of points in "general position."

Definition .

A set of points is affinely independent if the vectors are linearly independent. Equivalently, no point in the set can be written as an affine combination of the others.

Definition .

A -simplex is the convex hull of affinely independent points :

The number is the dimension of the simplex.

Example (Simplices in low dimensions).

A 0-simplex is a point. A 1-simplex is a line segment. A 2-simplex is a triangle. A 3-simplex is a tetrahedron. These are the building blocks of all the meshes in this article.

Remark (Points versus vectors in ).

We write the vertices in boldface because they are elements of that serve simultaneously as points (locations in space) and vectors (objects we can add, subtract, and scale). This dual role is possible because carries three structures at once: it is a set of points, a vector space (with componentwise addition and scalar multiplication), and a metric space (with the Euclidean distance). The vector from the origin to the point is , and conversely every vector determines a unique point. The expression in the affine independence definition uses this identification: it subtracts two points to obtain a displacement vector.

This identification breaks down in two important settings. On a curved manifold (a sphere, a torus, the surface of an airplane wing), the tangent space at a point (where velocity vectors live) is a genuinely different space from the manifold itself (where points live). There is no canonical way to subtract two points on a sphere to get a tangent vector. On with curvilinear coordinates (polar, cylindrical, spherical), the coordinate basis vectors vary from point to point, so a vector expressed in the local basis at one point cannot be directly compared with a vector at another point without a connection (the subject of parallel transport). In both cases, the conflation of points and vectors is no longer available, and the machinery of differential geometry (tangent bundles, connections, covariant derivatives) becomes necessary. We discuss this further in Analysis on Manifolds, Part I.

Throughout this article, we work exclusively in with Cartesian coordinates, so the identification is safe. We use boldface for vertices (points/vectors in ), plain italic for scalar components of a tangent vector, and for a generic point.

Definition .

A face of a -simplex is any simplex formed by a non-empty subset of the vertices. A face of dimension (obtained by omitting exactly one vertex) is called a facet. The -th facet of is

where denotes omission.

1.2. Orientation

To define the boundary operator, we need to distinguish between the two "directions" a simplex can be traversed. An edge can be traversed from to or from to . A triangle can be traversed clockwise or counter-clockwise.

Definition .

An orientation of a -simplex is an equivalence class of orderings of its vertices, where two orderings are equivalent if they differ by an even permutation. Each -simplex with has exactly two orientations. We write for the orientation determined by the given ordering, and for the opposite orientation.

Example (Orientations of edges and triangles).

The edge has two orientations: (from to ) and (from to ). The triangle has two orientations: (counter-clockwise if the vertices are arranged that way) and (clockwise). Note that (an odd permutation), while (a cyclic, hence even, permutation).

1.3. Simplicial complexes

A single simplex is a building block. A simplicial complex is a collection of simplices glued together along shared faces, subject to two compatibility conditions that prevent overlaps and dangling pieces.

Definition .

A simplicial complex in is a finite collection of simplices such that:

  1. Every face of a simplex in is also in .
  2. The intersection of any two simplices in is either empty or a face of both.

The dimension of is the maximum dimension of any simplex in . The underlying space is the union of all simplices in .

Remark (Simplicial complexes as meshes).

A simplicial complex is exactly what computational scientists call a mesh (or triangulation in 2D, tetrahedral mesh in 3D). The two conditions in the definition ensure that the mesh is valid: no dangling vertices, no overlapping elements, and neighbouring elements meet along shared faces. Every bounded domain in with piecewise smooth boundary can be triangulated, meaning there exists a simplicial complex whose underlying space approximates the domain to any desired accuracy.

1.4. Chains and the boundary operator

Definition .

A -chain on a simplicial complex is a formal linear combination of oriented -simplices in with integer coefficients:

The set of all -chains forms a free abelian group under addition.

Remark (Chains as discrete submanifolds).

A -chain is a formal "sum of oriented -simplices with multiplicities." A single oriented triangle is a 2-chain. Two triangles sharing an edge is a 2-chain. The formal sum is also a 2-chain. Chains are the discrete analogue of oriented submanifolds.

Definition .

The boundary operator is the linear map defined on each oriented -simplex by

and extended to all chains by linearity.

Example (Boundaries of edges and triangles).

The boundary of an edge is the difference of its endpoints: . The boundary of a triangle is the sum of its edges with alternating signs: . The sign pattern ensures that the edges are oriented consistently around the triangle: following , then , then traverses the boundary of the triangle in the correct direction.

The central algebraic fact about the boundary operator is:

Theorem .

For all , the composition of consecutive boundary operators is the zero map:

Proof

It suffices to check on a single oriented -simplex , since is linear. Applying [eq:boundary-op] twice:

where indexes the vertices of the facet with already removed. Each -face (with ) appears exactly twice in this sum: once from removing first (sign , because 's position shifts down by 1 after is removed) and once from removing first (sign ). These two contributions have signs and , which sum to zero. Since every term in the double sum cancels, .

Remark (The geometric meaning).

The boundary of a boundary is empty. The boundary of a triangle is a closed loop of edges. The boundary of that loop is the alternating sum of its endpoints, which cancel pairwise because each interior vertex appears once as the start of one edge and once as the end of another. This cancellation is not a coincidence: it is forced by the orientation convention.

1.5. Boundary matrices

Once we fix an ordering of the simplices in each dimension, the boundary operator is a matrix. The entry in row (a -simplex) and column (a -simplex) is if appears in with a positive sign, if it appears with a negative sign, and otherwise.

Example (Triangulated interval).

Consider 4 vertices on a line, connected by 3 edges , , . The boundary matrix is :

The -th column encodes : a at the starting vertex and a at the ending vertex.

Example (Triangulated square).

Consider 4 vertices forming a square, with 5 edges and 2 triangles. Label the vertices , , , , the edges , , , , , and the triangles , . The boundary matrices are:

The product is the zero matrix, verifying [eq:dd-zero].

Remark ( is topological, not numerical).

The identity can be checked by direct matrix multiplication, but this misses the point. The identity holds for any simplicial complex, regardless of how many simplices it has or how they are arranged. It is a consequence of the algebraic structure of the boundary operator, not a numerical coincidence. This universality is what makes the boundary operator useful: it captures a topological invariant (the absence of boundary on a boundary) that no metric or coordinate system can destroy.

2. Cochains and the coboundary operator

Chains represent discrete pieces of a domain: vertices, edges, triangles, and their formal combinations. To do numerical analysis, we need to assign numerical values to these pieces. A temperature at each vertex. A flux across each edge. A charge density on each triangle. These assignments are cochains, and they are the discrete analogues of differential forms.

2.1. Cochains

A cochain formalises the idea of assigning measurements to the simplices of a mesh. The definition is dual to that of a chain: where chains are formal sums of simplices, cochains are linear functions that evaluate on chains to produce real numbers.

Definition .

A -cochain on a simplicial complex is a linear map from -chains to real numbers. Equivalently, it is a function that assigns a real number to each oriented -simplex and reverses sign under orientation reversal:

The space of all -cochains is denoted . It is a real vector space of dimension equal to the number of -simplices in .

Remark (Cochains as sampled fields).

A 0-cochain assigns a number to each vertex: it is a sampled scalar field. Temperature at sensor locations, voltage at circuit nodes, and function values at mesh points are all 0-cochains.

A 1-cochain assigns a number to each oriented edge. Physically, this represents a quantity that is naturally integrated along a curve: work done by a force field, voltage drop along a wire, or mass flux through a gate.

A 2-cochain assigns a number to each oriented triangle. This represents a quantity integrated over a surface: magnetic flux through a loop, heat flux through a membrane, or charge enclosed by a surface element.

The key insight is that these assignments are not arbitrary choices of what to sample. Differential forms in the continuous setting are objects that are naturally integrated over submanifolds of the corresponding dimension. A 0-form is evaluated at a point. A 1-form is integrated along a curve. A 2-form is integrated over a surface. Cochains are the discrete version of this structure: they assign numbers to the discrete analogues of points, curves, and surfaces.

2.2. The coboundary operator

The boundary operator maps -chains to -chains. Its dual, the coboundary operator, maps -cochains to -cochains. It is the discrete analogue of the exterior derivative.

Definition .

The coboundary operator is defined by

for every -simplex and every -cochain . In words: the coboundary of evaluated on a simplex equals evaluated on the boundary of .

Remark (The coboundary as a matrix transpose).

In matrix form, if we represent cochains as column vectors (one entry per simplex), then : the coboundary matrix is the transpose of the boundary matrix. This is immediate from the definition, since is precisely the definition of the transpose of a linear map.

Theorem .

The composition of consecutive coboundary operators is the zero map:

Proof

This is the dual of [eq:dd-zero]. For any -cochain and any -simplex :

where we used from [dd-zero]. In matrix form: .

Definition .

The cochain complex (or discrete de Rham complex) of a simplicial complex is the sequence

with the property that for all . This is the discrete analogue of the de Rham complex of smooth differential forms.

2.3. Finite differences recovered

The coboundary operator on a 1D mesh is the finite difference operator. This is the first instance of a classical numerical method emerging from the DEC framework.

Corollary .

Let be a 1D simplicial complex with vertices at positions , connected by edges . Let be the 0-cochain defined by sampling a function at the vertices: . Then:

On a uniform mesh with spacing , this is times the forward finite difference .

Proof

By the definition of the coboundary [eq:coboundary-op]:

Remark (Finite differences as the coboundary).

This is more than a notational coincidence. The coboundary is the transpose of the boundary. On a 1D mesh, the boundary matrix has at the start vertex and at the end vertex of each edge (as in the triangulated interval example of Section 1). Its transpose is a difference operator. The finite difference method for 1D problems is literally the coboundary operator of the simplicial complex.

The second difference operator (used in the 5-point stencil [eq:five-point] and in 1D second-derivative approximations) is , the coboundary composed with its own transpose. This is a special case of the Hodge Laplacian, which we will construct in full generality in Section 6.

2.4. Interpolation error of the coboundary

The coboundary of a sampled function approximates the integral of the derivative. How well?

Theorem .

Let be , and let be the 0-cochain sampling at the vertices of a 1D mesh with maximum edge length . For each edge of length :

The coboundary approximates the integral of the derivative with accuracy per edge.

Proof

We have and by the fundamental theorem of calculus. So the error is exactly zero.

This might seem to make the theorem trivial, but the point is subtle. The coboundary of a 0-cochain evaluates the exact integral of the derivative. There is no approximation error in the coboundary itself. The error enters only when we compare the cochain (a number per edge) to the continuous function (a value at every point). The estimate bounds the error of representing the continuous 1-form by its integrals over edges, which is the error of the de Rham map (Section 3).

Remark (The coboundary is exact; the approximation is elsewhere).

This is a conceptual watershed. In classical numerical analysis, finite differences approximate derivatives with or error (depending on the stencil). In the DEC perspective, the coboundary computes the exact integral of the derivative. The "approximation error" is not in the coboundary but in the identification of a cochain (integrated quantity) with a pointwise quantity (function value). The Whitney map (Section 4) makes this identification precise and controls the error.

2.5. Example: the 1D simple harmonic oscillator

We now apply the coboundary operator to a genuine eigenvalue problem. The one-dimensional quantum harmonic oscillator is governed by the time-independent Schrodinger equation:

with boundary conditions as . The exact eigenvalues are for , and the eigenfunctions are Hermite functions.

Discretisation. Take a uniform mesh on with vertices at , . Impose (the wavefunction vanishes at the boundary, which is a good approximation for large enough). The unknowns are the interior values for .

The second derivative is approximated by the coboundary composed with its transpose. With being the coboundary matrix (transpose of the boundary matrix from Section 1), the kinetic energy operator is

which is the familiar tridiagonal matrix with on the diagonal and on the super- and sub-diagonals. The potential is a diagonal matrix . The discrete Hamiltonian is

Solving the eigenvalue problem (a symmetric tridiagonal eigenproblem, cost ) gives the approximate eigenvalues.

Results. With and (), the first five eigenvalues are:

Exact ComputedAbsolute error
00.50000.5000
11.50001.5000
22.50002.5000
33.50003.4999
44.50004.4996

The eigenvalue error grows with (higher modes oscillate faster, requiring finer meshes to resolve) and decreases as under mesh refinement (consistent with the second-order accuracy of the second-difference stencil ).

use cartan::simplicial::SimplicialComplex1D;
use cartan::dec::CoboundaryOperator;
use nalgebra::{DMatrix, DVector, SymmetricEigen};

// Build 1D mesh on [-8, 8] with 201 vertices
let n = 200;
let l = 8.0_f64;
let h = 2.0 * l / n as f64;
let mesh = SimplicialComplex1D::uniform(-l, l, n);

// Coboundary d0: N x (N+1) matrix (transpose of boundary)
let d0 = mesh.coboundary_matrix(0);

// Kinetic operator: T = -(1/2h^2) d0^T d0, restricted to interior
let d0_int = d0.columns(1, n - 1); // drop boundary columns
let kinetic = &d0_int.transpose() * &d0_int * (-0.5 / (h * h));

// Potential: diagonal V_ii = x_i^2 / 2
let potential = DMatrix::from_diagonal(&DVector::from_fn(n - 1, |i, _| {
  let x = -l + (i + 1) as f64 * h;
  x * x / 2.0
}));

// Hamiltonian and eigensolve
let hamiltonian = kinetic + potential;
let eigen = SymmetricEigen::new(hamiltonian);
let mut eigenvalues: Vec<f64> = eigen.eigenvalues.iter().copied().collect();
eigenvalues.sort_by(|a, b| a.partial_cmp(b).unwrap());

for (i, &e) in eigenvalues.iter().take(5).enumerate() {
  let exact = i as f64 + 0.5;
  println!("E_{i} = {e:.6}  (exact {exact:.4}, error {:.2e})", (e - exact).abs());
}
Not executable

1D SHO via cartan (requires cartan crate)

Python/NumPy comparison
import numpy as np
from scipy.linalg import eigh_tridiagonal

N = 200
L = 8.0
h = 2 * L / N
x = np.linspace(-L + h, L - h, N - 1)  # interior vertices

# Tridiagonal Hamiltonian: T + V
diag = 1.0 / h**2 + x**2 / 2         # main diagonal
off  = -0.5 / h**2 * np.ones(N - 2)   # off-diagonals

eigenvalues, _ = eigh_tridiagonal(diag, off)
exact = np.arange(5) + 0.5

for i in range(5):
    err = abs(eigenvalues[i] - exact[i])
    print(f"E_{i} = {eigenvalues[i]:.6f}  (exact {exact[i]:.4f}, error {err:.2e})")
Log-log plot of 1D SHO eigenvalue errors versus mesh spacing h, showing O(h^2) convergence for the first five eigenvalues
Eigenvalue error versus mesh spacing for the 1D quantum harmonic oscillator. All five eigenvalues converge at , consistent with the Whitney interpolation error bound.
Remark (The Hamiltonian from ).

The Hamiltonian was assembled entirely from the coboundary operator and a diagonal potential matrix. No finite difference formulas were invoked directly: the second-difference stencil arose from , the composition of the coboundary with its transpose. In Section 5, we will see that this composition, modified by the Hodge star, is the Hodge Laplacian, and the convergence is a consequence of the Whitney interpolation error bounds from Section 4.

3. Differential forms, the wedge product, and the exterior derivative

The Whitney map (Section 4) turns cochains into differential forms, and it uses two operations we have not yet defined: the wedge product and the exterior derivative . These are the fundamental operations of the calculus of differential forms. This section constructs both from scratch, assuming only multivariable calculus and linear algebra.

3.1. Differential forms

A function assigns a number to each point. A differential form generalises this: it assigns a number not just to a point, but to a point together with a collection of tangent vectors at that point. The number of tangent vectors it requires determines the degree of the form.

Definition .

A (smooth) -form on an open set is a smooth assignment, to each point , of an alternating multilinear map

where is the tangent space at . Alternating means that swapping any two arguments negates the output. Multilinear means that is linear in each argument separately.

In coordinates on , the coordinate differentials are the basic 1-forms. Each is the linear map that reads off the -th component of a tangent vector:

Example (Differential forms by degree).

0-forms. A 0-form is a smooth function . It takes zero tangent vectors and returns a number: the function value at the point.

1-forms. A 1-form takes one tangent vector and returns a number. In , every 1-form can be written

where are smooth functions. Given a tangent vector , the form evaluates to . This is a dot product with the vector field , which is why 1-forms are sometimes identified with vector fields in .

2-forms. A 2-form takes two tangent vectors and returns a number. In , every 2-form can be written

We will define the wedge product momentarily. For now, note that a 2-form in also has three components, so it too can be identified with a vector field. But this identification depends on the dimension and the metric, as we will see.

-forms. An -form on takes tangent vectors and returns a number. Every -form is a scalar multiple of , so the space of -forms is one-dimensional at each point. An -form is a volume form: it measures oriented volume.

Remark (Dimension count for -forms).

The alternating property forces every -form with to be zero, because any vectors in must be linearly dependent when , and the alternating property makes the form vanish on linearly dependent inputs. The number of linearly independent -forms at each point in is .

3.2. The wedge product

The wedge product is the operation that builds higher-degree forms from lower-degree ones. It is the exterior algebra analogue of multiplication.

Definition .

The wedge product (or exterior product) of a -form and a -form is the -form defined by

where the sum runs over all permutations of , and is the sign of the permutation.

The full permutation formula [eq:wedge] is useful for proofs, but in practice the wedge product is computed using the following rules.

Proposition .

The wedge product satisfies:

  1. Bilinearity. , and similarly in the second argument. Also for any constant .

  2. Associativity. .

  3. Graded commutativity. If is a -form and is a -form, then

In particular, for all , and for all .

Proof of graded commutativity

Define the permutation that moves the last elements before the first elements: for and for . This permutation has sign (it is the product of transpositions). Substituting in the sum [eq:wedge] relabels the arguments and swaps the roles of and , introducing the sign .

Example (Wedge products in ).

Let and be 1-forms in . Using bilinearity, , and :

The components are exactly those of the cross product . The wedge product of two 1-forms in is the exterior algebra version of the cross product.

3.3. The exterior derivative

The exterior derivative is the universal differentiation operator for differential forms. It generalises the gradient, curl, and divergence of vector calculus into a single operation.

Definition .

The exterior derivative is the unique linear operator that takes -forms to -forms and satisfies:

  1. On 0-forms. If is a smooth function, then . This is the total differential (the gradient written as a 1-form).

  2. Leibniz rule. For a -form and any form ,

  1. Nilpotency. for every form .

These three properties determine uniquely. For a general -form (where the sum is over increasing multi-indices ), the exterior derivative is

Example (The exterior derivative recovers grad, curl, and div).

In with coordinates :

Gradient (d on 0-forms). For a function :

Under the identification of 1-forms with vector fields, this is .

Curl (d on 1-forms). For :

Under the identification of 2-forms with vector fields (via the Hodge star), this is .

Divergence (d on 2-forms). For :

The coefficient is .

Remark ( unifies vector calculus identities).

The classical identities (curl of gradient is zero) and (divergence of curl is zero) are both special cases of . This single identity, which is a consequence of the equality of mixed partial derivatives, unifies all "exactness" results of vector calculus.

The nilpotency gives us a cochain complex of smooth forms, the de Rham complex:

where denotes the space of smooth -forms on . This is the continuous analogue of the discrete cochain complex from Section 2.

Proof of

It suffices to show for every smooth function (the general case follows by the Leibniz rule and the fact that every -form is a sum of terms ). We compute:

Since and (equality of mixed partials for smooth functions), the terms with indices and cancel pairwise.

3.4. Integration of forms and Stokes' theorem

Differential forms are the natural objects to integrate. A -form is integrated over a -dimensional oriented submanifold, producing a number. The general Stokes' theorem is the master identity that connects integration and differentiation of forms.

Theorem (Stokes' theorem, general form).

Let be a smooth -form and a compact oriented -dimensional manifold with boundary . Then

Remark (Classical integration theorems as special cases).

Every classical integration theorem of vector calculus is a special case of [eq:stokes]:

  • : the fundamental theorem of calculus, .
  • in : Green's theorem.
  • in : the classical Stokes' theorem (relating curl to circulation).
  • in : the divergence theorem.

The discrete coboundary from Section 2 was defined by . Stokes' theorem shows this is the discrete version of : the coboundary is the discrete exterior derivative, and it satisfies the discrete Stokes' theorem exactly, with no approximation.

3.5. A note on integration notation

Remark (Why and not ?).

In multivariable calculus, we write double integrals as and triple integrals as . In the language of differential forms, we should write and .

In with the standard Euclidean metric, the two notations produce the same number. The standard volume form on is , and the Lebesgue measure element is . These coincide because the metric tensor is the identity matrix, so the Riemannian volume form has .

On a curved manifold (or even with curvilinear coordinates), the distinction matters. The Riemannian volume form includes a factor that accounts for the stretching of coordinate lines. In polar coordinates , the volume form is , not , because the Jacobian of the coordinate transformation is . Writing "" in an integral is sloppy shorthand that hides this factor.

The wedge product notation makes the orientation and metric dependence explicit. In this article, we always write when working with differential forms and reserve the juxtaposition for classical integral notation.

4. Whitney forms and discrete-to-continuous

With differential forms, the wedge product, and the exterior derivative in hand, we can now construct the maps between the continuous and discrete worlds. Cochains assign numbers to simplices. Differential forms assign numbers to tangent vectors at every point. The de Rham map turns a continuous form into a cochain by integrating over simplices. The Whitney map goes the other direction: it turns a cochain into a continuous differential form by interpolation. Together, they form a bridge between the continuous and discrete worlds, and the error of this bridge controls the accuracy of every DEC computation.

4.1. Barycentric coordinates

The Whitney map requires a coordinate system that is intrinsic to each simplex. Barycentric coordinates provide exactly this: they express any point inside a simplex as a weighted average of its vertices, with the weights summing to one.

Definition .

Let be a -simplex. The barycentric coordinates of a point are the unique real numbers satisfying

Each is an affine function of , equal to 1 at and 0 at all other vertices: .

Example (Barycentric coordinates on edges and triangles).

On a 1-simplex (edge) , the barycentric coordinates are and . These are just the linear interpolation weights.

On a 2-simplex (triangle) , the barycentric coordinates express as a weighted average of the three vertices. The coordinate equals the ratio of the area of the triangle (opposite to ) to the area of the full triangle .

Remark (Constant differentials ).

The gradients are constant on each simplex (because is affine), and their exterior derivatives are constant 1-forms. These constant 1-forms are the building blocks of Whitney forms.

4.2. The Whitney map

The Whitney map constructs a continuous differential form from a cochain by interpolating with barycentric coordinates. The construction uses the wedge product and exterior derivative from Section 3: the resulting form is piecewise polynomial, smooth on the interior of each simplex, and continuous across shared faces.

Definition .

The Whitney map sends a -cochain to a piecewise smooth -form on the underlying space , defined as follows. For each oriented -simplex , the Whitney -form associated to is

where denotes omission. For a cochain , the Whitney form is

This formula is dense, so let us unpack it for each degree.

Example (Whitney -forms).

For , the Whitney form of a 0-cochain is

This is piecewise linear interpolation: the function that equals at each vertex and is linear on each simplex. Whitney 0-forms are the hat functions of classical finite element analysis.

Example (Whitney -forms).

For , the Whitney form associated to an edge is

This is a piecewise smooth 1-form that is nonzero only on simplices containing the edge . It is the simplest vector field (in the sense of 1-forms) with unit circulation along the edge and zero circulation along all other edges.

Example (Whitney -forms).

For , the Whitney form associated to a triangle is

This is a piecewise constant 2-form (since all the factors are constant on each simplex, and only the factors vary) that integrates to 1 over and to 0 over all other triangles.

4.3. The de Rham map

The Whitney map goes from discrete to continuous. The de Rham map goes the other direction: it converts a continuous differential form into a cochain by integrating over each simplex.

Definition .

The de Rham map sends a smooth -form to the -cochain defined by

for each oriented -simplex . In words: integrate the form over each simplex to get a cochain.

Remark (The de Rham map as sampling).

The de Rham map is the natural "sampling" operation: it converts a continuous field into a discrete one by integration. For 0-forms, (evaluation at the vertex). For 1-forms, (circulation along the edge). For 2-forms, (flux through the triangle). Cochains obtained via the de Rham map are not arbitrary numbers: they are genuine integrals of continuous fields, and they carry geometric meaning.

4.4. The round trip: R, W, and the de Rham theorem

The Whitney and de Rham maps are approximate inverses of each other. The following results make this precise.

Theorem .

For any -cochain ,

The de Rham map composed with the Whitney map is the identity on cochains.

Proof

We must show that for every -simplex . By linearity, it suffices to take to be the indicator cochain of a single simplex (equal to 1 on and 0 on all other -simplices). Then , and we need . This is the normalisation property of Whitney forms, which follows from a direct computation using the integral of products of barycentric coordinates over simplices:

where is the volume of . The factor in the Whitney form definition [eq:whitney-map] is chosen precisely to make this integral equal 1 when . When , the Whitney form vanishes on because at least one of the barycentric coordinates in the formula is identically zero on (corresponding to a vertex of not shared by ).

Theorem .

The Whitney map commutes with the exterior derivative and the coboundary: for any -cochain ,

Equivalently: differentiating the Whitney form gives the same result as first applying the coboundary to the cochain and then taking the Whitney form.

Proof

By linearity, it suffices to check on the basis cochain of a single -simplex . A direct computation shows that on simplices containing , and this is exactly summed over the -simplices containing . The key identity used is and the Leibniz rule for the exterior derivative applied to products of barycentric coordinates and their differentials.

Remark (The discrete-continuous commutative diagram).

This commutativity is the most important property of Whitney forms. It means the following diagram commutes:

The discrete coboundary on cochains is exactly the exterior derivative on Whitney forms. There is no approximation in this step. The only approximation in DEC is in the Hodge star (Section 5), which encodes geometry rather than topology.

4.5. Interpolation error

The other direction of the round trip, , is not the identity on smooth forms. It is an approximation, and the error is controlled by the mesh size.

Theorem .

Let be a smooth -form on a simplicial complex with mesh size (maximum simplex diameter). Then:

where is a constant depending only on the shape regularity of the mesh and the dimension, and is the Sobolev norm of (controlling both the form and its first derivatives).

Proof sketch

On each -simplex , the Whitney form is a polynomial of degree at most 1 (affine in the barycentric coordinates). By the Bramble-Hilbert lemma, the error of the best affine approximation to is bounded by , where is the diameter of . The Whitney interpolant is not the best affine approximation, but it satisfies the same scaling: its error on is bounded by with a constant depending only on the shape regularity (minimum angle condition) of the simplex. Summing over all simplices and using the quasi-uniformity of the mesh gives the global bound.

Corollary .

For a smooth function (a 0-form), the Whitney interpolant is the piecewise linear interpolant, and

The extra power of (compared to the general bound for k-forms) arises because Whitney 0-forms are the standard finite elements, and the Bramble-Hilbert lemma gives a sharper estimate for scalar functions with two derivatives.

Remark (Unifying classical error estimates).

The Whitney interpolation error theorem unifies the error estimates of classical numerical analysis under a single framework. Piecewise linear interpolation error ( in for functions) is the 0-form case. The error of approximating a vector field by its edge circulations (used in edge-based finite elements) is the 1-form case. The error of approximating a flux density by its face integrals (used in face-based finite elements) is the 2-form case. All are controlled by the same geometric quantity: the mesh size and the shape regularity of the simplices.

5. The discrete Hodge star

Everything we have built so far, simplicial complexes, cochains, the coboundary operator, Whitney forms, is purely topological. None of it depends on distances, angles, or volumes. The coboundary matrix is the same whether the simplices are equilateral or wildly deformed. The identity is combinatorial, not geometric.

But to solve PDEs, we must measure things. The Poisson equation [eq:poisson-intro] involves the Laplacian, which depends on the metric (distances and angles). The energy of a heat distribution involves the norm, which requires integration against a volume form. The Hodge star is where the metric enters the DEC framework.

5.1. The dual mesh

Every simplicial complex has a natural dual decomposition of the same domain, constructed from the circumcentres of its simplices. Where the primal mesh decomposes the domain into simplices (triangles, tetrahedra), the dual mesh decomposes it into cells that are roughly perpendicular to the primal elements. The ratio of dual cell volume to primal simplex volume is the Hodge star.

Definition .

The circumcentre of a -simplex is the unique point equidistant from all vertices of . For a triangle, this is the centre of the circumscribed circle. For a tetrahedron, it is the centre of the circumscribed sphere.

Definition .

The circumcentric dual mesh of a simplicial complex is constructed as follows. For each -simplex in , the dual cell is the -dimensional region formed by connecting the circumcentres of all simplices containing . Specifically:

  • The dual of a vertex is the -dimensional region bounded by the perpendicular bisectors of the edges meeting at (a Voronoi cell).
  • The dual of an edge is the -dimensional polygon connecting the circumcentres of the triangles (or higher simplices) sharing .
  • The dual of a triangle (in 3D) is the edge connecting the circumcentres of the two tetrahedra sharing .
Remark (Orthogonality of primal and dual).

The dual mesh is a Voronoi-like decomposition of the same domain. Every primal -simplex has a dual -cell, and they intersect orthogonally (by construction, since circumcentres are equidistant from vertices). This orthogonality is the geometric property that makes the diagonal Hodge star possible.

5.2. Well-centredness

The dual mesh construction assumes that circumcentres lie inside their simplices. When this condition fails (for obtuse triangles, for example), the dual cell volumes can become negative, and the Hodge star breaks down. The following condition guarantees that this does not happen.

Definition .

A simplicial complex is well-centred if the circumcentre of every simplex lies in the interior of that simplex.

Remark (Why well-centredness matters).

If the circumcentre of a triangle lies outside the triangle (which happens when the triangle has an obtuse angle greater than ), the dual cell volumes can become negative. This means the Hodge star matrix has negative entries, and the cochain inner product (which we will define shortly) is no longer positive definite. When the inner product fails, energy estimates fail, stability analysis fails, and the entire convergence theory collapses.

In 2D, a Delaunay triangulation of a point set is well-centred if and only if all triangle angles are acute (strictly less than ). This is a strong condition, but it can always be achieved by inserting additional vertices (Steiner points) into the mesh. In 3D, well-centredness is harder to guarantee, and much of the practical art of DEC meshing is devoted to constructing well-centred tetrahedral meshes.

For meshes that are not well-centred, alternatives exist (the barycentric dual, the diagonal approximation with absolute values), but these sacrifice the exactness of certain properties. We will work exclusively with well-centred meshes in this article.

5.3. The discrete Hodge star

With the dual mesh in place, the Hodge star has a remarkably simple form: it is a diagonal matrix whose entries are ratios of dual cell volumes to primal simplex volumes.

Definition .

The discrete Hodge star is the diagonal matrix with entries

where is the -dimensional volume of the primal simplex and is the -dimensional volume of the dual cell .

Example (Hodge stars on a 2D triangle mesh).

In 2D, consider a triangle mesh. The Hodge star on 0-cochains () has diagonal entries equal to the area of the Voronoi cell around each vertex divided by 1 (the "volume" of a 0-simplex). The Hodge star on 1-cochains () has entries equal to the length of the dual edge (connecting circumcentres of adjacent triangles) divided by the length of the primal edge. The Hodge star on 2-cochains () has entries equal to 1 divided by the area of each triangle (the dual of a triangle is a 0-cell, a point, with "volume" 1).

Remark (The Hodge star encodes geometry).

The coboundary operator is determined entirely by the combinatorics of the mesh (which simplices are faces of which). It does not change if you move the vertices, stretch the simplices, or deform the domain. The Hodge star, by contrast, depends on the geometry: the positions of the vertices, the shapes and sizes of the simplices, and the resulting volumes of the dual cells. This separation is a key feature of DEC: topology is exact, geometry is approximate.

5.4. The cochain inner product

The Hodge star turns the space of cochains into an inner product space, which is essential for defining norms, energies, and adjoint operators. The inner product of two -cochains weights each simplex's contribution by the corresponding Hodge star entry.

Definition .

The discrete inner product on -cochains is defined by

When the mesh is well-centred, all Hodge star entries are positive, and this is a genuine inner product (symmetric, bilinear, positive definite).

Definition .

The discrete norm of a -cochain is

The discrete seminorm of a 0-cochain is

This measures the "energy" of the discrete gradient, analogous to the continuous .

5.5. Convergence of the Hodge star

Theorem .

On a family of well-centred meshes with mesh size and uniformly bounded shape regularity, the discrete Hodge star converges to the smooth Hodge star in the sense that for any smooth -form ,

where is the de Rham map [eq:derham-map] and is the smooth Hodge star.

Proof sketch

On each simplex , the discrete Hodge star approximates the smooth Hodge star via volume ratios. The smooth Hodge star of a constant -form on a simplex has the form plus corrections that depend on the variation of the form across the simplex. These corrections are because the form varies by at most across a simplex of diameter . Summing over all simplices and using the quasi-uniformity of the mesh gives the global bound. The well-centredness condition ensures that the volume ratios are positive and bounded, so no cancellation issues arise.

Remark (Where the DEC error lives).

This theorem tells us precisely where the approximation error in DEC lives. The coboundary is exact (no approximation). The Whitney map introduces interpolation error. The Hodge star introduces metric error. The total DEC error is controlled by the sum of these two contributions, both , leading to for the solution in the norm and in the norm (by a duality argument).

5.6. Example: the 2D simple harmonic oscillator

We extend the 1D SHO computation from Section 2 to two dimensions. The 2D quantum harmonic oscillator has the Schrodinger equation

with exact eigenvalues and degeneracies: (non-degenerate), (doubly degenerate), (triply degenerate), and so on.

Discretisation. Triangulate the square with a Delaunay mesh. The Hodge Laplacian on 0-forms (which we will define formally in Section 6, but preview here) is

The Hamiltonian is where is the diagonal matrix with . The eigenvalue problem is the generalised system .

Results. With and a Delaunay mesh with approximately 2500 interior vertices, the first six eigenvalues are:

LevelExact DegeneracyComputed (mean)Relative error
1.00011.0001
2.00022.0005
3.00033.002

The degeneracies are resolved correctly: the two eigenvalues near agree to , and the three near agree to . On a log-log plot of eigenvalue error versus , the slope is approximately 2, confirming the convergence rate predicted by the theory.

use cartan::simplicial::SimplicialComplex2D;
use cartan::dec::{CoboundaryOperator, HodgeStar};
use cartan::mesh::delaunay_triangulate_square;
use nalgebra_sparse::CsrMatrix;

// Delaunay triangulation of [-6, 6]^2 with ~2500 interior vertices
let mesh = delaunay_triangulate_square(-6.0, 6.0, 50);

// DEC operators
let d0 = mesh.coboundary_matrix(0);   // edges x vertices
let star0 = mesh.hodge_star(0);       // diagonal, vertices
let star1 = mesh.hodge_star(1);       // diagonal, edges

// Hodge Laplacian: L = star1_inv * d0^T * star1 * d0
let star1_d0 = &star1 * &d0;
let laplacian = &d0.transpose() * &star1_d0;

// Potential: V_ii = (x_i^2 + y_i^2) / 2
let potential = mesh.vertex_diagonal(|v| (v.x * v.x + v.y * v.y) / 2.0);

// Generalised eigenproblem: (-0.5 * L + star0 * V) psi = E * star0 * psi
let (h_int, star0_int) = mesh.restrict_to_interior(
  &(-0.5 * &laplacian + &(&star0 * &potential)),
  &star0,
);

let eigenvalues = sparse_generalised_eigsh(&h_int, &star0_int, 6);
for (i, &e) in eigenvalues.iter().enumerate() {
  println!("E_{i} = {e:.4}");
}
Not executable

2D SHO via cartan (requires cartan crate)

Python/NumPy comparison
import numpy as np
from scipy.spatial import Delaunay
from scipy.sparse import lil_matrix, diags, csr_matrix
from scipy.sparse.linalg import eigsh

# --- Grid and Delaunay triangulation ---
n_side = 40
L = 6.0
x = np.linspace(-L, L, n_side)
xx, yy = np.meshgrid(x, x)
points = np.column_stack([xx.ravel(), yy.ravel()])
tri = Delaunay(points)
n_verts = len(points)

# --- Build DEC operators from triangle geometry ---
# Collect unique oriented edges
edge_map = {}
for simplex in tri.simplices:
    for i in range(3):
        e = tuple(sorted((simplex[i], simplex[(i + 1) % 3])))
        if e not in edge_map:
            edge_map[e] = len(edge_map)
n_edges = len(edge_map)

# d0: coboundary operator (n_edges x n_verts)
d0 = lil_matrix((n_edges, n_verts))
for (v0, v1), idx in edge_map.items():
    d0[idx, v0] = -1
    d0[idx, v1] = 1
d0 = csr_matrix(d0)

# Hodge stars from circumcentric duals
star0 = np.zeros(n_verts)  # Voronoi dual areas
star1 = np.zeros(n_edges)  # dual-edge / primal-edge length ratios
for simplex in tri.simplices:
    i, j, k = simplex
    pi, pj, pk = points[i], points[j], points[k]
    area = 0.5 * abs(np.cross(pj - pi, pk - pi))
    # Circumcentre
    D = 2 * (pi[0] * (pj[1] - pk[1]) + pj[0] * (pk[1] - pi[1])
             + pk[0] * (pi[1] - pj[1]))
    if abs(D) < 1e-14:
        cc = (pi + pj + pk) / 3
    else:
        ux = ((pi @ pi) * (pj[1] - pk[1]) + (pj @ pj) * (pk[1] - pi[1])
              + (pk @ pk) * (pi[1] - pj[1])) / D
        uy = ((pi @ pi) * (pk[0] - pj[0]) + (pj @ pj) * (pi[0] - pk[0])
              + (pk @ pk) * (pj[0] - pi[0])) / D
        cc = np.array([ux, uy])
    for v in [i, j, k]:
        star0[v] += area / 3
    for (v0, v1) in [(i,j), (j,k), (i,k)]:
        ek = tuple(sorted((v0, v1)))
        eidx = edge_map[ek]
        mid = 0.5 * (points[v0] + points[v1])
        star1[eidx] += np.linalg.norm(cc - mid) / np.linalg.norm(points[v1] - points[v0])

# --- Assemble Hamiltonian ---
S1 = diags(star1)
Lap = d0.T @ S1 @ d0                       # stiffness matrix
V = 0.5 * (points[:, 0]**2 + points[:, 1]**2)
S0 = diags(star0)
H = -0.5 * Lap + S0 @ diags(V)

# --- Restrict to interior vertices ---
edge_count = {}
for simplex in tri.simplices:
    for i in range(3):
        e = tuple(sorted((simplex[i], simplex[(i + 1) % 3])))
        edge_count[e] = edge_count.get(e, 0) + 1
bnd = sorted({v for (v0, v1), c in edge_count.items() if c == 1 for v in (v0, v1)})
int_mask = np.ones(n_verts, dtype=bool)
int_mask[bnd] = False
int_idx = np.where(int_mask)[0]
H_int = csr_matrix(H.toarray()[np.ix_(int_idx, int_idx)])
S0_int = diags(star0[int_idx])

# --- Solve generalised eigenproblem ---
eigenvalues, _ = eigsh(H_int, k=6, M=S0_int, sigma=0, which='LM')
eigenvalues.sort()
exact = sorted(i + j + 1.0 for i in range(4) for j in range(4))[:6]
for i in range(6):
    err = abs(eigenvalues[i] - exact[i])
    print(f"E_{i} = {eigenvalues[i]:.4f}  (exact {exact[i]:.1f}, error {err:.2e})")
Log-log plot of 2D SHO eigenvalue errors versus mesh spacing, showing O(h^2) convergence including degenerate pairs
Eigenvalue error versus mesh spacing for the 2D quantum harmonic oscillator on a Delaunay triangulation of . The exact eigenvalues include degeneracies ( is non-degenerate, is doubly degenerate, is triply degenerate). All converge at .
Remark (The role of the Hodge star in 2D).

The key difference from the 1D case is the Hodge star. In 1D, the Hodge star on a uniform mesh is a scalar multiple of the identity, so it drops out of the eigenvalue problem. In 2D on an unstructured Delaunay mesh, the Hodge star is a non-trivial diagonal matrix that encodes the local mesh geometry. Its entries (dual-area-to-primal-length ratios for , Voronoi-cell-area for ) vary across the mesh and affect both the eigenvalues and eigenfunctions. The fact that the correct degeneracies and convergence rates emerge from this unstructured computation is a validation of the DEC framework.

6. The discrete Laplacian and Poisson's equation

We now assemble the operators from the preceding sections into a discrete Laplacian that solves the problem posed in Section 0: a geometrically faithful discretisation of the Poisson equation [eq:poisson-intro] that works on arbitrary domains, including the L-shaped domain where the five-point stencil failed.

6.1. The Hodge Laplacian

In the smooth setting, the Laplacian on functions (0-forms) is : apply the exterior derivative, then the Hodge star, then the exterior derivative again, then the Hodge star once more. The general Hodge Laplacian on -forms also includes a term from the codifferential , but on 0-forms this term vanishes, so we focus on the 0-form case.

Definition (Discrete Hodge Laplacian on -forms).

The discrete Hodge Laplacian on 0-cochains is the linear operator

where is the coboundary, is the Hodge star on 1-cochains, and is the Hodge star on 0-cochains.

Each factor has a clear geometric role. The coboundary computes differences along edges (the discrete gradient). The Hodge star converts these edge differences into dual-edge fluxes, weighting each edge by the ratio of dual-edge length to primal-edge length. The transpose sums the incoming fluxes at each vertex (the discrete divergence). The inverse Hodge star normalises by the Voronoi cell area at each vertex. The composition is the discrete divergence of the discrete gradient: the discrete Laplacian.

Remark (Recovery of the five-point stencil).

On a uniform rectangular grid with spacing , the Delaunay triangulation produces right isoceles triangles. The Hodge star entries become: for every edge (the dual edge has the same length as the primal edge in this symmetric configuration), and for every interior vertex (the Voronoi cell is a square of side ). Substituting into [eq:hodge-laplacian] recovers exactly the five-point stencil [eq:five-point], up to the factor absorbed by . The five-point stencil is the Hodge Laplacian on a uniform Cartesian mesh.

Definition (Hodge Laplacian on -forms).

More generally, the Hodge Laplacian on -cochains is

or equivalently , where is the discrete codifferential. For , the second term vanishes (there is no ), recovering [eq:hodge-laplacian].

6.2. The discrete Poisson equation

The discrete Poisson equation is: given a 0-cochain (the source), find a 0-cochain such that

subject to boundary conditions. For Dirichlet boundary conditions ( prescribed on boundary vertices), we partition the vertices into interior and boundary sets, restrict [eq:discrete-poisson] to interior vertices, and move the known boundary values to the right-hand side. The resulting system is sparse, symmetric, and positive definite (on the interior, by the well-centredness of the mesh), and can be solved by a sparse Cholesky factorisation or a conjugate gradient iteration.

Theorem ( convergence of the discrete Poisson solution).

Let be a bounded domain with Lipschitz boundary, and let be a family of well-centred simplicial complexes triangulating with mesh size and uniformly bounded shape regularity. Let be the smooth solution of with Dirichlet boundary conditions, and let be the solution of the discrete Poisson equation [eq:discrete-poisson] on . Then:

where is the Whitney map.

Proof sketch

The proof combines three ingredients from the preceding sections:

  1. Galerkin orthogonality. The discrete Poisson equation is equivalent to the Galerkin condition: for all 0-cochains vanishing on the boundary. This follows from the commutativity of the Whitney map with the exterior derivative ([whitney-commutes]) and the definition of the cochain inner product.

  2. Best approximation. By Galerkin orthogonality and the coercivity of the bilinear form (guaranteed by well-centredness), the discrete solution is the best approximation to the exact solution in the discrete energy norm: .

  3. Interpolation error. The Whitney interpolation error theorem ([whitney-error]) gives , yielding the estimate in . The estimate in follows by the Aubin-Nitsche duality argument.

6.3. The L-shaped domain revisited

Return to the L-shaped domain from Section 0. The exact solution to the Laplace equation has a singularity at the re-entrant corner: .

The five-point stencil on a uniform grid converges at in the energy norm because it cannot adapt to the singularity. The DEC approach, using a triangulation that can be refined near the corner, does significantly better. On a graded mesh with element sizes proportional to the distance from the corner (so that the smallest elements are concentrated where the gradient is largest), the DEC solution achieves the optimal rate in and in , matching the smooth-domain rates. Even the uniform triangular mesh, thanks to the Aubin-Nitsche duality argument, converges at in , already a substantial improvement over the stencil.

The key is that the simplicial complex conforms exactly to the re-entrant corner (no staircase approximation), and the graded mesh resolves the singularity without wasting degrees of freedom in the smooth interior. The Hodge Laplacian on this mesh inherits all the structural properties (symmetry, positive definiteness, exactness of the coboundary) that guarantee convergence, regardless of the domain geometry.

use cartan::simplicial::SimplicialComplex2D;
use cartan::dec::{CoboundaryOperator, HodgeStar};
use cartan::mesh::delaunay_triangulate_polygon;
use nalgebra_sparse::CsrMatrix;

// L-shaped domain vertices (counter-clockwise)
let boundary = vec![
  (-1.0, -1.0), (1.0, -1.0), (1.0, 0.0),
  (0.0, 0.0), (0.0, 1.0), (-1.0, 1.0),
];

// Graded Delaunay triangulation: refine near the re-entrant corner (0,0)
let mesh = delaunay_triangulate_polygon(&boundary, |x, y| {
  let r = (x * x + y * y).sqrt().max(0.01);
  0.02 + 0.15 * r  // element size grows with distance from corner
});

// DEC operators
let d0 = mesh.coboundary_matrix(0);
let star0 = mesh.hodge_star(0);
let star1 = mesh.hodge_star(1);

// Hodge Laplacian: L = star0_inv * d0^T * star1 * d0
let laplacian = mesh.hodge_laplacian_0();

// RHS: f = 0 (Laplace equation)
// Boundary: u(r, theta) = r^(2/3) sin(2*theta/3)
let (l_int, rhs) = mesh.apply_dirichlet(&laplacian, |x, y| {
  let r = (x * x + y * y).sqrt();
  let theta = y.atan2(x);
  let theta = if theta < 0.0 { theta + 2.0 * std::f64::consts::PI } else { theta };
  r.powf(2.0 / 3.0) * (2.0 * theta / 3.0).sin()
});

// Solve: sparse Cholesky
let u_h = sparse_cholesky_solve(&l_int, &rhs);

// Compute L2 error against exact solution
let l2_err = mesh.l2_error(&u_h, |x, y| {
  let r = (x * x + y * y).sqrt();
  let theta = y.atan2(x);
  let theta = if theta < 0.0 { theta + 2.0 * std::f64::consts::PI } else { theta };
  r.powf(2.0 / 3.0) * (2.0 * theta / 3.0).sin()
});
println!("L2 error: {l2_err:.4e}");
Not executable

Poisson on the L-shaped domain via cartan

Python/NumPy comparison
import numpy as np
from scipy.spatial import Delaunay
from scipy.sparse import lil_matrix, diags, csr_matrix
from scipy.sparse.linalg import spsolve

def build_dec_2d(points, simplices):
    """Build d0, star0, star1 from a 2D triangulation."""
    n_v = len(points)
    edge_map = {}
    for s in simplices:
        for i in range(3):
            e = tuple(sorted((s[i], s[(i+1)%3])))
            if e not in edge_map:
                edge_map[e] = len(edge_map)
    n_e = len(edge_map)
    d0 = lil_matrix((n_e, n_v))
    for (v0, v1), idx in edge_map.items():
        d0[idx, v0] = -1; d0[idx, v1] = 1
    d0 = csr_matrix(d0)
    star0 = np.zeros(n_v); star1 = np.zeros(n_e)
    for s in simplices:
        i, j, k = s; pi, pj, pk = points[i], points[j], points[k]
        area = 0.5 * abs(np.cross(pj - pi, pk - pi))
        D = 2*(pi[0]*(pj[1]-pk[1]) + pj[0]*(pk[1]-pi[1]) + pk[0]*(pi[1]-pj[1]))
        cc = (pi+pj+pk)/3 if abs(D)<1e-14 else np.array([
            ((pi@pi)*(pj[1]-pk[1])+(pj@pj)*(pk[1]-pi[1])+(pk@pk)*(pi[1]-pj[1]))/D,
            ((pi@pi)*(pk[0]-pj[0])+(pj@pj)*(pi[0]-pk[0])+(pk@pk)*(pj[0]-pi[0]))/D])
        for v in [i,j,k]: star0[v] += area/3
        for (v0,v1) in [(i,j),(j,k),(i,k)]:
            ek = tuple(sorted((v0,v1))); eidx = edge_map[ek]
            mid = 0.5*(points[v0]+points[v1])
            star1[eidx] += np.linalg.norm(cc-mid)/np.linalg.norm(points[v1]-points[v0])
    return d0, star0, star1

def l_shaped_exact(x, y):
    r = np.sqrt(x**2 + y**2)
    theta = np.arctan2(y, x)
    theta = np.where(theta < 0, theta + 2*np.pi, theta)
    return r**(2/3) * np.sin(2*theta/3)

def l_shaped_points(n, graded=False):
    """Points in [-1,1]^2 \\ (0,1]^2."""
    if graded:
        t = np.linspace(0, 1, n)
        v = np.unique(np.concatenate([-1 + t, t]))
    else:
        v = np.linspace(-1, 1, n)
    xx, yy = np.meshgrid(v, v)
    pts = np.column_stack([xx.ravel(), yy.ravel()])
    return pts[~((pts[:,0] > 1e-10) & (pts[:,1] > 1e-10))]

def solve_l(n, graded=False):
    pts = l_shaped_points(n, graded)
    tri = Delaunay(pts)
    d0, star0, star1 = build_dec_2d(pts, tri.simplices)
    n_v = len(pts)
    L = d0.T @ diags(star1) @ d0
    # Boundary vertices
    ec = {}
    for s in tri.simplices:
        for i in range(3):
            e = tuple(sorted((s[i], s[(i+1)%3]))); ec[e] = ec.get(e,0)+1
    bnd = sorted({v for (v0,v1),c in ec.items() if c==1 for v in (v0,v1)})
    mask = np.ones(n_v, bool); mask[bnd] = False; ii = np.where(mask)[0]
    u_ex = l_shaped_exact(pts[:,0], pts[:,1])
    Ld = L.toarray()
    rhs = -Ld[np.ix_(ii, bnd)] @ u_ex[bnd]
    u_int = spsolve(csr_matrix(Ld[np.ix_(ii,ii)]), rhs)
    u_h = u_ex.copy(); u_h[ii] = u_int
    return 2.0/n, np.sqrt(np.sum(star0 * (u_h - u_ex)**2))

for label, graded in [("Uniform", False), ("Graded", True)]:
    print(f"\n{label} mesh:")
    for n in [15, 20, 30, 40, 60]:
        h, err = solve_l(n, graded)
        print(f"  h = {h:.4f}, L2 error = {err:.4e}")
Side-by-side comparison of uniform and graded Delaunay meshes on the L-shaped domain, with the re-entrant corner at (0,0) highlighted
Delaunay triangulations of the L-shaped domain . Left: uniform spacing. Right: graded mesh with elements concentrated near the re-entrant corner at the origin (red dot), where the solution has an singularity.
Log-log convergence plot comparing uniform mesh at O(h^{4/3}) versus graded mesh at O(h^2) on the L-shaped domain
error versus mesh spacing for the Laplace equation on the L-shaped domain. The uniform mesh converges at (Aubin-Nitsche duality), while the graded mesh recovers the optimal rate.
Remark (Adaptive refinement and the geometry of singularities).

The L-shaped domain example illustrates a general principle. Singularities in elliptic PDE solutions are caused by geometric features of the domain (corners, edges, changes in boundary conditions), and their severity is determined by the local geometry (the interior angle at a corner, the opening angle of a crack). A mesh that resolves these geometric features, by concentrating elements where the solution varies rapidly, recovers the optimal convergence rate. The DEC framework provides the algebraic structure that guarantees this: the Hodge Laplacian on any well-centred mesh satisfies the discrete maximum principle, energy estimates, and Galerkin orthogonality, regardless of how the elements are distributed.

7. Parabolic problems: the heat equation

The Poisson equation is elliptic: it describes a steady state with no time dependence. The heat equation introduces time. Rather than asking "what is the temperature after all transients have died?", we ask "how does the temperature evolve from a given initial distribution?" The DEC discretisation of the heat equation is a direct consequence of the Hodge Laplacian.

7.1. The continuous heat equation

The heat equation on a domain is

with initial condition and boundary conditions (Dirichlet, Neumann, or mixed) on . The solution describes how an initial temperature distribution diffuses over time. Heat flows from hot to cold at a rate proportional to the Laplacian, which measures the local average deviation of from its surroundings.

7.2. The semidiscrete system

Replacing the spatial Laplacian with the Hodge Laplacian [eq:hodge-laplacian] and leaving time continuous gives the semidiscrete heat equation: a system of ODEs for the cochain :

The mass matrix on the left accounts for the fact that different vertices control different amounts of the domain (their Voronoi cells). On a uniform mesh in 1D, and the system reduces to the familiar method of lines for the heat equation.

7.3. Time integration

To integrate [eq:semidiscrete-heat] in time, we discretise the time derivative. Let be the time step and .

Forward Euler (explicit). The simplest choice is

which gives . This is cheap (one matrix-vector multiply per step) but conditionally stable: the time step must satisfy for a mesh-dependent constant , or the solution blows up.

Backward Euler (implicit). Evaluating the right-hand side at time level gives

This requires solving a sparse linear system at each step, but is unconditionally stable: any time step produces a bounded solution. The matrix on the left is symmetric positive definite (by well-centredness), so a single sparse Cholesky factorisation, reused at every time step, makes the cost per step comparable to the explicit method.

Crank-Nicolson (trapezoidal). Averaging the forward and backward Euler gives

This is unconditionally stable and second-order accurate in time (error ), compared to first-order () for forward and backward Euler.

Theorem (Convergence of the DEC heat equation).

Under the hypotheses of [poisson-convergence], the backward Euler DEC solution of the heat equation with time step satisfies

For Crank-Nicolson, the temporal error improves to .

7.4. Example: heat diffusion on a disk

Consider the heat equation on the unit disk with homogeneous Dirichlet boundary conditions ( on ) and initial condition . The exact solution is a sum of Bessel functions, and the temperature decays exponentially to zero as the heat escapes through the boundary.

On a Delaunay triangulation of the disk with approximately 1000 interior vertices, backward Euler with produces the following decay of the maximum temperature:

Time Exact DEC Relative error
0.001.00001.0000
0.050.71530.7148
0.100.51150.5109
0.200.26170.2611
0.500.03500.0348

The solution preserves positivity (the discrete maximum principle) and monotonically decreases, consistent with the continuous problem. The error is dominated by the spatial discretisation () at early times and by the temporal discretisation () at late times.

use cartan::simplicial::SimplicialComplex2D;
use cartan::dec::{CoboundaryOperator, HodgeStar};
use cartan::mesh::delaunay_triangulate_disk;

// Delaunay triangulation of the unit disk, ~1000 interior vertices
let mesh = delaunay_triangulate_disk(1.0, 0.05);
let d0 = mesh.coboundary_matrix(0);
let star0 = mesh.hodge_star(0);
let star1 = mesh.hodge_star(1);

// Stiffness matrix: A = d0^T * star1 * d0
let stiffness = &d0.transpose() * &(&star1 * &d0);

// Backward Euler: (star0 + dt * A) u^{n+1} = star0 * u^n
let dt = 0.001;
let lhs = &star0 + &(&stiffness * dt);
let chol = sparse_cholesky(&lhs);  // factor once, reuse

// Initial condition: u0 = 1 - x^2 - y^2, restricted to interior
let mut u = mesh.interior_cochain(|v| 1.0 - v.x * v.x - v.y * v.y);

for step in 0..500 {
  let rhs = &star0 * &u;
  u = chol.solve(&rhs);  // reuse factorisation
  if step % 50 == 49 {
      let t = (step + 1) as f64 * dt;
      println!("t = {t:.2}, max u = {:.4}", u.max());
  }
}
Not executable

Heat equation on a disk via cartan

Python/NumPy comparison
import numpy as np
from scipy.spatial import Delaunay
from scipy.sparse import lil_matrix, diags, csr_matrix
from scipy.sparse.linalg import splu

# --- Mesh: concentric rings in the unit disk ---
pts = [[0.0, 0.0]]
n_rad, n_ang = 20, 24
for i in range(1, n_rad + 1):
    r = i / n_rad
    nt = max(6, int(n_ang * r))
    for j in range(nt):
        theta = 2 * np.pi * j / nt
        pts.append([r * np.cos(theta), r * np.sin(theta)])
points = np.array(pts)
tri = Delaunay(points)
n_v = len(points)

# --- DEC assembly (same helper as previous cells) ---
edge_map = {}
for s in tri.simplices:
    for i in range(3):
        e = tuple(sorted((s[i], s[(i+1)%3])))
        if e not in edge_map: edge_map[e] = len(edge_map)
n_e = len(edge_map)
d0 = lil_matrix((n_e, n_v))
for (v0, v1), idx in edge_map.items():
    d0[idx, v0] = -1; d0[idx, v1] = 1
d0 = csr_matrix(d0)
star0 = np.zeros(n_v); star1 = np.zeros(n_e)
for s in tri.simplices:
    i, j, k = s; pi, pj, pk = points[i], points[j], points[k]
    area = 0.5 * abs(np.cross(pj - pi, pk - pi))
    D = 2*(pi[0]*(pj[1]-pk[1]) + pj[0]*(pk[1]-pi[1]) + pk[0]*(pi[1]-pj[1]))
    cc = (pi+pj+pk)/3 if abs(D)<1e-14 else np.array([
        ((pi@pi)*(pj[1]-pk[1])+(pj@pj)*(pk[1]-pi[1])+(pk@pk)*(pi[1]-pj[1]))/D,
        ((pi@pi)*(pk[0]-pj[0])+(pj@pj)*(pi[0]-pk[0])+(pk@pk)*(pj[0]-pi[0]))/D])
    for v in [i,j,k]: star0[v] += area/3
    for (v0,v1) in [(i,j),(j,k),(i,k)]:
        ek = tuple(sorted((v0,v1))); eidx = edge_map[ek]
        mid = 0.5*(points[v0]+points[v1])
        star1[eidx] += np.linalg.norm(cc-mid)/np.linalg.norm(points[v1]-points[v0])

# --- Stiffness and boundary restriction ---
A = d0.T @ diags(star1) @ d0
ec = {}
for s in tri.simplices:
    for i in range(3):
        e = tuple(sorted((s[i], s[(i+1)%3]))); ec[e] = ec.get(e,0)+1
bnd = sorted({v for (v0,v1),c in ec.items() if c==1 for v in (v0,v1)})
mask = np.ones(n_v, bool); mask[bnd] = False
int_idx = np.where(mask)[0]
S0_int = diags(star0[int_idx])
A_int = csr_matrix(A.toarray()[np.ix_(int_idx, int_idx)])

# --- Backward Euler time stepping ---
dt = 0.001
lhs = S0_int + dt * A_int
lu = splu(lhs.tocsc())
u = 1.0 - points[int_idx, 0]**2 - points[int_idx, 1]**2

for step in range(500):
    u = lu.solve(S0_int @ u)
    if (step + 1) % 50 == 0:
        print(f"t = {(step+1)*dt:.3f}, max u = {u.max():.4f}")
Maximum temperature versus time for backward Euler DEC heat equation on the unit disk, compared with the exact first eigenmode decay
Heat diffusion on the unit disk. The DEC backward Euler solution (gold) tracks the exact first eigenmode decay (blue dashed), where is the first zero of the Bessel function . The initial condition is .

8. Maxwell's equations and computational electromagnetics

The Poisson and heat equations involve only 0-forms (scalar fields). Maxwell's equations demand the full de Rham complex: the electric field is a 1-form, the magnetic field is a 2-form, charge density is a 3-form, and the equations relating them are the exterior derivative and the Hodge star. DEC discretises Maxwell's equations with the same operators we have already built, and the identity automatically enforces the constraint equations (Gauss's laws) at the discrete level.

8.1. Maxwell's equations in differential forms

On a 3-dimensional domain, Maxwell's equations in the language of differential forms are:

where is the electromagnetic 2-form (the Faraday tensor), is its Hodge dual, and is the current 3-form. In components on (the static case, separating electric and magnetic fields), these become the familiar four equations:

Differential formClassical formName
Faraday's law
No magnetic monopoles
Gauss's law
Ampere-Maxwell

The equation (no magnetic monopoles) and (Faraday) are topological: they involve only the exterior derivative and hold on any manifold, with any metric. The equations involving are metric-dependent: the Hodge star encodes the constitutive relations of the medium (permittivity, permeability).

Remark (The constraint equations are automatic).

The identity means that if holds at time and evolves by , then holds for all time: . Similarly for Gauss's law. In DEC, the discrete identity guarantees that the discrete constraint equations are preserved exactly, with no drift, at every time step. This is a major advantage over finite-difference methods, which must enforce the constraints by additional projection steps or cleaning procedures.

8.2. DEC discretisation

The DEC discretisation assigns each field to the appropriate cochain degree:

FieldContinuousDiscreteStored on
Electric potential 0-form0-cochainvertices
Electric field 1-form1-cochainedges
Magnetic flux 2-form2-cochaintriangles
Charge density 3-form3-cochaintetrahedra

Faraday's law becomes , which is exact (the coboundary is the transpose of the boundary, no approximation). Gauss's law becomes , which is automatically satisfied by if for some 1-cochain (the vector potential). The constitutive relations (, ) are encoded in the Hodge star, which now carries the material parameters.

8.3. Example: electrostatics of a biological cell

Consider the electrostatic potential inside a spherical biological cell of radius , modelled as a dielectric sphere with permittivity surrounded by a medium with permittivity . A point charge at position inside the cell creates a potential that satisfies the Poisson equation , with continuity conditions at the membrane.

In DEC, the variable permittivity enters through the Hodge star: is multiplied by evaluated at the midpoint of each edge (or, more precisely, by the average of over the dual cell of the edge). The discrete Poisson equation becomes

where is the material Hodge star and is the discrete charge distribution (a 0-cochain that is nonzero only at the vertex closest to ).

On a tetrahedral mesh of the cell with approximately 5000 interior vertices and a refined layer near the membrane (where the permittivity jumps), the DEC solution captures the image charge effects that arise from the dielectric mismatch. The potential inside the cell is enhanced relative to the free-space Coulomb potential, because the lower permittivity of the membrane partially reflects the electric field lines back into the cell.

Remark (Material interfaces and the Hodge star).

The ability to encode material properties in the Hodge star, without modifying the coboundary or the mesh topology, is a distinctive feature of DEC. In finite-difference methods, a permittivity jump requires special treatment at the interface (staircase approximation, immersed boundary corrections). In DEC, the interface is simply a change in the diagonal entries of . The coboundary still satisfies , Gauss's law is still automatically enforced, and the convergence theory applies with the material Hodge star in place of the geometric one.

9. Elliptic eigenvalue problems: atomic orbitals

The SHO examples in Sections 2 and 5 solved the Schrodinger equation in 1D and 2D with a harmonic potential. This section extends to 3D with a Coulomb potential, computing the hydrogen atom's energy levels and orbital shapes. The Hodge Laplacian discretises the kinetic energy; the potential is a diagonal 0-cochain; and the eigenvalue problem is a generalised sparse eigenproblem whose solutions are the atomic orbitals.

9.1. The hydrogen atom

The time-independent Schrodinger equation for the hydrogen atom (in atomic units, ) is

on , with as . The exact eigenvalues are for , with degeneracy . The eigenfunctions (orbitals) are products of radial functions and spherical harmonics: the familiar , , , , etc.

9.2. DEC discretisation in 3D

We work on a tetrahedral mesh of a large ball with chosen large enough that the wavefunctions have decayed to negligible values at the boundary (typically Bohr radii for the first few orbitals). The mesh is refined near the origin, where the Coulomb singularity demands higher resolution.

The discrete Hamiltonian is

where is the 3D Hodge Laplacian on 0-forms [eq:hodge-laplacian] (now built from a tetrahedral mesh, with the vertex-to-edge coboundary, encoding edge-to-dual-face volume ratios, and encoding Voronoi cell volumes). The eigenvalue problem is

a generalised sparse eigenproblem. We seek the smallest (most negative) eigenvalues.

9.3. Results: energy levels and degeneracies

On a graded tetrahedral mesh with approximately 15,000 interior vertices (element size near the origin, near ), the first eigenvalues are:

Shell Exact DegeneracyComputed (mean)Relative error

The degeneracies are resolved correctly: the 4 eigenvalues in the shell (one and three states) agree to , and the 9 eigenvalues in the shell agree to . The error grows with because higher orbitals extend further and are less well-resolved by the finite mesh.

Remark (The 3D SHO as a consistency check).

Before attacking the Coulomb potential, one should verify the 3D code against the harmonic oscillator , whose exact eigenvalues and degeneracies () provide a stringent test. On the same tetrahedral mesh, the 3D SHO eigenvalues converge at , confirming that the Hodge Laplacian, the Voronoi-based Hodge star, and the sparse eigensolver are all functioning correctly.

use cartan::simplicial::SimplicialComplex3D;
use cartan::dec::{CoboundaryOperator, HodgeStar};
use cartan::mesh::delaunay_triangulate_ball;

// Graded tetrahedral mesh of B_20, refined near origin
let mesh = delaunay_triangulate_ball(20.0, |r| 0.1 + 0.1 * r);

let d0 = mesh.coboundary_matrix(0);
let star0 = mesh.hodge_star(0);
let star1 = mesh.hodge_star(1);

// Hodge Laplacian on 0-forms
let laplacian = mesh.hodge_laplacian_0();

// Coulomb potential: V_vv = -1/r
let potential = mesh.vertex_diagonal(|v| {
  let r = (v.x * v.x + v.y * v.y + v.z * v.z).sqrt().max(1e-10);
  -1.0 / r
});

// Hamiltonian: H = -0.5 * L + star0 * V
let hamiltonian = -0.5 * &laplacian + &(&star0 * &potential);

// Restrict to interior, solve generalised eigenproblem
let (h_int, s_int) = mesh.restrict_to_interior(&hamiltonian, &star0);
let eigenvalues = sparse_generalised_eigsh(&h_int, &s_int, 14);

for (i, &e) in eigenvalues.iter().enumerate() {
  println!("E_{i} = {e:.6}");
}
Not executable

Hydrogen atom via cartan (requires cartan crate)

Python/NumPy comparison
import numpy as np
from scipy.spatial import Delaunay
from scipy.sparse import lil_matrix, diags, csr_matrix
from scipy.sparse.linalg import eigsh

# --- Graded tetrahedral mesh of a ball of radius R ---
R = 15.0
pts = [[0, 0, 0]]
# Concentric shells with grading: finer near origin
for i in range(1, 16):
    r = R * (i / 15)**1.5          # grade toward origin
    n_phi = max(4, int(8 * (i / 15)))
    for ip in range(n_phi):
        phi = np.pi * (ip + 0.5) / n_phi
        n_theta = max(6, int(12 * np.sin(phi) * (i / 15)))
        for it in range(n_theta):
            theta = 2 * np.pi * it / n_theta
            pts.append([r*np.sin(phi)*np.cos(theta),
                        r*np.sin(phi)*np.sin(theta), r*np.cos(phi)])
points = np.array(pts)
tri = Delaunay(points)
n_v = len(points)

# --- DEC assembly (3D: tetrahedra) ---
edge_map = {}
for s in tri.simplices:
    for i in range(4):
        for j in range(i+1, 4):
            e = tuple(sorted((s[i], s[j])))
            if e not in edge_map: edge_map[e] = len(edge_map)
n_e = len(edge_map)
d0 = lil_matrix((n_e, n_v))
for (v0, v1), idx in edge_map.items():
    d0[idx, v0] = -1; d0[idx, v1] = 1
d0 = csr_matrix(d0)

# Hodge stars: lumped (barycentric) for simplicity
star0 = np.zeros(n_v)
star1 = np.zeros(n_e)
for s in tri.simplices:
    verts = points[s]
    # Tetrahedron volume
    mat = np.column_stack([verts[1]-verts[0], verts[2]-verts[0], verts[3]-verts[0]])
    vol = abs(np.linalg.det(mat)) / 6
    for v in s:
        star0[v] += vol / 4
    for i in range(4):
        for j in range(i+1, 4):
            ek = tuple(sorted((s[i], s[j])))
            eidx = edge_map[ek]
            primal_len = np.linalg.norm(points[s[j]] - points[s[i]])
            # Barycentric dual: vol / (6 * edge_length)
            star1[eidx] += vol / (6 * primal_len)

# --- Hamiltonian ---
Lap = d0.T @ diags(star1) @ d0
V = np.array([-1.0 / max(np.linalg.norm(p), 1e-8) for p in points])
S0 = diags(star0)
H = -0.5 * Lap + S0 @ diags(V)

# --- Restrict to interior ---
ec = {}
for s in tri.simplices:
    for i in range(4):
        for j in range(i+1, 4):
            for k in range(j+1, 4):
                f = tuple(sorted((s[i], s[j], s[k])))
                ec[f] = ec.get(f, 0) + 1
bnd = sorted({v for face, c in ec.items() if c == 1 for v in face})
mask = np.ones(n_v, bool); mask[bnd] = False
int_idx = np.where(mask)[0]
H_int = csr_matrix(H.toarray()[np.ix_(int_idx, int_idx)])
S0_int = diags(star0[int_idx])

# --- Solve generalised eigenproblem ---
eigenvalues, _ = eigsh(H_int, k=10, M=S0_int, sigma=-0.6, which='LM')
eigenvalues.sort()
exact = [-0.5 / n**2 for n in range(1, 4)]  # -0.5, -0.125, -0.0556
print("Hydrogen eigenvalues (Hartree):")
for i, e in enumerate(eigenvalues[:10]):
    print(f"  E_{i} = {e:.6f}")
print(f"\nExact: E_1s = {exact[0]:.4f}, E_2 = {exact[1]:.4f}, E_3 = {exact[2]:.4f}")

The visualisation below shows the exact hydrogen wavefunctions on the -plane. Select quantum numbers to explore the orbital geometries: the number of radial nodes grows with , the angular structure is governed by the spherical harmonic , and the sign changes (blue to red) reflect the nodal surfaces that the DEC eigensolver must resolve.

2p orbital, m = 0 | slowly rotating 3D volume | blue = negative, red = positive

10. Nonlinear problems: the Navier-Stokes equations

Every problem so far has been linear: the Poisson equation, the heat equation, Maxwell's equations, the Schrodinger equation. The Navier-Stokes equations for viscous incompressible flow are nonlinear, because the fluid velocity appears in both the transport and the transported quantity. DEC handles the nonlinearity by discretising the vorticity-stream function formulation, where the topological structure (the de Rham complex) enforces the incompressibility constraint exactly.

10.1. The vorticity-stream function formulation

The incompressible Navier-Stokes equations in 2D are

where is the velocity, is the pressure, and is the kinematic viscosity. The divergence-free constraint is a topological condition: it says the velocity 1-form is coclosed.

In the vorticity-stream function formulation, we define the vorticity (a scalar in 2D, the curl of the velocity) and the stream function (satisfying ). The incompressibility constraint is automatically satisfied, and the Navier-Stokes equations reduce to a single scalar equation:

This is an advection-diffusion equation for the vorticity, with the velocity field recovered from the vorticity by solving (a Poisson equation) and computing .

10.2. DEC discretisation

In the DEC framework, the vorticity is a 0-cochain (a scalar at each vertex), and the stream function is also a 0-cochain. The velocity is a 1-cochain (circulations along edges), recovered from the stream function by the coboundary: , where the Hodge star rotates the gradient 1-form by to give the perpendicular velocity.

The discrete vorticity equation is

where is the discrete advection operator, assembled from the edge circulations of the velocity. At each time step:

  1. Solve for the stream function (a Poisson solve).
  2. Compute edge velocities .
  3. Assemble the advection operator from edge velocities.
  4. Advance by one time step using [eq:dec-vorticity].
Remark (Incompressibility is exact).

The incompressibility constraint is enforced exactly in the DEC discretisation, not approximately. The velocity 1-cochain is coclosed by construction: its discrete divergence is the Hodge Laplacian applied to , which is not zero in general, but the flux through every closed dual 1-cycle is zero (by ). The stream function formulation avoids the need for a pressure Poisson equation or a projection step, both of which introduce splitting errors in classical methods.

The figure below shows the result of this DEC solver on the standard lid-driven cavity benchmark at . The top wall moves with unit velocity to the right, driving a primary recirculation vortex that fills the cavity. The vorticity concentrates at the top corners (where the moving lid meets the stationary walls) and diffuses into the interior, exactly as the continuous solution predicts.

DEC vorticity field for lid-driven cavity flow at Re=100 on a Delaunay triangulation
Vorticity for the lid-driven cavity at , computed with the DEC vorticity-stream function solver on a Delaunay mesh. The primary recirculation vortex fills the cavity, with vorticity concentrated near the driven lid.

10.3. Energy estimates

The cochain inner product provides the natural energy functional.

Theorem (Discrete energy dissipation).

The discrete enstrophy satisfies

The enstrophy is non-increasing, and strictly decreasing unless is constant on all connected components (a discrete harmonic function). This mirrors the continuous energy dissipation estimate .

Proof

Multiply [eq:dec-vorticity] on the left by . The advection term vanishes because the advection operator is skew-symmetric (it transports vorticity without creating or destroying it). The diffusion term gives (non-negative because has positive entries on a well-centred mesh). Therefore .

Remark (Why energy estimates matter for nonlinear equations).

For linear problems (Poisson, heat, Schrodinger), convergence can be proved by the Lax equivalence theorem: consistency plus stability implies convergence. For nonlinear problems like Navier-Stokes, this theorem does not apply. Instead, convergence proofs rely on a priori energy estimates: bounds on the solution's energy that are uniform in the mesh size. The discrete energy dissipation theorem above provides exactly this: the enstrophy is bounded by its initial value, which controls the norm of the vorticity, which in turn controls the velocity through the Poisson equation for the stream function. These estimates, combined with the compactness arguments of Leray and Hopf, yield convergence of the DEC solution to a weak solution of Navier-Stokes as .

The figure below verifies the energy dissipation theorem numerically. Starting from a Taylor-Green-like initial vorticity (sinusoidal in both directions, zero on the boundary), the DEC solver evolves the vorticity under pure diffusion (no advection forcing). The normalised enstrophy is plotted for two viscosities. In both cases the enstrophy is strictly monotone decreasing, as the theorem guarantees. Higher viscosity dissipates faster, exactly as the continuous estimate predicts.

Normalised enstrophy versus time for two viscosities, showing monotone dissipation
Normalised enstrophy for decaying vorticity at two viscosities. The monotone decrease confirms the discrete energy dissipation theorem. Higher produces faster decay.

10.4. Time integration and solver comparison

The DEC framework separates the spatial discretisation (which is geometric and structure-preserving) from the time integration (which is a choice). The spatial operator is the same regardless of how we advance in time, but the choice of time integrator determines the stability, accuracy, and energy behaviour of the full scheme.

Consider the DEC heat equation on the unit disk with on the boundary. Three classical time integrators applied to this semi-discrete system produce strikingly different behaviour:

  • Forward Euler (explicit, first-order): . Unconditionally unstable for the heat equation unless , where is the largest eigenvalue of . The solution blows up within a few time steps at the time step used here.

  • Backward Euler (implicit, first-order): . Unconditionally stable (the implicit solve damps all modes), but introduces temporal diffusion that smears the solution.

  • Classical RK4 (explicit, fourth-order): applies four explicit stages per step. Much more accurate than either Euler variant at the same , but still subject to a CFL stability constraint (satisfied here). The RK4 error is orders of magnitude below backward Euler.

Comparison of forward Euler, backward Euler, and RK4 on the DEC heat equation
Left: maximum temperature versus time for three time integrators on the DEC heat equation. Forward Euler diverges (red, marked unstable), backward Euler is stable but diffusive, and RK4 tracks the exact decay closely. Right: relative error of the two stable methods.

The same spatial discretisation also allows a direct comparison with classical finite differences. On the unit square with the exact Poisson solution , both the 5-point stencil and the DEC cotangent Laplacian converge at in , but the DEC method achieves lower absolute error because the cotangent weights adapt to the Delaunay triangulation's geometry.

Log-log convergence comparison of DEC cotangent Laplacian versus 5-point finite differences for the Poisson equation
error versus mesh spacing for the Poisson equation on . Both the 5-point finite difference stencil and the DEC cotangent Laplacian converge at , but DEC achieves a smaller constant.

11. What was preserved

We began with a failure: the five-point stencil on an L-shaped domain, converging at instead of because the rectangular grid destroyed the geometry of the domain. We asked what geometric structure was lost and how to preserve it.

The answer, developed over the preceding ten sections, is a separation principle: topology is exact, geometry is approximate.

The topological layer consists of the simplicial complex (Section 1), the cochain complex (Section 2), the coboundary operator (Section 2), and the identity . These structures are combinatorial. They do not depend on the positions of the vertices, the shapes of the simplices, or the metric of the ambient space. They are preserved exactly in the DEC discretisation, with no approximation at any stage. The consequences are:

  • Stokes' theorem holds exactly at the discrete level: .
  • Gauss's laws are automatically satisfied: prevents magnetic monopoles from appearing and charge from being created or destroyed.
  • Incompressibility of fluid flow is exact in the stream function formulation.
  • Conservation laws that follow from (charge conservation, mass conservation, vorticity conservation) hold to machine precision.

The geometric layer consists of the Hodge star (Section 5), which encodes distances, angles, volumes, and material properties. This is where the approximation lives. The Hodge star converges at , and the Whitney interpolation error also contributes , giving overall in and in for the Poisson equation.

The classical numerical methods of the standard curriculum are special cases:

Classical methodDEC interpretationWhat it preserves
Finite differencesCoboundary on a Cartesian mesh (accidentally, on uniform grids)
Piecewise linear FEMWhitney -formsGalerkin orthogonality
Edge elements (Nedelec)Whitney -forms commutes with interpolation
Face elements (Raviart-Thomas)Whitney -formsNormal flux continuity
Yee scheme (FDTD)DEC on a Cartesian dual mesh for Maxwell

Each classical method preserves a fragment of the geometric structure by accident, because it was designed for a specific problem on a specific mesh. DEC preserves all of it by construction, because it discretises the entire de Rham complex, not just the particular operator appearing in the PDE at hand.

The price of this generality is small: a well-centred simplicial mesh (which any mesh generator can produce) and a diagonal Hodge star (which costs nothing to invert). The reward is a unified framework in which convergence theorems, energy estimates, and conservation laws hold for every problem simultaneously, from the Poisson equation on an L-shaped domain to the Navier-Stokes equations on a biological cell.

Comments

Loading…

Leave a comment

or comment as guest

$...$ inline · $$...$$ display

0 / 2000