Numerical solution of DIVA / SSA
The DIVA and SSA momentum balances share the same 2D depth-integrated form: a nonlinear elliptic problem for the depth-averaged horizontal velocity , with coefficients that depend on the solution. Yelmo discretises this problem on the Arakawa C-grid (the ac-grid) and linearises it by Picard iteration, freezing at the previous iterate, solving a linear system for the new , relaxing, and repeating until convergence.
Two solvers are provided for the linear step. Both produce the same
solution at interior cells (the two systems are related by a sign and a
cell-area factor), but they differ in the structure of the assembled
matrix and in how boundary conditions are imposed. The choice is made
at runtime via the parameter ydyn.ssa_solver = "residual" | "energy",
which the DIVA solver dispatches on.
Discretisation conventions
Yelmo uses the Arakawa C / staggered AC grid:
- aa-nodes (cell centres): scalars — , , , , (before staggering).
- acx-nodes (right face of each aa-cell): , , .
- acy-nodes (top face): , , .
- ab-nodes (cell corners): cross-coupling viscosity
, obtained by averaging
from its four neighbouring aa-cells
(
stagger_visc_aa_ab).
The two unknowns per cell ( at the right face and at the
top face) are interleaved into a single state vector
,
so the assembled linear system has dimension . The
matrix is stored in CSR format and solved with
LIS (Library of Iterative Solvers for
Linear Systems); the iterative method and preconditioner are configured
at runtime via ydyn.ssa_lis_opt.
Per-row solver masks (ssa_mask_acx, ssa_mask_acy) classify each
ac-node as one of:
0: Dirichlet zero velocity (frozen bed, edge of domain, etc.);-1: Dirichlet prescribed velocity (e.g. observed input);1: solve (interior);3: lateral / calving-front Neumann row driven by the depth-integrated lateral stress .
The two assemblers share the same argument list so they are drop-in
interchangeable from the Picard loop in calc_velocity_diva.
Solver A — residual form (Yelmo v1)
The residual assembler (solver_ssa_ac.f90) builds a
non-symmetric matrix and right-hand side
directly from the strong form of the SSA PDE.
Writing for brevity, the interior row
is a 5-point stencil in plus cross-coupling terms in
on the neighbouring acy-faces, balanced against the basal drag and the
driving stress. Schematically (cell , with on
aa-nodes and on ab-nodes):
The stencil coefficients carry the membrane stretching and shearing,
with the centre coefficient being minus the sum of its four neighbours. The coefficients couple the row to four neighbouring -faces via the and cross-terms in the membrane stress. The row has the analogous structure.
The right-hand side is the driving stress itself (no cell-area factor). The system is non-symmetric, and is solved with a Krylov method such as BiCGStab plus an algebraic preconditioner.
- Lateral / calving-front rows substitute the membrane-stress balance with the prescribed depth-integrated lateral stress in a row-specific stencil.
- Dirichlet rows replace the equation by with the corresponding column kept in place (non-symmetric).
- Free-slip, no-slip and periodic conditions are applied per side via
the boundary-code helper
get_neighbor_indices_bc_codes.
This is the formulation inherited from Yelmo v1 and is the legacy default.
Solver B — energy form (new)
The energy assembler (solver_ssa_ac_energy.f90) builds
the Hessian of a discrete energy functional and solves
for the velocity that minimises that energy.
With frozen during each Picard step the energy is
quadratic, so is
symmetric positive (semi-)definite and the linear step can use a
symmetric Krylov method — CG with an AMG preconditioner — in place of
BiCGStab.
Energy density
The continuum energy density underlying the SSA momentum balance is the sum of a membrane (deformation) term, a basal-drag term, and a gravitational potential-energy term:
The first line is written out for the depth-averaged horizontal strain rates. Stationarity of the integral with respect to reproduces exactly the SSA / DIVA strong form, so any critical point of is a solution of the momentum balance.
Discrete assembly
Yelmo's discrete energy is the cell-by-cell evaluation of on the C-grid, with the derivatives expressed as the natural finite differences between adjacent ac-nodes. The Hessian then has the same stencil graph as the residual matrix but is symmetric in . At inner cells the two formulations are related by an exact algebraic identity (documented in the header of the energy assembler):
So the energy formulation is, at interior cells, the residual formulation rescaled by the cell area and a sign — the physical solution at interior cells is identical to machine precision. Where the two solvers differ is at boundaries:
- Lateral / calving-front BC: the front stress enters the energy as a boundary-work term on the RHS, with the sign determined by the outward normal. This is the variational form of the Neumann condition and is symmetric by construction.
- Dirichlet rows: prescribed values are imposed by static condensation — the prescribed column is multiplied by the known velocity and moved to the RHS — instead of by row replacement. This preserves the symmetry of and so allows CG / AMG to be used without spoiling the SPD structure.
The viscosity staggering aa ab is the same routine
(stagger_visc_aa_ab) used by the residual assembler.
Why bother?
Two practical advantages flow from the SPD structure:
- Linear solver choice: CG with AMG is typically faster and more robust than BiCGStab + ILU for large, well-conditioned SPD systems, and converges monotonically in the energy norm.
- Physical interpretability and discrete consistency: every term in and corresponds to a contribution to a discrete energy. Boundary conditions that are natural for the continuum functional (e.g. Neumann front stress) become natural for the discrete one. This makes it easier to add new physics — e.g. alternative friction laws, additional body forces — in a way that provably preserves the variational structure.
The Picard loop, the viscosity update, the F-integral closure and the basal-stress and 3D velocity diagnostics are identical between the two solvers: only the linear-system assembly differs.