December 2026 · Politecnico di Milano
Atmosphere and Ocean Dynamics — Lecture 8
Prof. Dr. Pedro da Silva Peixoto
Applied Mathematics
Instituto de Matemática e Estatística
Universidade de São Paulo
Visiting Professor at MOX Lab
Politecnico di Milano
Previous knowledge
Local polynomials glued by fluxes: finite volumes that reach high order on any mesh
(Durran 2010, secs. 6.5–6.6; Cotter and Shipton 2012)
Finite elements: local basis functions on any mesh
(Durran 2010, sec. 6.5; Marras et al. 2016)
Model problem: the 1D Poisson problem
\[-u'' = f \text{ on } (0, 1), \qquad u(0) = u(1) = 0\]
\(u\): the unknown; \(f\): a given source; a prime: \(d/dx\)
Multiply by a test function \(v\), with \(v(0) = v(1) = 0\), and integrate:
\[\int_0^1 \big(-u'' - f\big)\,{\color{#1f5ccc} v}\;dx = 0 \quad\text{for every } v\]
Multiply by a test function and integrate: one equation for every test function
(Durran 2010, sec. 6.5; Hesthaven and Warburton 2008)
\[-\int_0^1 u''v\,dx = \int_0^1 u'v'\,dx - \big[u'v\big]_0^1\]
The boundary term vanishes (\(v = 0\) at the ends):
\[{\color{#1f5ccc}\int_0^1 u'\,v'\,dx} = \int_0^1 f\,v\,dx \quad\text{for every } v\]
Integration by parts moves a derivative onto the test function: kinks are allowed
(Durran 2010, sec. 6.5)
Take \(u_h\) and \(v\) from the same finite space, the hat functions \(\ell_j\) (linear Lagrange functions):
\[u_h = \sum_j U_j\,\ell_j, \qquad v = \ell_i\] \[\sum_j \underbrace{\int\ell_i'\ell_j'\,dx}_{S_{ij}}\,U_j = \underbrace{\int f\,\ell_i\,dx}_{F_i}\]
\(\ell_j\): 1 at node \(x_j\), 0 at the others; \(U_j\): nodal values; \(S\): stiffness matrix
Galerkin: one equation per basis function, a sparse linear system
(Durran 2010, sec. 6.5.1)
On a uniform mesh of size \(h\), only neighbours overlap:
\[\begin{aligned} S &= \frac{1}{h}\,\mathrm{tridiag}(-1,\,2,\,-1) && \text{(stiffness)}\\ M &= \frac{h}{6}\,\mathrm{tridiag}(1,\,4,\,1) && \text{(mass)} \end{aligned}\]
Linear elements on a uniform mesh: the stiffness matrix is the finite-difference Laplacian
(Durran 2010, sec. 6.5.1)
From now on a problem in time, transport:
\[u_t + c\,u_x = 0\]
\(u\): the transported field; \(c\): constant advection speed; periodic domain
Hats (P1): \(M\dot U = -c\,\big[\textstyle\int\ell_i\ell_j'\,dx\big]\,U\); row \(j\):
\[\frac{\dot U_{j-1} + 4\dot U_j + \dot U_{j+1}}{6} = -c\,\frac{U_{j+1} - U_{j-1}}{2h}\]
\(U_j\): nodal values; \(\dot U_j = dU_j/dt\); \(k\): wavenumber; \(\omega\): numerical frequency
Continuous: one value per node. Discontinuous: two values per face.
But: \(M^{-1}\) couples all unknowns, a global solve every step; and nothing damps the noise
Let the solution jump between elements: discontinuous Galerkin
(Durran 2010, sec. 6.5.1; Hesthaven and Warburton 2008)
Broken space: on each element \(K_j\), a polynomial of degree \(p\); no continuity between elements:
\[V_h = \{\,v :\; v|_{K_j} \in \mathbb P_p \text{ for every } K_j\,\}\]
\(\mathbb P_p\): polynomials of degree \(\le p\); \(K_j\): the elements
But: what happens at the faces, where \(u_h\) jumps?
DG: a polynomial in each element, free to jump at the faces
(Cockburn 2003; Hesthaven and Warburton 2008)
Test with \(v\) that lives on \(K_j\) only; integrate over \(K_j\); move the derivative to \(v\):
\[\int_{K_j}\!\partial_t u_h\,v\,dx - \int_{K_j}\! c\,u_h\,\partial_x v\,dx + {\color{#1f5ccc}\Big[\hat F\,v\Big]_{x_{j-1/2}}^{x_{j+1/2}}} = 0\]
\(u_h\): the DG solution; \(\hat F\): the numerical flux at a face; \(x_{j\pm1/2}\): the faces of \(K_j\)
Integrated over one element, the equations meet the neighbours only at the faces
(Durran 2010, sec. 6.6; Hesthaven and Warburton 2008)
At a face, \(u_h\) has two values. Choose one flux, the same for both elements:
\[\hat F = c\,u^- \quad (c > 0): \textbf{upwind}\]
\(u^-\), \(u^+\): the values of \(u_h\) just left and right of the face
One flux per face, the same for both elements: consistent and conservative
(Cockburn 2003; LeVeque 2002)
With \(u_h|_{K_j} = \sum_l U_{j,l}\,P_l\) and \(v = P_i\) (polynomials of degree \(\le p\), for instance Legendre):
\[M_K\,\frac{dU_j}{dt} = R\big(U_j,\; U_{j-1}\big)\]
\(U_j\): the coefficients of element \(j\); \(M_K\): its mass matrix; \(R\): volume and face terms
DG = a polynomial in each element + numerical fluxes at the faces
(Hesthaven and Warburton 2008; Cockburn 2003)
\(p = 0\): \(u_h = U_j\) on \(K_j\), \(v = 1\), \(\partial_x v = 0\):
\[h\,\frac{dU_j}{dt} = -\big(c\,U_j - c\,U_{j-1}\big)\]
\(U_j\): the mean of \(u\) on \(K_j\); \(h\): element size
The upwind (donor cell) finite-volume scheme
DG with p = 0 is the upwind finite-volume scheme: DG is finite volumes with polynomials inside
(Cockburn 2003; LeVeque 2002)
With orthogonal polynomials each element is a tiny spectral method
(Hesthaven and Warburton 2008; Durran 2010, sec. 6.6.1)
L2 error after one revolution of \(\sin 2\pi x\), periodic, \(c = 1\); upwind flux, SSP-RK3, Courant number \(0.1/(2p+1)\)
| \(p = 0\) | 1.26 |
| \(p = 1\) | 0.41 |
| \(p = 2\) | 0.21 |
| \(p = 3\) | 0.13 |
Courant number \(c\Delta t/h\). For Runge–Kutta of order \(p+1\) the limit is \(1/(2p+1)\) (Cockburn 2003); for large \(p\) it falls like \(p^{-2}\) (Hesthaven & Warburton, §4.8)
Higher degree: much smaller errors for smooth fields, at a smaller time step
(Cockburn 2003, sec. 3.3; Hesthaven and Warburton 2008, sec. 5.7; Shu and Osher 1988; Gottlieb et al. 2001)
Semi-discrete (exact in time), a wave \(e^{ikx}\): \(du/dt = \lambda u\). Left: phase speed \(-\mathrm{Im}\,\lambda/k\) over \(c\); right: damping rate \(-\mathrm{Re}\,\lambda\). DG: \(\lambda\) of the physical mode of the element-to-element (Bloch) problem. \(\Delta x = h/(p+1)\): same number of unknowns
DG moves the resolved waves at almost the right speed and damps only the unresolved ones
(Hesthaven and Warburton 2008; Durran 2010, sec. 6.6)
Notebook 08a (open in Colab · download): discontinuous Galerkin for advection in 1D, in a few lines of numpy.
A hump and a square wave after one revolution, 96 unknowns: DG with p = 0, 1, 2
Predict, run, explain: write down what you expect before each run
DG in a few lines: order \(p + 1\) where smooth, overshoots in a narrow band at jumps
(Hesthaven and Warburton 2008; Cockburn 2003)
Godunov’s theorem (Godunov 1959). A linear scheme for the advection equation that never creates new extrema (monotonicity preserving) is at most first order accurate.
High order where the solution is smooth; the upwind flux keeps it clean
(Godunov 1959; Durran 2010, sec. 5.2; Cockburn 2003)
For \(\partial_t q + \nabla\cdot(\mathbf u\,q) = 0\) on each element \(K\) of a mesh:
\[\begin{gathered}\int_K \partial_t q\,v\,dx - \int_K q\,\mathbf u\cdot\nabla v\,dx + \oint_{\partial K}\hat F\,v\,ds = 0,\\ \hat F = (\mathbf u\cdot\mathbf n)\,q^{\text{up}}\end{gathered}\]
\(q\): tracer; \(\mathbf u\): velocity; \(\mathbf n\): outward normal of \(K\); \(q^{\text{up}}\): \(q\) on the upwind side
In 2D the same weak form: integrals over the element, fluxes through its faces
(Hesthaven and Warburton 2008; Cockburn 2003)
\[\int_K \phi\,\partial_t q\,dx = \int_K q\,\mathbf u\cdot\nabla\phi\,dx - \oint_{\partial K}\phi\,(\mathbf u\cdot\mathbf n)\,q^{\text{up}}\,ds\]
\(K\): one element, \(\partial K\): its boundary, \(\mathbf n\): outward normal; \(\phi\): test function; \(q^{\text{up}}\): the value of \(q\) on the upwind side
V = FunctionSpace(mesh, "DQ", 1) # broken polynomials
phi = TestFunction(V)
n = FacetNormal(mesh)
un = 0.5*(dot(u, n) + abs(dot(u, n))) # max(u.n, 0)
a = phi*dq*dx # mass matrix
L = (q*dot(u, grad(phi))*dx # volume term
- (phi('+') - phi('-')) # faces
*(un('+')*q('+') - un('-')*q('-'))*dS
- phi*dot(u, n) # boundary
*conditional(dot(u, n) < 0, q_in, q)*ds)dx: elements; dS: interior faces, sides '+', '-'; ds: boundaryWrite the weak form, Firedrake writes the code
(Rathgeber et al. 2016) · Demo: firedrakeproject.org: DG advection
Notebook 08b (open in Colab · download): the weak form as code, DG advection on a 2D mesh with Firedrake.
DQ1 on 40 × 40 squares: the initial shapes and one rotation
❗ 4.1: the polynomial degree. Predict, run, explain; the install cell first (a few minutes)
Write the weak form, run a 2D DG model
(Rathgeber et al. 2016; Hesthaven and Warburton 2008)
Shallow water: velocity \(\mathbf u \in V^1\), height \(\eta \in V^2\). Compatible:
\[\nabla\cdot V^1 = V^2\]
\(V^1\): velocity space, normal components continuous across edges; \(V^2\): height space, discontinuous
Compatible finite elements: the C-grid on any mesh, at any order
(Cotter and Shipton 2012; Melvin et al. 2019)
From \(\partial_t\mathbf u + f\mathbf u^\perp = -g\nabla\eta\), \(\partial_t\eta + H\nabla\cdot\mathbf u = 0\): test with \(\mathbf w \in V^1\), \(\phi \in V^2\); the gradient by parts:
\[\begin{aligned} \int \mathbf w\cdot\partial_t\mathbf u + f\,\mathbf w\cdot\mathbf u^\perp - {\color{#1f5ccc}g\,(\nabla\cdot\mathbf w)\,\eta} &= 0\\ \int \phi\,\partial_t\eta + H\,\phi\,\nabla\cdot\mathbf u &= 0 \end{aligned}\]
\(\mathbf w\), \(\phi\): test functions; \(\mathbf u^\perp = \mathbf k\times\mathbf u\), \(\mathbf k\): unit vertical; \(H\): mean depth; \(\psi\): streamfunction
Geostrophic adjustment, BDM1 × DG0 (notebook 08c).
Compatible spaces conserve energy and keep geostrophic balance exactly
(Cotter and Shipton 2012; Vallis 2017, sec. 3.9)
Notebook 08c (open in Colab · download): rotating shallow water with compatible finite elements.
After 2 days, from a 1 m bump of radius 150 km (deformation radius \(L_d = 99\) km): with and without rotation
A demo or at home; ❗ 4.1: the bump radius against \(L_d\). Predict, run, explain
Compatible elements in a notebook: energy and balance kept to round-off
(Cotter and Shipton 2012; Rathgeber et al. 2016)
Compatible elements keep the physics of the shallow water equations: energy, balance, waves
(Cotter and Shipton 2012; Vallis 2017, sec. 3.9)
But: which spaces, and why those?
A dynamical core: a mesh, compatible spaces, the equations in weak form, a time stepper
(Bendall et al. 2020; Shipton et al. 2018) · Code: github.com/firedrakeproject/gusto
\[H^1 \xrightarrow{\;\nabla^\perp\;} H(\mathrm{div}) \xrightarrow{\;\nabla\cdot\;} L^2, \qquad \nabla\cdot\nabla^\perp = 0\]
\(V^0 \subset H^1\) (streamfunction, vorticity), \(V^1 \subset H(\mathrm{div})\) (velocity), \(V^2 \subset L^2\) (depth), as in Cotter & Thuburn 2014
Each variable lives in the space that matches what the equations do to it
(Cotter and Shipton 2012; Cotter and Thuburn 2014; Natale et al. 2016)
\[\partial_t\mathbf u + (\zeta + f)\,\mathbf u^\perp + \nabla\!\left(g(D + b) + \tfrac12|\mathbf u|^2\right) = 0, \qquad \partial_t D + \nabla\cdot(D\mathbf u) = 0\]
\(\zeta\): relative vorticity; \(D\): fluid depth; \(b\): height of the orography
The fast part (gravity waves, rotation), linearized about rest, \(D = H + \eta\); tests \(\mathbf w \in H(\mathrm{div})\), \(\phi \in L^2\); the pressure term integrated by parts (no boundary on the sphere):
\[\begin{aligned} \int \mathbf w\cdot\partial_t\mathbf u + f\,\mathbf w\cdot\mathbf u^\perp - g\,{\color{#1f5ccc}(\nabla\cdot\mathbf w)}\,\eta\;dA &= 0\\ \int \phi\,\partial_t\eta + H\,\phi\,{\color{#1f5ccc}\nabla\cdot\mathbf u}\;dA &= 0 \end{aligned}\]
Only the divergence of the velocity appears: \(\mathbf u, \mathbf w \in H(\mathrm{div})\) is enough, and \(\eta \in L^2\) needs no derivative at all
The same linear system as in compatible elements (2/2), now on the sphere
But: and the nonlinear transport terms?
Velocity in \(H(\mathrm{div})\), depth in \(L^2\): exactly the derivatives the fast terms need
(Cotter and Shipton 2012; Shipton et al. 2018)
The upwind flux of DG (3/4).
The slow part, transport by the wind, on each triangle \(K\), integrated by parts (DG, this lecture):
\[\int_K \phi\,\partial_t D - \int_K \nabla\phi\cdot\mathbf u\,D + \oint_{\partial K}\phi\,(\mathbf u\cdot\mathbf n)\,\tilde D = 0\]
\(D\): fluid depth (free-surface height minus the orography \(b\)); \(\phi\): test function (as in Cotter & Shipton 2012)
Slow transport: explicit and upwind; fast waves: implicit and compatible
(Shipton et al. 2018; Bendall et al. 2020)
Transport: explicit, subcycled: limited only by the wind
Forcing: implicit, trapezoidal; 2 quasi-Newton iterations, each a linear solve about the rest state: a Helmholtz problem, on a mesh
No CFL for gravity waves: Gusto stable at Courant 5.5 (steps of 4 h); LFRic: up to 10 (20 km, 10 min)
Explicit where it is cheap, implicit where the waves are fast: the structure of all global models
(Melvin et al. 2019; Wood et al. 2014; Bendall et al. 2020)
| UM (ENDGame) | LFRic (GungHo) | |
|---|---|---|
| Grid | latitude–longitude | equiangular cubed sphere |
| Waves and forces | finite differences | lowest-order compatible finite elements |
| Horizontal | C-grid | its finite element equivalent |
| Vertical | Charney–Phillips | its finite element equivalent |
| Equations | non-hydrostatic, deep atmosphere | the same |
| Transport | semi-Lagrangian | flux-form semi-Lagrangian (conservative) |
| Time step | semi-implicit | semi-implicit |
Named after Lewis Fry Richardson
LFRic: the same staggering as the UM, rebuilt with compatible elements on the cubed sphere
(Melvin et al. 2024; Bendall and Kent 2025); T. Bendall, “Recent progress on the Met Office’s LFRic-Atmosphere model”, PDEs on the Sphere, São Paulo, 2025
Notebook 08d (open in Colab · download): a dynamical core in a notebook, shallow water on the sphere with Gusto.
Case 5, five days: change of the free surface and of the vorticity; ▲ the mountain
About 3 min of computing (5 with the exercises)
A real dynamical core, step by step: mesh, spaces, equations, time step
(Williamson et al. 1992; Bendall et al. 2020)
A real dynamical core in a notebook: accurate, stable with long steps, and the right waves
(Williamson et al. 1992; Shipton et al. 2018)
Cubed-sphere mesh; red: the nodes of one spectral element of degree 3.
| Model | Centre | Finite elements | Status |
|---|---|---|---|
| LFRic (GungHo core) | Met Office, UK | compatible, lowest order; cubed sphere | operational from 2028 |
| KIM | KIAPS, Korea | spectral elements; cubed sphere | Korea’s global forecast model |
| CAM-SE, E3SM | NCAR, US DOE | spectral elements (HOMME); cubed sphere | climate models |
| NEPTUNE (NUMA core) | US Navy, NRL | spectral elements on any quadrilateral mesh | the US Navy’s model (closed code) |
| ClimaAtmos | CliMA, Caltech | spectral elements in the horizontal; cubed sphere | climate model |
LFRic does not use Firedrake: it is Fortran 2003, with the science code kept apart from the parallel code (PSyKAl layers), and the code generator PSyclone (STFC Hartree Centre) writes the parallel layer. Gusto, in Python on Firedrake, is the test bed of its numerics.
Element methods scale: each element talks only to its neighbours
(Adams et al. 2019; Choi and Hong 2016; Dennis et al. 2012; Kelly and Giraldo 2012; Yatunin et al. 2025) · NEPTUNE fact sheet · ClimaAtmos
Schematic: a mesh of the Adriatic refined towards the coast, not a model’s mesh.
| Model | Finite elements | Use |
|---|---|---|
| ADCIRC (US) | continuous Galerkin, triangles | NOAA’s global tide and surge |
| SCHISM (US) | hybrid finite element–finite volume | NOAA, Atlantic coast |
| SHYFEM (CNR-ISMAR, Italy) | finite elements, triangles | Adriatic, Venice lagoon |
| FESOM 1.4 (AWI) | continuous Galerkin | CMIP6; FESOM2: finite volumes |
| Fluidity (Imperial College) | adaptive tetrahedra | research |
| SLIM (UCLouvain), Thetis | DG | research |
But: continuous elements need a global solve and stabilized advection (FESOM2 moved to finite volumes, three times faster); DG, local and conservative, is so far in research codes
Finite elements are rare in the ocean: they live on the coast, where meshes follow the shore
(Tsujino et al. 2020; Cirano et al. 2025; Danilov et al. 2017; Kärnä et al. 2018) · NOAA STOFS



Left: an unstable jet, relative vorticity (red positive, blue negative) at day 14; DG of degree \(p = 4\) on a Voronoi mesh of 4096 cells, the cell edges in grey
Local and high order on the meshes of operational models: an open research direction
Peixoto, Alves, Fumagalli & Antonietti, M4E 2026 talk; paper in preparation (the jet: its graphical abstract)
Notebook 08e (open in Colab · download), not done in class: the compressible Euler equations in an \(x\)–\(z\) slice.
Skamarock & Klemp (1994): a warm bump of 0.01 K in a wind of 20 m/s, \(N = 0.01\) s⁻¹, 3000 s; \(\theta'\) in mK, grey: the centre carried by the wind
A non-hydrostatic dynamical core in a notebook, with the vertical staggering of ENDGame and LFRic
(Skamarock and Klemp 1994; Bendall et al. 2020)
Notebooks:
08a (open in Colab · download): DG in 1D · 08b (open in Colab · download): DG in 2D with Firedrake
08c (open in Colab · download): compatible shallow water · 08d (open in Colab · download): Gusto on the sphere
08e (open in Colab · download): a vertical slice with Gusto
Finite elements: local, high order, on any mesh, and still conservative
Reading: (Durran 2010, secs. 6.5–6.6; Hesthaven and Warburton 2008; Cockburn 2003; Cotter and Shipton 2012)