Transport on a Voronoi lattice — verification against the 1D diffusion analytical

OOFEM's lattice models aren't just for fracture. The same Voronoi dual mesh carries mass-transport — and on a homogeneous 100×100 mm prism it reproduces the 1D diffusion analytical to within mesh-randomness noise.

Most lattice posts on this site have been about fracture — structural frame elements that lie along the edges of the Delaunay triangulation of a random point set, carrying axial, shear, and bending action and breaking under load. Their cross-sections are the Voronoi cell faces perpendicular to each element (polygon edges in 2D, polyhedron faces in 3D).

The transport lattice is the geometric dual of that. Its conduit elements lie along the Voronoi cell edges (between Voronoi vertices), not the Delaunay edges, and their cross-sections are the Delaunay edges (triangle edges in 2D, tetrahedron faces in 3D) that each Voronoi edge perpendicularly bisects. Mechanical and transport problems share the same underlying Voronoi–Delaunay mesh, but each lives on a different part of the duality: structural on the Delaunay edges, transport on the Voronoi edges.

This first post in a short flow series introduces that transport lattice and checks that it actually solves the right equation.

The verification problem

A 100×100 mm prism, fully homogeneous, saturated pressure prescribed on the bottom face, dry initial condition everywhere else. Linear constant capacity c and permeability k. The 2D lattice transport problem reduces to 1D diffusion in the vertical direction with diffusivity D = k / (vis · c) = 10⁻⁴ m²/s. Total run length is 5 s, so the wetting front penetrates only about 22 mm into the 100 mm specimen — the far face stays essentially dry, and the early-time semi-infinite limit p(y, t) ≈ erfc(y / (2√(D t))) is a useful intuition for what to expect. It would be exact only if there were no flow at all at the far boundary.

Lattice vs analytical

Side by side: a 1D vertical profile (lattice nodes as dots, finite-slab analytical as solid line) and a 2D contour of the pressure field, animated over the 100-step run.

The lattice tracks the analytical curve closely throughout. With a 2 mm node spacing, the agreement is within about 3% in pressure.

Why this matters

For everything that follows — unsaturated flow, heterogeneous matrices, coupled mechanics-transport — this is the baseline. The two subsequent posts (van Genuchten with lumped capacity, transport through a heterogeneous matrix with aggregates) build on top of this same discretisation.

Reproduce

git clone https://github.com/githubgrasp/oofem-examples.git
cd oofem-examples/lattice-flow-2d-erfc
docker run --rm -v "$PWD":/work ghcr.io/githubgrasp/oofem-public:lattice-flow-2d-erfc bash run.sh

The :lattice-flow-2d-erfc image tag is immutable — use :latest instead to track the current OOFEM build (results may drift slightly as the code evolves).

The example folder is at github.com/githubgrasp/oofem-examples/lattice-flow-2d-erfc; issues and questions go on the issue tracker.

Built with OOFEM.

← All posts