Finite Element Module for Julia that focusses on gradient-robust discretisations and multiphysics problems
Author chmerdon
16 Stars
Updated Last
10 Months Ago
Started In
December 2019

Build status DOI


finite element module for Julia focussing on gradient-robust finite element methods and multiphysics applications, part of the meta-package PDELIB.jl


  • solves 1D, 2D and 3D problems in Cartesian coordinates
  • several available finite elements (scalar and vector-valued, H1, Hdiv and Hcurl on different geometries), see here for a complete list
  • finite elements can be broken (e.g. piecewise Hdiv) or live on faces or edges (experimental feature)
  • grids by ExtendableGrids.jl
  • PDEDescription module for easy and close-to-physics problem description (as variational equations) independent from the actual discretisation
  • Newton terms for nonlinear operators are added automatically by automatic differentiation (experimental feature)
  • solver can run fixed-point iterations between subsets of equations of the PDEDescription
  • time-dependent problems can be integrated in time by internal backward Euler or Crank-Nicolson implementation or via the external module DifferentialEquations.jl (experimental)
  • reconstruction operators for gradient-robust Stokes discretisations (BR->RT0/BDM1 or CR->RT0 in 2D/3D, and P2B->RT1/BDM2 in 2D, more to come)
  • plotting via functionality of GridVisualize.jl
  • export into csv files (or vtk files via WriteVTK.jl interface of ExtendableGrids.jl)

Quick Example

The following minimal example demonstrates how to setup a Poisson problem.

using GradientRobustMultiPhysics
using ExtendableGrids

# build/load any grid (here: a uniform-refined 2D unit square into triangles)
xgrid = uniform_refine(grid_unitsquare(Triangle2D), 4)

# create empty PDE description
Problem = PDEDescription("Poisson problem")

# add unknown(s) (here: "u" that gets id 1 for later reference)
add_unknown!(Problem; unknown_name = "u", equation_name = "Poisson equation")

# add left-hand side PDEoperator(s) (here: only Laplacian with diffusion coefficient 1e-3)
add_operator!(Problem, [1,1], LaplaceOperator(1e-3))

# define right-hand side function (as a constant DataFunction, x and t dependency explained in documentation)
f = DataFunction([1]; name = "f")

# add right-hand side data (here: f = [1] in region(s) [1])
add_rhsdata!(Problem, 1, LinearForm(Identity, f; regions = [1]))

# add boundary data (here: zero data for boundary regions 1:4)
add_boundarydata!(Problem, 1, [1,2,3,4], HomogeneousDirichletBoundary)

# discretise = choose FEVector with appropriate FESpaces
FEType = H1P2{1,2} # quadratic element with 1 component in 2D
Solution = FEVector(FESpace{FEType}(xgrid); name = "u_h")

# inspect problem and Solution vector structure
@show Problem Solution

# solve
solve!(Solution, Problem)

Other Examples

More extensive examples can be found in the documentation and interactive Pluto notebooks can be found in the subfolder examples/pluto for download.


via Julia package manager in Julia 1.6 or above:

# latest stable version
(@v1.6) pkg> add GradientRobustMultiPhysics
# latest version
(@v1.6) pkg> add GradientRobustMultiPhysics#master

Dependencies on other Julia packages: