Shallow Water Dam Break
The dam break problem is a standard test for the shallow water equations. A column of deep water (height $h_L$) is released into a shallower region ($h_R$), producing a rarefaction wave propagating upstream and a bore (shock) propagating downstream.
Problem Setup
The 1D shallow water equations are:
\[\pdv{}{t}\begin{pmatrix}h \\ hu\end{pmatrix} + \pdv{}{x}\begin{pmatrix}hu \\ hu^2 + \tfrac{1}{2}g h^2\end{pmatrix} = 0,\]
with initial conditions:
\[(h, u) = \begin{cases}(2, 0) & x < 0.5,\\(1, 0) & x \geq 0.5.\end{cases}\]
We begin by loading the package and defining the conservation law.
using FiniteVolumeMethod
using StaticArrays
law = ShallowWaterEquations{1}(g = 9.81)ShallowWaterEquations{1}(9.81)Define left and right primitive states $(h, u)$:
wL = SVector(2.0, 0.0)
wR = SVector(1.0, 0.0)2-element StaticArraysCore.SVector{2, Float64} with indices SOneTo(2):
1.0
0.0Set up the mesh, boundary conditions, and initial condition:
N = 200
mesh = StructuredMesh1D(0.0, 1.0, N)
ic(x) = x < 0.5 ? wL : wRic (generic function with 1 method)Solving with HLLC + MUSCL
We use the HLLC Riemann solver with MUSCL reconstruction using the minmod limiter.
prob = HyperbolicProblem(
law, mesh, HLLCSolver(), CellCenteredMUSCL(MinmodLimiter()),
TransmissiveBC(), TransmissiveBC(), ic;
final_time = 0.15, cfl = 0.4,
)
x, U, t = solve_hyperbolic(prob)200-element Vector{Float64}:
0.0025
0.0075
0.0125
0.0175
0.0225
⋮
0.9775
0.9825
0.9875
0.9925
0.9975Visualisation
Extract the primitive variables (water height $h$ and velocity $u$).
using CairoMakie
W = to_primitive(law, U)
h_vals = [W[i][1] for i in eachindex(W)]
u_vals = [W[i][2] for i in eachindex(W)]
fig = Figure(fontsize = 24, size = (900, 400))
ax1 = Axis(fig[1, 1], xlabel = "x", ylabel = "h", title = "Water Height")
ax2 = Axis(fig[1, 2], xlabel = "x", ylabel = "u", title = "Velocity")
scatter!(ax1, x, h_vals, color = :blue, markersize = 4)
scatter!(ax2, x, u_vals, color = :red, markersize = 4)
resize_to_layout!(fig)
fig
The left rarefaction fan smoothly connects $h = 2$ to the intermediate plateau, while the right-moving bore sharply transitions the intermediate state to $h = 1$.
Physical Checks
Water height must be positive everywhere, and mass should be approximately conserved.
Just the code
An uncommented version of this example is given below. You can view the source code for this file here.
using FiniteVolumeMethod
using StaticArrays
law = ShallowWaterEquations{1}(g = 9.81)
wL = SVector(2.0, 0.0)
wR = SVector(1.0, 0.0)
N = 200
mesh = StructuredMesh1D(0.0, 1.0, N)
ic(x) = x < 0.5 ? wL : wR
prob = HyperbolicProblem(
law, mesh, HLLCSolver(), CellCenteredMUSCL(MinmodLimiter()),
TransmissiveBC(), TransmissiveBC(), ic;
final_time = 0.15, cfl = 0.4,
)
x, U, t = solve_hyperbolic(prob)
using CairoMakie
W = to_primitive(law, U)
h_vals = [W[i][1] for i in eachindex(W)]
u_vals = [W[i][2] for i in eachindex(W)]
fig = Figure(fontsize = 24, size = (900, 400))
ax1 = Axis(fig[1, 1], xlabel = "x", ylabel = "h", title = "Water Height")
ax2 = Axis(fig[1, 2], xlabel = "x", ylabel = "u", title = "Velocity")
scatter!(ax1, x, h_vals, color = :blue, markersize = 4)
scatter!(ax2, x, u_vals, color = :red, markersize = 4)
resize_to_layout!(fig)
figThis page was generated using Literate.jl.