Skip to main content

1D Saint-Venant (shallow water) equations solver: MUSCL-HLLC + SSP-RK2

Project description

amerta: A Python Library for 1D Idealized Saint-Venant Dam-Break Simulation

Python 3.8+ PyPI version License: MIT Code style: black DOI

NumPy SciPy Matplotlib Pandas netCDF4 Numba Pillow tqdm

damBreak

Model

The Saint-Venant (shallow water) equations describe depth-averaged free-surface flow. In conservative form on a horizontal, frictionless bed:

Governing Equations

Mass conservation:

$$\partial_t h + \partial_x (hu) = 0$$

Momentum conservation:

$$\partial_t (hu) + \partial_x \left(hu^2 + \tfrac{1}{2} g h^2\right) = 0$$

where $h(x,t)$ is the water depth, $u(x,t)$ is the depth-averaged velocity, $q = hu$ is the specific discharge, and $g$ is gravitational acceleration.

Vector Form

In conservative vector form $\partial_t \mathbf{U} + \partial_x \mathbf{F}(\mathbf{U}) = 0$ with

$$\mathbf{U} = \begin{pmatrix} h \ hu \end{pmatrix}, \qquad \mathbf{F}(\mathbf{U}) = \begin{pmatrix} hu \ hu^2 + \tfrac{1}{2} g h^2 \end{pmatrix}$$

The Jacobian $\partial \mathbf{F} / \partial \mathbf{U}$ has eigenvalues $\lambda_{1,2} = u \mp c$ where $c = \sqrt{gh}$ is the gravity-wave celerity. The Froude number $\mathrm{Fr} = |u|/c$ classifies subcritical ($\mathrm{Fr} < 1$) vs supercritical ($\mathrm{Fr} > 1$) flow.

Riemann Invariants (for rarefactions)

Across a left-going rarefaction the invariant $u + 2\sqrt{gh}$ is preserved; across a right-going rarefaction $u - 2\sqrt{gh}$ is preserved. Across a shock, the Rankine–Hugoniot conditions hold with shock speed $S$ satisfying

$$S = \frac{h_\star u_\star - h_R u_R}{h_\star - h_R}$$

Key Parameters

Parameter Symbol Description Typical Range
g $g$ Gravitational acceleration $9.81 \ \text{m/s}^2$
L $L$ Channel length 10–1000 m
h_left $h_L$ Initial depth left of dam 0.5–10 m
h_right $h_R$ Initial depth right of dam 0–10 m
u_left $u_L$ Initial velocity left of dam $-10$ to $+10$ m/s
u_right $u_R$ Initial velocity right of dam $-10$ to $+10$ m/s
nx $N_x$ Number of grid cells 200–5000
CFL $\nu$ Courant number 0.5–0.9

Canonical Riemann Problems

The dam-break problem with initial state $\mathbf{U}(x, 0) = \mathbf{U}L$ for $x < x{\text{dam}}$ and $\mathbf{U}_R$ otherwise produces four classical wave patterns:

Case State Wave Structure Characteristics
1. Stoker Wet–wet dam break Left rarefaction + right shock Classical flood wave
2. Ritter Wet–dry dam break Single rarefaction, dry front Catastrophic collapse onto dry bed
3. Double Rarefaction Diverging flow Two rarefactions Near-vacuum at center
4. Double Shock Converging flow Two shocks Frontal collision / surge

Numerical Method

MUSCL Reconstruction (Second-Order Spatial)

Cell-interface states are reconstructed from cell averages $\mathbf{U}_i$ using the minmod slope limiter:

$$\mathbf{U}_{i+1/2}^L = \mathbf{U}i + \tfrac{1}{2},\mathrm{minmod}(\mathbf{U}i - \mathbf{U}{i-1},, \mathbf{U}{i+1} - \mathbf{U}_i)$$

$$\mathbf{U}{i+1/2}^R = \mathbf{U}{i+1} - \tfrac{1}{2},\mathrm{minmod}(\mathbf{U}{i+1} - \mathbf{U}i,, \mathbf{U}{i+2} - \mathbf{U}{i+1})$$

where $\mathrm{minmod}(a,b) = \tfrac{1}{2}[\mathrm{sgn}(a) + \mathrm{sgn}(b)],\min(|a|,|b|)$.

HLLC Approximate Riemann Solver

The interface numerical flux $\mathbf{F}_{i+1/2}$ is computed by HLLC (Harten–Lax–van Leer Contact) using Roe-averaged wave-speed estimates:

$$S_L = \min(u_L - c_L,\ \tilde{u} - \tilde{c}), \qquad S_R = \max(u_R + c_R,\ \tilde{u} + \tilde{c})$$

with contact wave speed

$$S_\star = \frac{S_L h_R (u_R - S_R) - S_R h_L (u_L - S_L)}{h_R (u_R - S_R) - h_L (u_L - S_L)}$$

SSP-RK2 Time Integration

The strong-stability-preserving two-stage Runge–Kutta scheme (Shu & Osher, 1988):

$$\mathbf{U}^{(1)} = \mathbf{U}^n + \Delta t, \mathcal{L}(\mathbf{U}^n)$$

$$\mathbf{U}^{n+1} = \tfrac{1}{2} \mathbf{U}^n + \tfrac{1}{2}\mathbf{U}^{(1)} + \tfrac{1}{2} \Delta t, \mathcal{L}(\mathbf{U}^{(1)})$$

with CFL-limited time step

$$\Delta t = \nu \cdot \frac{\Delta x}{\max_i (|u_i| + \sqrt{g h_i})}$$

Diagnostics

