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 8 -- 2D Burgers’ Equation

Authors
Affiliations
University of Valencia

The 2D viscous Burgers equation combines nonlinear convection (Step 6) with diffusion (Step 7):

∂u∂t+u∂u∂x+v∂u∂y=ν(∂2u∂x2+∂2u∂y2)\frac{\partial u}{\partial t} + u \frac{\partial u}{\partial x} + v \frac{\partial u}{\partial y} = \nu \left( \frac{\partial^2 u}{\partial x^2} + \frac{\partial^2 u}{\partial y^2} \right)
∂v∂t+u∂v∂x+v∂v∂y=ν(∂2v∂x2+∂2v∂y2)\frac{\partial v}{\partial t} + u \frac{\partial v}{\partial x} + v \frac{\partial v}{\partial y} = \nu \left( \frac{\partial^2 v}{\partial x^2} + \frac{\partial^2 v}{\partial y^2} \right)

What you will learn:

  1. How viscosity balances nonlinear steepening

  2. The effect of low vs. high viscosity on the solution

  3. Differentiating through ν\nu for parameter sensitivity

  4. Why Burgers is the gateway to Navier--Stokes

Physics

Burgers’ equation is the simplest PDE that contains both nonlinear advection and diffusion -- the same two ingredients that appear in the Navier--Stokes momentum equation. Low viscosity allows steep gradients (near-shocks); high viscosity smooths everything out. The balance between these two effects determines the solution character and is controlled by the Reynolds number Re=UL/ν\mathrm{Re} = U L / \nu.

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. Both u and v fields receive the same periodic treatment:

 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

Burgers2D(
  params=Burgers2DParams(nu=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)
  ),
  advection=Advection2D(
    grid=ArakawaCGrid2D(Nx=66, Ny=66, Lx=2.0, Ly=2.0, dx=0.03125, dy=0.03125),
    recon=Reconstruction2D(
      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 for both velocity components.

State shapes: u=(66, 66), v=(66, 66)

3. Run the simulation

Solution shapes: u=(250, 66, 66), v=(250, 66, 66)

4. Visualize initial and final fields

<Figure size 1600x450 with 6 Axes>

5. Low vs. high viscosity

We run two simulations with different viscosities from the same initial condition and compare the final fields.

<Figure size 1200x500 with 4 Axes>

Low viscosity preserves sharper gradients (the nonlinear steepening from Step 6 dominates). High viscosity smears the solution out (the diffusion from Step 7 dominates).

6. Cross-section comparison

<Figure size 800x400 with 1 Axes>

7. Gradient through viscosity

We compute ∂L/∂ν\partial \mathcal{L} / \partial \nu where L=∑(u2+v2)\mathcal{L} = \sum (u^2 + v^2). This tells us how the total kinetic energy depends on viscosity -- useful for calibrating sub-grid diffusion.

--- Gradient w.r.t. viscosity ---
  dL/d(nu) = -1006.128723

8. Joint gradient -- viscosity and initial state

--- Joint gradient ---
  max |dL/du0| = 0.735805
  max |dL/dv0| = 0.735805
  dL/d(nu)     = -1006.128723

Summary

ConceptAPI
Create modelBurgers2D.create(nx=64, ny=64, Lx=2.0, Ly=2.0, nu=0.05)
Two-component stateBurgers2DState(u=u0, v=v0)
Viscosity comparisoncreate two models with different nu
Grad w.r.t. ν\nueqx.filter_grad(loss)(model)
Joint gradjax.grad(loss, argnums=(0, 1))(state0, model)

Where we stand: Steps 5--8 have covered the fundamental building blocks of fluid dynamics in 2D: linear advection, nonlinear advection, diffusion, and their combination in Burgers’ equation. The next steps introduce elliptic solvers (Laplace, Poisson) which are needed to enforce incompressibility in the Navier--Stokes equations.