Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Step 5 -- 2D Linear Convection

Authors
Affiliations
University of Valencia

We now move from 1D to 2D. The governing PDE is the 2D linear advection equation:

∂u∂t+cx∂u∂x+cy∂u∂y=0\frac{\partial u}{\partial t} + c_x \frac{\partial u}{\partial x} + c_y \frac{\partial u}{\partial y} = 0

where (cx,cy)(c_x, c_y) is a constant velocity vector.

What you will learn:

  1. How somax represents 2D fields on a regular grid

  2. The Arakawa C-grid staggering convention

  3. How to run a 2D simulation and visualize the result

  4. How to differentiate through the 2D solver

Background: Arakawa C-grid

On a collocated grid every variable lives at the cell centre. The Arakawa C-grid staggers velocity components: uu sits on the east/west cell faces, vv on the north/south faces, and scalars (pressure, tracers) at cell centres. This arrangement naturally satisfies discrete continuity and avoids the 2dx pressure mode.

For pure scalar advection (this step) we place the scalar uu at cell centres with shape (Ny, Nx).

Grid layout and boundary conditions

In 2D, somax uses the Arakawa C-grid where different variables live at different positions within each cell:

       V_{j+1/2}
    ┌─────●─────┐
    │           │
 U  ●     T     ●  U
i-1/2   (i,j)    i+1/2
    │           │
    └─────●─────┘
       V_{j-1/2}
  • T-points (cell centres): scalars (uu, pp, ω\omega)

  • U-points (east/west faces): x-fluxes

  • V-points (north/south faces): y-fluxes

  • X-points (corners): vorticity (in some formulations)

The full array has shape (Ny, Nx) with a 1-cell ghost ring on all sides:

 ┌───────────────────────────────────┐
 │  ghost  ghost  ghost  ghost  ghost│  ← row 0
 │  ghost  T(1,1) T(1,2) ···   ghost│  ← row 1
 │  ghost  T(2,1) T(2,2) ···   ghost│
 │   ⋮      ⋮      ⋮           ⋮    │
 │  ghost  T(n,1) T(n,2) ···   ghost│  ← row Ny-2
 │  ghost  ghost  ghost  ghost  ghost│  ← row Ny-1
 └───────────────────────────────────┘
        col 0  col 1  ···  col Nx-1

Interior cells are [1:-1, 1:-1]. Ghost cells are filled by boundary conditions before each RHS evaluation.

Periodic BCs (enforce_periodic) copy the last interior row/column to the opposite ghost row/column:

 field[0, :]  = field[-2, :]   (south ghost ← north interior)
 field[-1, :] = field[1, :]    (north ghost ← south interior)
 field[:, 0]  = field[:, -2]   (west ghost ← east interior)
 field[:, -1] = field[:, 1]    (east ghost ← west interior)

1. Create the model and grid

LinearConvection2D(
  params=LinearConvection2DParams(cx=weak_f32[], cy=weak_f32[]),
  grid=ArakawaCGrid2D(Nx=66, Ny=66, Lx=2.0, Ly=2.0, dx=0.03125, dy=0.03125),
  diff=Difference2D(
    grid=ArakawaCGrid2D(Nx=66, Ny=66, Lx=2.0, Ly=2.0, dx=0.03125, dy=0.03125)
  ),
  interp=Interpolation2D(
    grid=ArakawaCGrid2D(Nx=66, Ny=66, Lx=2.0, Ly=2.0, dx=0.03125, dy=0.03125)
  )
)
Grid: Nx=66, Ny=66
Spacing: dx=0.0312, dy=0.0312

2. Initial condition

A 2D Gaussian centred at (1.0,1.0)(1.0, 1.0):

u0(x,y)=exp⁡ ⁣[−(x−1)2+(y−1)22σ2]u_0(x, y) = \exp\!\Bigl[ -\frac{(x - 1)^2 + (y - 1)^2}{2\sigma^2} \Bigr]
State shape: u=(66, 66)

3. Run the simulation

Solution shape: (250, 66, 66)

4. Visualize initial and final fields

We plot only the interior cells (excluding ghost cells) using pcolormesh.

<Figure size 1200x500 with 4 Axes>

The Gaussian translates in the (cx,cy)=(1.0,0.5)(c_x, c_y) = (1.0, 0.5) direction without changing shape -- exactly what the linear advection equation predicts.

5. Cross-section through the centre

A 1D slice along the mid-y row shows the translation more clearly.

<Figure size 800x400 with 1 Axes>

The pulse shifts to the right at speed cx=1.0c_x = 1.0 without changing amplitude -- the hallmark of linear advection.

6. Mass conservation check

Linear advection conserves total mass ∫u dx dy\int u\,dx\,dy. We verify this by tracking the sum over time.

<Figure size 800x300 with 1 Axes>
Mass: initial = 0.251327, final = 0.250106
Relative change: 4.86e-03

7. Gradient through convection speeds

Because somax models are equinox modules, we can differentiate the solution with respect to the advection velocities (cx,cy)(c_x, c_y).

--- Gradient w.r.t. convection speeds ---
  dL/d(cx) = 0.000003
  dL/d(cy) = 0.000025

8. Gradient through the initial state

We can also compute gradients with respect to the initial field -- the building block for data assimilation (4D-Var) in 2D.

<Figure size 1200x500 with 4 Axes>

Summary

ConceptAPI
Create 2D modelLinearConvection2D.create(nx=64, ...)
Grid coordinatesjnp.arange(grid.Nx) * grid.dx
Initial stateLinearConvection2DState(u=u0) with u0.shape == (Ny, Nx)
Grad w.r.t. paramseqx.filter_grad(loss)(model)
Grad w.r.t. statejax.grad(loss)(state0)

Next: Step 6 extends to nonlinear convection in 2D, where the velocity is no longer constant but depends on the solution itself.