Diagnostic Formula Interpretation
Celerity $c = \sqrt{gh}$ Gravity-wave speed
Froude number $\mathrm{Fr} = \lvert u \rvert / c$ Flow regime classifier
Specific energy $E = \tfrac{1}{2} u^2 + g h$ Hydraulic head
Mass balance $\int h, dx$ Conservation check (closed BC)
CFL actual $\nu_{\text{act}} = (\lvert u \rvert + c), \Delta t / \Delta x$ Stability monitor

Installation

From PyPI:

pip install amerta

From source:

git clone https://github.com/sandyherho/amerta.git
cd amerta
pip install .

Development installation with Poetry:

git clone https://github.com/sandyherho/amerta.git
cd amerta
poetry install

Quick Start

CLI:

amerta case1                     # Stoker wet dam break
amerta case2                     # Ritter dry dam break
amerta case3                     # Double rarefaction
amerta case4                     # Double shock
amerta --all                     # Run all four cases
amerta case1 --nthreads 8        # Use 8 threads

Python API:

from amerta_sv import SaintVenantSolver, get_case
from amerta_sv.io import ConfigManager

# Load preset and override grid resolution
cfg = ConfigManager.validate_config({
    **get_case('stoker'),
    'nx': 800, 'cfl': 0.9, 'g': 9.81,
    'scenario_name': 'stoker_hires',
    'case_type': 'stoker'
})

# Solve
solver = SaintVenantSolver(nthreads=8, verbose=True)
result = solver.solve(cfg)

print(f"Steps: {result['n_steps']}")
print(f"CFL max: {result['cfl_max']:.4f}")
print(f"Mass error: {result['mass_err_pct']:+.3e} %")
print(f"Final h range: [{result['h_final'].min():.4f}, {result['h_final'].max():.4f}] m")

Features

  • Second-order MUSCL reconstruction with minmod slope limiter
  • HLLC approximate Riemann solver with Roe-averaged wave speeds
  • SSP-RK2 strong-stability-preserving time integration
  • Adaptive CFL-limited time step with positivity preservation
  • Numba JIT acceleration with parallel prange sweeps (user-selectable thread count)
  • Four canonical Riemann test cases validated against analytical solutions
  • CF-1.8 compliant NetCDF4 output with full trajectory data
  • Dark-themed publication figures (time evolution, physical interpretation, numerical aspects)
  • Animated GIF with red-dashed dam reference and real-time counter
  • Configurable scenarios via plain-text config files
  • Progress bars via tqdm for integration and GIF rendering

Output Files

The library generates, for each case:

  • CSV files:
    • <case>_metrics.csv — single-run diagnostics (steps, CFL, mass error, etc.)
    • comparison_metrics.csv — appended across all runs for side-by-side comparison
  • NetCDF: <case>.nc — CF-1.8 with $h(t,x)$, $u(t,x)$, $q(t,x)$ and all simulation attributes
  • PNG:
    • <case>_time_evolution.png — snapshot overlay at saved times
    • <case>_physical.png — depth, velocity, Froude, specific energy
    • <case>_numerical.png — celerity, $\Delta t$ range, CFL stats, mass error
  • GIF: <case>.gif — animated evolution with dam reference line and parameter subtitle
  • Log: logs/<case>.log — full run log

Dependencies

  • numpy >= 1.20.0
  • scipy >= 1.7.0
  • matplotlib >= 3.3.0
  • pandas >= 1.3.0
  • netCDF4 >= 1.5.0
  • numba >= 0.53.0
  • Pillow >= 8.0.0
  • tqdm >= 4.60.0

License

MIT 2026 © Dasapta E. Irawan, Sandy H. S. Herho, Iwan P. Anwar, Faruq Khadami, Astyka Pamumpuni, Rendy D. Kartiko, Edi Riawan, Rusmawan Suwarman, and Deny J. Puradimaja

Citation

@software{irawanEtAl2026_amerta,
  title   = {{\texttt{amerta}: A Python library for 1D idealized Saint-Venant dam-break simulation}},
  author  = {Irawan, Dasapta E. and Herho, Sandy H. S. and Anwar, Iwan P. and
             Khadami, Faruq and Pamumpuni, Astyka and Kartiko, Rendy D. and
             Riawan, Edi and Suwarman, Rusmawan and Puradimaja, Deny J.},
  year    = {2026},
  version = {0.0.1},
  url     = {https://github.com/sandyherho/amerta}
}

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

amerta-0.0.1.tar.gz (19.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

amerta-0.0.1-py3-none-any.whl (20.0 kB view details)

Uploaded Python 3

File details

Details for the file amerta-0.0.1.tar.gz.

File metadata

  • Download URL: amerta-0.0.1.tar.gz
  • Upload date:
  • Size: 19.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.2 CPython/3.11.7 Linux/5.15.0-173-generic

File hashes

Hashes for amerta-0.0.1.tar.gz
Algorithm Hash digest
SHA256 c26e2771fd4000a5ee83f62f94769e746cfc7dff10beb2a684d12b762482098b
MD5 48a14bfe1ec9462b3641d137d37d6be0
BLAKE2b-256 ed59b18019b6925db861be0e2d8a3ccf09a648a20b9ab86017a3dc5b634ed899

See more details on using hashes here.

File details

Details for the file amerta-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: amerta-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 20.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.2 CPython/3.11.7 Linux/5.15.0-173-generic

File hashes

Hashes for amerta-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a32c4b62f018be91a6aed4094008d8e6af75d1b52d19b7dbb0a063fba1f8a60f
MD5 f18b58a2067a8b052d2fcaff21e71287
BLAKE2b-256 5edf233ed2f17aa65ce269922e5a08c52a351dd8ebedff032a726148bafd71e6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page