Notebooks · pde/advection_1d
pde/ advection_1d.viv
pde/advection_1d.viv · 1 code cellOpen in the workbenchDownload .vivLook inside this program
- Atlas
The program’s map: every function and which calls which.
There’s no recorded run of this program yet.
Shift+Enter in a cell runs it and moves to the next. Running a cell runs every cell above it too, as one program.
[1]lines 20–92
pi = 3.141592653589793 C = 1.0 NU = 0.5 #: NU the Courant number c dt / dx #| A smooth pulse on the ring. def pulse(x) { return exp(-100.0 * (x - 0.5) * (x - 0.5)) } #| Carry the pulse once around the ring with the upwind scheme; return what comes back. def upwind_lap(n) { x = linspace(0.0, 1.0 - 1.0 / n, n) u = pulse(x) steps = n / (C * NU) for s to steps { u = u - NU * (u - roll(u, 1.0)) } return u } #| The same trip with Lax-Wendroff. def lax_wendroff_lap(n) { x = linspace(0.0, 1.0 - 1.0 / n, n) u = pulse(x) steps = n / (C * NU) for s to steps { right = roll(u, -1.0) left = roll(u, 1.0) u = u - 0.5 * NU * (right - left) + 0.5 * NU * NU * (right - 2.0 * u + left) } return u } #| L2 distance between what came back and what set out. def lap_error(u, n) { x = linspace(0.0, 1.0 - 1.0 / n, n) d = u - pulse(x) return sqrt(sum(d * d) / n) } # upwind reaches its asymptotic order slowly, so it is measured on finer grids than it is drawn on up1 = lap_error(upwind_lap(1600.0), 1600.0) up2 = lap_error(upwind_lap(3200.0), 3200.0) up_coarse = lap_error(upwind_lap(400.0), 400.0) lw1 = lap_error(lax_wendroff_lap(200.0), 200.0) lw2 = lap_error(lax_wendroff_lap(400.0), 400.0) order_upwind = log(up1 / up2) / log(2.0) order_lw = log(lw1 / lw2) / log(2.0) show order_upwind show order_lw show up_coarse show lw2 N = 200 X = linspace(0.0, 1.0 - 1.0 / N, N) figure("One trip around the ring", "x", "u") plot(X, pulse(X), "exact (the starting pulse)") plot(X, upwind_lap(N), "upwind: it diffuses") plot(X, lax_wendroff_lap(N), "Lax-Wendroff: it keeps its height") style("exact (the starting pulse)", "dash") test "upwind is first order (measured between n = 1600 and 3200: it gets there slowly)" { assert_near(order_upwind, 1.0, 0.05) } test "Lax-Wendroff is second order" { assert_near(order_lw, 2.0, 0.15) } test "at the same resolution Lax-Wendroff is more than ten times closer" { assert_lt(lw2 * 10.0, up_coarse) } # SPDX-License-Identifier: MIT OR Apache-2.0 # SPDX-FileCopyrightText: 2026 The Viv authors