This site is version 0.0.1. Most of the code on this site is drafted by an agent and needs review. I apologize for the AI-speak, we are working on rewriting it!
viv-lang.org

← Posts

demoAINumerics

Burgers' equation in nonconservative form puts the shock in the wrong place

For smooth solutions, and are the same equation. For a shock from to they are not. A scheme built on the first form, Godunov's, moves the shock at 0.625, the Rankine-Hugoniot speed , to rounding. Upwinding the second form moves it at 0.5132, on 400, 800 and 1600 cells alike, so refining the grid does not fix it. With the nonconservative shock stays at , with speed 0.

Look inside this program

  • Atlas

    The program’s map: every function and which calls which.

  • There’s no recorded run of this program yet.

Burgers' equation is the simplest model of a nonlinear wave: each value of travels at speed , so faster parts catch up with slower ones and the profile steepens until it breaks into a jump, a shock. Past that point the derivative does not exist and the differential equation says nothing. What still holds is the integral form: the amount of between two points changes by what flows in at one end minus what flows out at the other, with flux . Applied to a box around a jump from to moving at speed , it gives the Rankine-Hugoniot condition , which for Burgers is .

The runs here start from a step, for and for , on , with the two states held in a ghost cell at each end, and time step . The Python reference, posts/refs/burgers-in-nonconservative-form-puts-the-shock-in-the-wrong-place.py, runs both schemes separately (output beside it).

Two schemes

A conservative scheme updates each cell by the difference of the fluxes through its two faces: . Whatever leaves one cell enters its neighbor, so the total changes only by the fluxes through the two ends of the domain. Godunov's flux is the flux of the exact solution of the jump between the two neighbors; for Burgers it is .

The nonconservative scheme discretizes the obvious way. Every here is positive, so information comes from the left and upwinding takes the left difference: . On smooth data this is a consistent first-order scheme. At a shock the product is a value that jumps times a derivative that is infinite, and the scheme's answer depends on how it approximates that product.

Where the shock goes

Both runs use 800 cells (, 800 steps to ). The shock position is read from the mass: a step from to at holds , so follows from . The speed is the distance moved between and , divided by , which leaves out the first steps, while the profile forms.

Godunov's shock moves at 0.625 to rounding. The mass it holds changes by exactly the inflow per unit time, and that forces the Rankine-Hugoniot speed, whatever the smeared profile looks like. The nonconservative scheme moves its shock at 0.5132. By it has lost 0.085 of mass that the inflow brought in: about , the mass a step would lose by lagging behind at that rate.

Printed

s_cons: 0.625
s_nonc: 0.513186
gain_cons: 0
gain_nonc: -0.0847576
Burgers, uL=1, uR=0.25, at t=1 (800 cells)
start, t = 0exact: shock at x = 0.625conservative (Godunov)nonconservative (uux upwinded)
00.51.0−0.500.51.01.5xu

Tests 4 of 4 pass

  • Godunov's shock moves at the Rankine-Hugoniot speed (1 + 0.25)/2 = 0.625, to 1e-13 (passes)
  • its mass changes by exactly the inflow through the ends, to 1e-15 (passes)
  • the nonconservative shock moves at 0.51319, 18% slow (the Python reference: 0.5131859) (passes)
  • and it has lost 0.0848 of mass by t = 1, near (1 - 0.25)(0.625 - 0.5132) = 0.0838 (passes)

Refining the grid does not help

The last cell repeats the nonconservative run on 400 and 1600 cells, and runs as well. The speeds on 400, 800 and 1600 cells agree to (S_SPREAD): the scheme converges, to a solution with the wrong shock speed. A first-order error would halve with each refinement; this one does not change.

With the shock should move at , and in the nonconservative scheme its speed is 0. The cell just right of the jump has , so its update is zero whatever its neighbor holds. It stays 0 at every step, and the jump never advances. Godunov's scheme moves this shock at to rounding.

Printed

S_GRIDS: [0.513188, 0.513186, 0.513187]
S_SPREAD: 2.4583e-06
0.5
0
Shock position from the mass (uR=0.25)
Rankine-Hugoniot, x = 0.625 tconservativenonconservative
00.20.40.600.20.40.60.81.0txs

Tests 3 of 3 pass

  • on 400, 800 and 1600 cells the nonconservative speed is 0.513187 to 2e-6 (the Python reference: 0.5131884, 0.5131859, 0.5131874) (passes)
  • the speeds on 400, 800 and 1600 cells agree to 3e-6 (passes)
  • with u_R = 0 Godunov's shock moves at 1/2 and the nonconservative one stays at x = 0 (passes)

Checked when the site was built: 7 of 7 tests passed, in under 0.1 s. Download 2026-09-25-burgers-in-nonconservative-form-puts-the-shock-in-the-wrong-place.viv