TwoDG.jl

High-order Galerkin methods for PDEs in 2D and 3D — continuous, discontinuous, and hybridizable discontinuous — behind a single solve entry point, running on CPU or GPU from the same code.

Highlights

  • Hybridizable DG (HDG) as a first-class solver. Implicit high-order solves where the globally coupled unknowns live only on element faces: static condensation shrinks the system dramatically, the trace system is solved directly or with preconditioned Krylov iterations, and a cheap local postprocessing step recovers a solution that converges one order faster than the polynomial degree suggests ($k+2$ superconvergence). This extends all the way to steady and unsteady incompressible Navier–Stokes with an exactly divergence-free postprocessed velocity.
  • GPU-resident implicit and explicit solvers. Not just the explicit DG time loop: the batched HDG assembly and recovery and the matrix-free CG iteration also run through KernelAbstractions, so the same code executes on CPU threads or a CUDA GPU (ArrayT = CuArray), with no per-backend forks.
  • High-order curved simplices, in 2D and 3D. Triangles and tetrahedra with isoparametric curved boundaries at arbitrary polynomial order, so p-refinement on circles, airfoils, spheres, and mapped geometries keeps its design accuracy. The whole stack is dimension-generic — the dimension flows from the mesh, and the same equations, boundary conditions, and solvers run on both (see 3D in TwoDG).
  • Three methods, one API. CG, explicit (L)DG, and implicit HDG share the same meshes, equations, and boundary conditions — comparing methods on the same problem is a few lines of code.
  • An open physics surface. A new equation, numerical flux, or boundary condition defined in your own script — using only exported methods — runs in every solver path, CPU and GPU alike (see Extending TwoDG).
  • Composable run-time callbacks. Progress heartbeats, quadrature-exact analysis (conservation drift, energies, L² errors), solution snapshots, CFL-driven step control, and atomic checkpoint/restart, in the spirit of Trixi.jl and Oceananigans.jl (see Callbacks and diagnostics).
  • Numerics you can hand a precision or a stepper. The element type is parametric (T = Float32 runs the whole loop in single precision, on GPU too), and semidiscretize hands the semidiscrete system to the SciML ecosystem when you want adaptive or specialized time integrators.

Installation

TwoDG is not yet registered; install it directly from GitHub:

julia> ]  # enter Pkg mode
pkg> add https://github.com/xkykai/TwoDG.jl

Julia 1.10 or newer is required. Optional capabilities activate through package extensions:

CapabilityActivate with
Plotting (scaplot, meshplot)using CairoMakie (any Makie backend)
GPU executionusing CUDA (or another KernelAbstractions backend)
semidiscretize → OrdinaryDiffEqusing SciMLBase (or any OrdinaryDiffEq solver package)
NACA airfoil meshesusing Gmsh

<!– Images are served from the repository so the docs build stays small. These URLs are the only name-dependent strings outside docs/make.jl. –>


Compressible flow through a channel with a bump (2D Euler, Mach number)


Natural convection in a differentially heated cavity at Ra = 10⁴ (incompressible Navier–Stokes with Boussinesq buoyancy, HDG k = 3): temperature (left) and speed (right)


3D natural convection in a differentially heated cavity at Ra = 10⁵ (incompressible Navier–Stokes with Boussinesq buoyancy, HDG on tetrahedra)


Kovasznay-flow verification of the HDG Navier–Stokes solver: optimal k+1 convergence and k+2 superconvergence of the divergence-free postprocessed velocity u*

Supported features

All four solver families are dimension-generic — the same equations and problems run on triangles and tetrahedra:

EquationsTime / solverBackends
DG / LDG (explicit)convection, convection–diffusion (LDG), first-order wave system, compressible Euler (Roe flux)internal RK4, or any OrdinaryDiffEq stepper via semidiscretize; run-time callbacksCPU + GPU (KernelAbstractions)
HDG (implicit, static condensation)Poisson, steady convection–diffusionDirect sparse LU, GMRES (Krylov.jl, block-Jacobi preconditioned, batched assembly)CPU + GPU trace solve
HDG Navier–Stokessteady/unsteady incompressible NS, Boussinesq buoyancy; superconvergent H(div) postprocessing (2D)Newton + batched direct/GMRES (driver-level API, see examples/hdg/ and examples/hdg3d/)CPU + GPU local solves (trace LU on CPU)
CGPoisson, convection–diffusion–reactionDirect sparse Cholesky/LU, ConjugateGradient / GMRES (matrix-free)Direct(): CPU; iterative: CPU + GPU

Meshes: structured square/L-shape and tetrahedral boxes, unstructured circle (distmesh), cos²-bump duct, Trefftz airfoil (conformal map), NACA 4-digit and tetrahedral Gmsh import (package extension), uniform red refinement (uniref). All support curved isoparametric elements at arbitrary porder; generators attach named boundary tags (boundary_names). A MeshGeometry + discretize two-stage API separates geometry from discretization; 3D results export to ParaView as high-order Lagrange cells (save_vtk, WriteVTK extension).

Where to go next