Conservation Laws and Riemann Problems
Pdes
A CONSERVATION LAW is a PDE of the form
expressing that a conserved quantity evolves through a flux in the -direction. The integral form — — says that is neither created nor destroyed, only transported. For NONLINEAR , smooth initial data can develop SHOCKS in finite time (see method of characteristics), and the classical PDE breaks down. The theory of WEAK SOLUTIONS, the RIEMANN PROBLEM, and modern shock-capturing FINITE-VOLUME methods all start from this point.
Two canonical examples drive the theory:
- Inviscid Burgers: . The simplest nonlinear scalar conservation law; develops shocks from smooth data. Used as the testbed for almost every shock-capturing numerical method.
- Euler equations of gas dynamics: a system of three conservation laws (mass, momentum, energy) for an inviscid compressible fluid. The foundation of computational fluid dynamics; the standard hyperbolic test that any production CFD code must handle.
Weak solutions
A classical (smooth) solution to ceases to exist once characteristics intersect. To handle the post-shock regime, we relax the requirement to WEAK SOLUTIONS: functions (allowed to have jumps) that satisfy the equation in the integral sense. Test against any smooth compactly-supported function :
A weak solution may have JUMP DISCONTINUITIES at curves . Across such a discontinuity, the Rankine-Hugoniot condition relates the jump in to the jump in flux and the shock speed:
For Burgers' equation specifically, this becomes — the shock moves at the AVERAGE of the values on either side.
The catch: Rankine-Hugoniot alone admits MULTIPLE weak solutions for the same initial data. Some are physical (compressive shocks); some are mathematical ghosts (expansive "shocks" that violate the second law). The ENTROPY CONDITION (Lax, Oleinik) selects the physical solution:
Equivalently: characteristics on BOTH SIDES must run INTO the shock. The physical-shock criterion is the vanishing-viscosity limit: solutions of as always satisfy the entropy condition. Numerical methods that produce the correct entropy solution are called ENTROPY-CONSISTENT.
The Riemann problem
A RIEMANN PROBLEM is the initial-value problem with piecewise-constant initial data:
This is the FUNDAMENTAL BUILDING BLOCK of modern numerical methods for conservation laws. For Burgers' equation, the Riemann solution is:
- Shock case (): if , if , with shock speed . Two characteristics converging.
- Rarefaction case (): if , if , if . A smooth FAN of characteristics filling the wedge.
The two cases are RELATED but qualitatively different: shocks are discontinuous, rarefactions are smooth. The entropy condition picks the right one in each case. Notice the SELF-SIMILAR structure: the solution depends only on , a consequence of the scale invariance of Burgers' equation under .
Godunov's method
The seminal idea (Sergei Godunov, 1959). Discretize as PIECEWISE CONSTANTS on a finite-volume grid: in each cell , the value is the cell average. At each time step, between adjacent cells with values and , the local situation is exactly a RIEMANN PROBLEM with left state and right state . SOLVE that Riemann problem analytically, read off the flux at the cell interface, and update via:
The flux is the value of where is the Riemann solution at the cell interface. For Burgers:
- If (shock): the shock moves at speed . If , the interface sees and the flux is ; otherwise the flux is .
- If (rarefaction): if both sides have the same sign, the flux is the "upwind" one. If they straddle zero, the flux is the SONIC value .
The Godunov flux is the COARSEST upwind reconstruction — first-order accurate in space but FORMALLY ENTROPY-CONSISTENT because it solves the local Riemann problem exactly. Higher-order schemes (Lax-Wendroff, MUSCL, WENO) extend this by using piecewise-LINEAR or piecewise-POLYNOMIAL reconstruction within each cell while keeping the Riemann-flux idea at cell interfaces.
Code: Riemann problems for Burgers
# Godunov scheme for the inviscid Burgers equation u_t + (u²/2)_x = 0.
# Tests:
# (1) Shock-tube Riemann problem (u_L = 1, u_R = 0) — exact shock at
# speed s = (u_L + u_R)/2 = 0.5; shock position at T = 1 is x = 0.5.
# (2) Rarefaction-wave Riemann problem (u_L = 0, u_R = 1) — exact
# solution u(x,t) = max(0, min(x/t, 1)), a fan opening at the origin.
import numpy as np
def godunov_flux(uL, uR):
"""Exact-Riemann flux for f(u) = u²/2."""
if uL > uR: # compressive: shock
s = 0.5 * (uL + uR)
return 0.5 * uL**2 if s > 0 else 0.5 * uR**2
else: # expansive: rarefaction
if uL >= 0: return 0.5 * uL**2 # supersonic right
if uR <= 0: return 0.5 * uR**2 # supersonic left
return 0.0 # sonic point at u = 0
def godunov_burgers(u_init, T, cfl=0.4):
N = len(u_init)
h = 4.0 / (N - 1) # we'll use x in [-2, 2]
u = u_init.copy()
dt = cfl * h / max(np.max(np.abs(u)), 1e-6)
nsteps = int(T / dt)
dt = T / nsteps
for _ in range(nsteps):
F = np.array([godunov_flux(u[i], u[i+1]) for i in range(N - 1)])
u_new = u.copy()
u_new[1:-1] = u[1:-1] - (dt / h) * (F[1:] - F[:-1])
u = u_new
return u
N = 401
x = np.linspace(-2, 2, N)
T = 1.0
# ─── Test 1: shock-tube Riemann problem ────────────────────────────────
u0_shock = np.where(x < 0, 1.0, 0.0)
u_shock = godunov_burgers(u0_shock, T)
# Locate the numerical shock as the midpoint between u > 0.95 and u < 0.05
idx_high = np.where(u_shock > 0.95)[0]
idx_low = np.where(u_shock < 0.05)[0]
shock_num = 0.5 * (x[idx_high[-1]] + x[idx_low[0]])
print(f"(1) Shock-tube Riemann (u_L=1, u_R=0), T = {T}:")
print(f" Analytical shock position: x_s = 0.5")
print(f" Numerical shock position: x_s = {shock_num:.4f}")
print(f" Error: {abs(shock_num - 0.5):.4f}")
# ─── Test 2: rarefaction-wave Riemann problem ──────────────────────────
u0_rare = np.where(x < 0, 0.0, 1.0)
u_rare = godunov_burgers(u0_rare, T)
exact = np.clip(x / T, 0, 1)
exact[x < 0] = 0
err = np.max(np.abs(u_rare - exact))
print(f"\n(2) Rarefaction Riemann (u_L=0, u_R=1), T = {T}:")
print(f" Exact solution: u(x,t) = max(0, min(x/t, 1))")
print(f" ||u_num - u_exact||_inf = {err:.4f}")
print(f" (Godunov resolves the fan; small error is from grid spacing.)") Output:
(1) Shock-tube Riemann (u_L=1, u_R=0), T = 1.0:
Analytical shock position: x_s = 0.5
Numerical shock position: x_s = 0.4950
Error: 0.0050
(2) Rarefaction Riemann (u_L=0, u_R=1), T = 1.0:
Exact solution: u(x,t) = max(0, min(x/t, 1))
||u_num - u_exact||_inf = 0.0513
(Godunov resolves the fan; small error is from grid spacing.) Two outcomes. The shock-tube Riemann problem (compressive, ) produces a clean numerical shock at vs the analytical — 0.005 error from 401 grid points over , i.e. essentially exactly resolved at this discretization. The shock speed is captured exactly by Rankine-Hugoniot; the small position error is from the finite cell width. The rarefaction problem (expansive, ) produces a smooth fan profile, with max error 0.05 (5%) — first-order Godunov is somewhat diffusive at the fan edges, and higher-order reconstruction (MUSCL with limiters) would resolve this more sharply.
Beyond Burgers: systems of conservation laws
The scalar Burgers theory generalizes to SYSTEMS:
The Jacobian has real eigenvalues (assuming the system is HYPERBOLIC), each giving a characteristic FIELD. The Riemann problem decomposes into a sequence of waves — each either a shock, a rarefaction, or a contact discontinuity. The full Riemann solution is the composition of these.
For the EULER EQUATIONS (compressible gas dynamics with conserved variables ), the three characteristic fields are: a sound wave moving LEFT ( with the speed of sound), a CONTACT discontinuity moving at fluid speed , and a sound wave moving RIGHT (). The Riemann problem is the classical "shock tube": initial data with different gas states on the two sides produces a left-moving rarefaction, a middle contact, and a right-moving shock — the structure observed in shock-tube experiments and the standard CFD test case (the SOD shock tube).
Exact Riemann solvers for the Euler equations are non-trivial (involving a nonlinear iteration to find the pressure in the "star region" between the left and right waves), so most practical CFD codes use APPROXIMATE Riemann solvers — Roe, HLL, HLLC, AUSM — that capture the essential wave structure while being cheap to evaluate at each cell interface. The choice of approximate Riemann solver is a major tuning knob in production CFD codes.
The MUSCL / WENO upgrade
First-order Godunov is robust but diffusive. The MUSCL framework (van Leer 1979) extends it to second order by piecewise-LINEAR reconstruction within each cell, with SLOPE LIMITERS (minmod, van Leer, superbee, MC) that prevent spurious oscillations near discontinuities. WENO (weighted essentially non-oscillatory, Shu 1989) reaches arbitrarily high order via weighted polynomial reconstruction. Both are the standard tools for modern shock-capturing CFD: keep the Riemann-flux idea, just feed it more accurately-reconstructed states.
Connections
- Method of characteristics — the analytical foundation; conservation laws are the natural setting for the shock-formation story.
- The three classical equations — the wave equation is a LINEAR conservation law (); nonlinear conservation laws are its hyperbolic cousins where the wave speed depends on the solution.
- Finite differences — upwind FD is a degenerate case of Godunov-type finite volume.
- Finite elements — discontinuous-Galerkin methods unify finite-volume shock capturing with finite-element high-order accuracy.
- Method of lines — once spatial discretization is done, time integration of the resulting ODE system follows the usual MOL framework.