The FEniCS Project
Theory: solving by writing the weak form
Overview
How is using FEniCS different from other finite element software?
Rather than choosing an analysis type from a menu, you write the weak form of the equation yourself. For the Poisson equation, multiply by a test function v, integrate by parts and write in Python almost exactly as in mathematics: 'a = inner(grad(u), grad(v))*dx', 'L = f*v*dx'. FEniCS's form compiler turns this into element code, DOLFINx assembles the global system and PETSc solves it. Any new constitutive law or coupled problem can be tried as soon as its weak form is written — but mistakes in boundary conditions or function spaces can yield wrong answers without errors. That is why checks against known solutions matter so much.
Weak form of the Poisson equation
u is the unknown, v the test function, f the source and Ω the domain; the two lines on the right are how it is written in FEniCS (UFL).
A project born in Nordic universities
FEniCS began around 2003 among researchers at the University of Chicago and Chalmers University of Technology in Sweden, among others, and later grew with Norway's Simula Research Laboratory at its centre. Since 2019 it has moved to the new DOLFINx implementation, so tutorial code written for the legacy DOLFIN may not run unchanged — watch out for that.
Worked examples
The table comes from an independent Python/SciPy P1-triangle FEM reference implementation, not a DOLFINx run. It uses a unit-square grid with the same diagonal and three-point quadrature. Machine-precision nodal agreement is special to this problem and grid; it is not guaranteed for general P1 meshes or interior interpolated values.
Example 1: tutorial solution u = 1 + x² + 2y² (linear elements, 8 × 8)
With f = −6 and exact Dirichlet data, this special uniform triangle grid gives a reference nodal error of about 1.6×10⁻¹⁵. P1 interpolation inside elements does not reproduce the quadratic exact solution; check domain-wide errors too.
Example 2: convergence for sin(πx)sin(πy) (linear elements)
| Mesh | Unknowns | L2 error | Max nodal error | L2 order |
|---|---|---|---|---|
| 8×8 | 49 | 2.04×10⁻² | 1.27×10⁻² | — |
| 16×16 | 225 | 5.20×10⁻³ | 3.20×10⁻³ | 1.97 |
| 32×32 | 961 | 1.31×10⁻³ | 8.03×10⁻⁴ | 1.99 |
Doubling the divisions cuts the L2 error about fourfold — second order, as theory predicts for linear elements — while unknowns grow about fourfold.
Example 1 has essentially zero error but Example 2 does not. Isn't Example 1 enough?
No. Example 1 has special nodal agreement on a particular grid. Refine a non-polynomial problem and measure L2 and gradient errors. For smooth solutions, suitable meshes and quadrature, P1 typically gives L2 order 2 and gradient order 1. Singularities or reduced regularity can lower rates without an implementation bug. In DOLFINx, assemble norms with fem.assemble_scalar and MPI reduction; do not confuse this with legacy DOLFIN errornorm.
Getting started
- Install DOLFINx via conda or Docker and run the official Poisson tutorial.
- Confirm machine-precision nodal error for u = 1 + x² + 2y².
- Refine with a non-polynomial solution and measure the error order.
- Write your own equation's weak form and verify it the same way with a manufactured solution.
- Parallelise large problems with MPI and choose PETSc solvers and preconditioners.
“The tutorial code won't run”
The first stumbling block with FEniCS is that much example code online targets the legacy DOLFIN (up to 2019). DOLFINx changed how meshes are created, boundary conditions specified, function spaces built and solutions written, so legacy code will not run unchanged. Follow the official DOLFINx tutorial and the demos for your version.
Common mistakes
Mistakes and fixes
| Mistake | Effect | Fix |
|---|---|---|
| Running legacy DOLFIN code | Errors, won't run | Follow DOLFINx examples |
| Boundary markers wrong | Wrong answer without error | Check with a known solution |
| Exact solution interpolated at low degree | Error underestimated | Interpolate in a higher-degree space |
| Comparing nodal values only | Element errors missed | Check order in norms |
| Direct solver on large problems | Out of memory | Iterative solver with preconditioner |
I'd like to learn related topics.
Related pages include the method of manufactured solutions, MMS convergence rate calculation, the MOOSE framework and Elmer Multiphysics.
Frequently asked questions
What is FEniCS?
A collection of open-source libraries for solving partial differential equations by finite elements. You write the weak form in Python with UFL (Unified Form Language) in near-mathematical notation; a form compiler generates the element code and DOLFINx (the current version) assembles and solves. It is widely used to prototype new equations and coupled problems, and in research and teaching.
How do I check that my FEniCS code is right?
Use analytical or manufactured solutions and check boundary and domain errors plus refinement rates. Quadratic-solution nodal agreement is a special-grid property, not a machine-precision guarantee for general linear elements.
How much do quadratic elements help?
In theory the L2 error order rises from 2 to 3. In FEniCS you switch by changing the degree from 1 to 2 in the function space definition. Linear elements gave an L2 error of 1.3×10⁻³ on a 32 × 32 mesh (961 unknowns); quadratic elements tend to reach that accuracy or better on coarser meshes, often needing fewer unknowns for the same accuracy.
References and scope of verification
Numbers are educational reference calculations under the stated assumptions. Sources document theory and setup, not proof that these numerical values were reproduced in each package. Engineering decisions require validation for the actual conditions.
Related Topics
Experience the theory firsthand with the interactive simulator for this field
All Simulators