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:

  1. 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.
  2. 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.