Skip to main content

Module reproduce

Module reproduce 

Source
Expand description

§Reproducing the results

From the repository root. The default build writes HDF5 and needs the HDF5 C library (brew install hdf5); uv creates .venv/ for the Python tools. The numbers in this book are from a run on 2026-10-25 on one thread of an 8-core Apple M1.

§Build and run every problem

cargo build --release -p merlin-cli --all-features
for f in problems/*/*/*.toml; do target/release/merlin $f; done   # they write HDF5

Every problem file begins with a comment giving the pymerlin plot command for it. merlin --timings FILE prints where the time went.

§The tests

cargo test --workspace
cargo test --workspace --all-features      # adds the scalar laws (advection, Burgers) and the tests that need both families
cargo test -p merlin-docs                   # the links of this book (see below)

Integration tests are in crates/<crate>/tests/<area>/, one program per area (--test schemes, --test geometry, …).

§Build cost and speed

merlin-cli is built in two families, the cargo features materials (the default, with hdf5) and scalar. The numbers of phase 9.1c (solver copies, clean build time, peak compiler memory, output hashes, flux-sweeps time per equation family) come from the scripts in scripts/; the plan and its outcome are in docs/plans/phase-9.1c-scheme-dispatch.md, the options that were tried in docs/plans/spike-build-cost.md.

scripts/build-cost.sh -- --no-default-features --features materials   # copies, seconds, peak memory
scripts/hashes.sh target/build-cost/release/merlin before.txt          # hash of every shipped problem at 1, 2, 4, 8 threads
python3 scripts/timing-cases.py /tmp/cases && scripts/timings.sh target/build-cost/release/merlin /tmp/cases
make families                                                           # each family alone: lint and test

§Checks outside cargo test

All run in continuous integration.

# the independent Python solvers against published values and their own invariants
uv run pymerlin check --self-test euler
uv run pymerlin check --self-test schlieren
uv run pymerlin check --self-test acoustic
uv run pymerlin check --self-test sedov

# sound waves in cylindrical and spherical symmetry: observed order against exact solutions
uv run pymerlin convergence spherical/euler/acoustic --expect-order=2 --tolerance=0.4
uv run pymerlin convergence cylindrical/euler/acoustic --expect-order=2 --tolerance=0.4

# Sedov blasts against the similarity solution
uv run pymerlin convergence spherical/euler/sedov --max-error=0.005
uv run pymerlin convergence cylindrical/euler/sedov --max-error=0.005

# threads do not change the answer; the scaling study
uv run pymerlin scaling 2d/euler/vortex --threads=1,2,4,8 --repeats=3
uv run pymerlin check output/2d/euler/vortex/scaling/scaling.csv   # exits non-zero if any thread count changed the answer

§HDF5 against CSV

A CSV variant is a copy of a problem with the format and directory changed:

sed 's#output/1d/euler/sod"#output/1d/euler/sod_csv"#; s#format = "hdf5"#format = "csv"#' \
    problems/1d/euler/sod.toml > output/1d/euler/sod_csv.toml
target/release/merlin output/1d/euler/sod_csv.toml
uv run pymerlin check output/1d/euler/sod_csv output/1d/euler/sod   # bit-identical

§The deliberate failures

Edit a copy of the file, not the shipped one:

# HLL in place of HLLC
sed 's/"hllc"/"hll"/; s#output/1d/euler/contact#output/1d/euler/contact_hll#' problems/1d/euler/contact.toml > output/1d/euler/contact_hll.toml
target/release/merlin output/1d/euler/contact_hll.toml
# the unfixed Roe flux
target/release/merlin problems/1d/burgers/transonic_unfixed.toml

§Convergence studies

cargo run --release -p merlin-finite-volume --example advection_convergence
uv run pymerlin plot 1d/advection/convergence --type=convergence

§The figures

uv run pymerlin plot 1d/euler/sod --type=snapshots
uv run pymerlin plot 2d/euler/riemann_config3 --type=schlieren
uv run pymerlin plot 1d/advection/upwind --type=compare --with=1d/advection/lax_wendroff --with=1d/advection/muscl --time=1.0
uv run pymerlin plot 1d/burgers/transonic --type=compare --with=1d/burgers/transonic_unfixed --time=0.5
# the interfaces of three rules on one figure: run copies of the problem with another flux_scheme,
# written to output/2d/levelset/zalesak_first_order and zalesak_upwind11 (CSV), then
uv run pymerlin plot 2d/levelset/zalesak --type=compare --with=2d/levelset/zalesak_first_order --with=2d/levelset/zalesak_upwind11 --label=weno5 --label=first_order --label=upwind11
uv run pymerlin plot 2d/levelset/vortex --type=compare --with=2d/levelset/vortex_first_order --with=2d/levelset/vortex_upwind11 --label=weno5 --label=first_order --label=upwind11 --time=1 --time=2

The plots are written next to the results (output/<name>/plots/). --type=compare handles one-variable runs only.

§This book

cargo doc --workspace --no-deps --open

The figures in this book are copied from output/ by the build script of merlin-docs, which names each one from the pages; a figure that is missing stops the build, and cargo test -p merlin-docs checks that every test and file a page refers to exists, so a renamed test cannot leave a stale claim behind.