FastFEM was a class project for Software Engineering for Scientific Computing at Princeton University, taught by Henry F. Schreiner and Romain Teyssier, and built with Sacha Escudier and Kentaro Hanson.
The finite element method (FEM) is a numerical way to approximate solutions of partial differential equations (PDEs). FastFEM uses it to solve scalar two-dimensional (2D) parabolic PDEs. Such a problem asks for an unknown field , such as temperature, over a 2D domain . Here, is the geometry itself: it may be a square, an irregular shape, or a shape with holes. The PDE applies inside , while boundary conditions apply along its edges, . FEM transforms the PDE into a solvable system of algebraic equations. Solving that system gives a continuous finite-element field that approximates the exact solution . FastFEM provides the complete workflow, from constructing the geometry () to visualizing the solution on that geometry.
FastFEM solves PDEs of the form
where is the coefficient of the time derivative and is a source term. To solve the PDE, we must also specify how behaves along the boundary. On each boundary segment, the value of can be held fixed (Dirichlet), or its derivative perpendicular to the boundary can be set to zero (Neumann), meaning does not change as we move across the boundary.
FEM rewrites the original differential equation (strong form) by multiplying it by any allowed function , integrating over the entire geometry , and integrating the Laplacian by parts. This gives
If this integral equation (weak form) is satisfied for every allowed , it is equivalent to the original differential equation.
FEM makes the integral equation computable by dividing the geometry into a mesh and defining one simple basis function around each mesh node. A basis function is just an ordinary function: it is at its own node, changes linearly to at neighboring nodes, and is outside the mesh elements touching that node. All finite sums of these building blocks form a limited space of available fields, and FEM searches only within this space. Instead of solving for an arbitrary function , it solves for the finite set of coefficients that multiply the basis functions. It chooses those coefficients by requiring the integral equation to hold for every basis function. Intuitively, among all fields that can be constructed by adding the basis functions with different coefficients, this selects the one that best satisfies the original PDE. The original field problem has now become one equation per coefficient and, after discretizing time, a finite system of algebraic equations.
Using these basis functions, FEM represents the approximate field and its time derivative as
FEM sets for each basis function in turn, giving one equation for each mesh node:
Putting these equations together produces the finite-element system
with
FastFEM evaluates the integrals on each mesh element and assembles the local contributions into the global matrices. Discretizing time then turns the problem into algebraic equations for . For example, when is constant and is the resulting mass matrix, one backward-Euler step is
Solving this system gives the field at the next time step.
To use FastFEM, users construct the 2D geometry from points, lines, surfaces, and holes; label its domains and boundaries; generate a mesh with Gmsh; and define the initial field, , , and boundary conditions. FastFEM assembles the finite-element system and advances the solution in time. Its PyVista-based visualization tools display the mesh and map the solved nodal values back onto the geometry as plots or animations.
The example below solves the scalar wave equation on the unit square:
The field starts as a localized displacement with zero initial velocity and zero derivative perpendicular to the square’s boundary.
FastFEM’s field operations support NumPy and JAX. Using JAX enables automatic differentiation, just-in-time (JIT) compilation, and execution on GPUs.
Read the original report.
Check out the source code on GitHub: github.com/fastfem/fastfem