Skip to content

Add the test cases of the article, and the option that picks one - #11

Merged
gouarin merged 2 commits into
mainfrom
article-test-cases
Sep 13, 2026
Merged

gouarin merged 2 commits into
mainfrom
article-test-cases

Conversation

@gouarin

@gouarin gouarin commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Lot 2 of the plan: the monofluid cases of the article, and the machinery a case
needs once it comes in variants.

The cases

lax_liu is the four-quadrant Riemann problem, all nineteen Lax & Liu
configurations behind --riemann-config, interfaces at 0.8. In three
dimensions it is the eight-octant extension of configuration 3, the one the
article extends. It replaces riemann2d_config3, _config4 and _config12:
those differed by twenty numbers and nothing else, and every configuration
anyone wanted next was twenty more numbers to copy.

sod_x is the axis-aligned tube, the layout the article runs and the one
to hold against the exact solution with nothing projected in the way.
Registered in 1D, 2D and 3D. The rotated sod stays; it measures isotropy,
which the article does not.

blast_periodic is the initial condition of the weak scaling study: a high
pressure sphere at gamma = 5/3 in a periodic box. First case here to use
either.

triple_point_single_gamma is the geometry of section 6.1.2 with one gas
instead of two. Its header says at length that this is not the case of the
article, which needs the five-equation model. What earns it a place is the
longest run in the repository, on the most strongly adapted mesh.

Options that belong to a case

A case that comes in variants declares its own command line option. The
registry carries an options function, main() calls it before parsing, and
the case keeps the variable the parser writes into.

The option is declared by the binary it belongs to, so --riemann-config
accepts 1 to 19 in euler_2d and only 3 in euler_3d: a number the case
cannot honour is a parse error rather than a surprise at run time.

Every case's options are declared, not only those of the selected one, since
which case runs is itself decided by the parse. Two cases must therefore not
ask for the same option name. Naming the option after the case is the
convention that keeps them apart, and a collision is a CLI11 exception at
startup rather than a silent shadowing.

Three corrections to the reference table

The table here is Kurganov and Tadmor's, cross-checked against two independent
implementations. It differs from the article's reference code in three places,
noted in the header of lax_liu.hpp:

reference code Lax & Liu
config 6, upper left p = 0.5 p = 1, as in all four quadrants
config 10, lower right v = -0.4259 v = -0.4297 (the first is config 9's figure)
config 19 a copy of config 1 (1,0,0.3,1) / (2,0,-0.3,1) / (1.0625,0,0.2145,0.4) / (0.5197,0,-0.4259,0.4)

Neither of the two configurations the article uses is affected.

Renamed, not regenerated

The nine reference files of the three old Riemann cases are renamed. At
equal configuration the single case reproduces them bit for bit, which is what
says the regrouping changed no result. Checked before the rename, for all three
configurations and all three Riemann solvers.

Tests

The diagonal symmetry check now covers the six configurations invariant
under (x,y,u,v) -> (y,x,v,u) instead of three.

sod_x is held to the exact Riemann solution at both orders, in L1 and in the
position of each wave. The L1 errors fall by about eight between the orders,
against four for a smooth solution: the second order also puts the contact on
fewer cells.

A periodic box is held to conservation of mass, energy and momentum, the last
of which a wall does not conserve. It pins the gas as well, since the energy is
reconstructed at the gamma the case declares and agrees only if the solver ran
on the same one. Run at 1.4 it misses by 8%.

New reference files for the new cases, in every dimension they are registered
for. 106 fast tests and 22 slow ones pass.

Run to the end

Each case was taken to the final time the article gives, well past what the
short regression runs reach:

run time cells levels density
lax_liu #3, 2D, l in [4,9], t_f = 0.8 103 s 151 480 5 [0.138, 1.749]
lax_liu #3, 3D, l in [2,6], t_f = 0.8 49 s 167 350 4 [0.138, 2.040]
blast_periodic, l in [4,9], t_f = 0.2 28 s 95 692 5 [0.153, 9.563]
triple_point_single_gamma, l in [4,8], t_f = 2.0 198 s 138 234 5 [0.125, 3.314]

All at order 2, pressure positive throughout.

Not in this lot

The sparsity index measured on lax_liu #3 is 58% against the 12% or so the
article reports with a Löhner criterion. That is the question lot 3 asks, not a
defect here.

The four monofluid cases of the article are in the repository, and the three
that were already there under ad hoc names are now one case with a parameter.

`lax_liu` is the four-quadrant Riemann problem with all nineteen Lax & Liu
configurations behind `--riemann-config`, and in three dimensions the
eight-octant extension of configuration 3, which is the one the article
extends. It replaces riemann2d_config3, _config4 and _config12: those differed
by twenty numbers and nothing else, and every configuration anyone wanted next
was twenty more numbers to copy.

`sod_x` is the axis-aligned tube, the layout the article runs and the one to
hold against the exact solution with nothing projected in the way. The rotated
`sod` stays; it measures isotropy, which the article does not.

`blast_periodic` is the initial condition of the weak scaling study, at
gamma = 5/3 in a periodic box. It is the first case in the repository to use
either.

`triple_point_single_gamma` is the geometry of section 6.1.2 with one gas
instead of two. Its header says at length that it is not the case of the
article, which needs the five-equation model. What earns it a place is the
longest run here, on the most strongly adapted mesh.

A case that comes in variants now declares its own command line option. The
registry carries an `options` function, main() calls it before parsing, and the
case keeps the variable the parser writes into. The option is declared by the
binary it belongs to, so --riemann-config accepts 1 to 19 in euler_2d and only
3 in euler_3d, and a number the case cannot honour is a parse error rather than
a surprise at run time.

The table is Kurganov and Tadmor's, cross-checked against two independent
implementations. It differs from the article's reference code in three places,
noted in the header: configuration 6 has p = 1 in all four quadrants and not
0.5 in one of them; configuration 10 has v = -0.4297 in the lower right
quadrant, not configuration 9's -0.4259; configuration 19 is itself and not a
repeat of configuration 1. Neither of the two configurations the article uses
is affected.

The nine renamed reference files are renamed and not regenerated: at equal
configuration the new case reproduces them bit for bit, which is what says the
regrouping changed no result.

The symmetry check now covers the six configurations invariant about the
diagonal instead of three. sod_x is held to the exact Riemann solution at both
orders, in L1 and in the position of each wave; the L1 errors fall by about
eight between the orders, against four for a smooth solution, the difference
being that the second order also puts the contact on fewer cells. A periodic
box is held to conservation of mass, energy and momentum, which pins the gas as
well: the energy is reconstructed at the gamma the case declares and agrees
only if the solver ran on the same one. Run at 1.4 it misses by 8%.

All four run to the final times the article gives: Riemann #3 to 0.8 in two
dimensions and in three, the periodic blast to 0.2, the triple point to 2.0.
The review found that euler_3d_sod_x_hll.npz and euler_3d_sod_x_rusanov.npz
are the same file, and the reason it gives is right. At level 4 the first time
step is 0.021 and the entry ran to 0.01, so the run is a single step from a gas
at rest; with u_L = u_R = 0 the HLL speed estimates come out at -c* and +c*,
the flux collapses to 0.5(F_L + F_R) - 0.5 c* (q_R - q_L), and that is Rusanov.
The entry now runs to 0.03, which is two steps, and the second one starts from
a state that moves.

Pulling that thread found worse next door, and it predates this branch. The
euler_3d sedov_blast entry has all three references identical, and not because
the run is short: at level 4 on [-1,1]^3 the smallest cell centre sits at
radius 0.108 and the blast has radius 0.1, so no cell falls inside it. The
reference is a uniform gas at rest, and so is what the positivity invariant has
been asserting on in three dimensions. Both move to level 5, where eight cells
fall inside, and the references are regenerated: the new ones hold a blast,
pressure from 1e-5 to 11.3.

A test now compares the references against each other rather than against a
run. Three identical files for the three Riemann solvers mean the entry
exercises none of them. It compares the whole state and not the density alone,
since the density flux is rho*u and a first step from rest updates the density
identically under every solver while the pressure already parts, which is what
euler_3d closed_box does.

Where the interfaces sit was attributed to Lax & Liu, and it is not theirs:
they and Kurganov & Tadmor put the four quadrants of the unit square at its
centre, and 0.8 is what the article uses for its configuration 3. The header
says so now, and adds what follows from it. The default suits configurations 3
and 4 and misleads for the other seventeen, whose structure is born 0.2 from a
corner and reaches it well before the published final times. So the position is
an option of its own, `--riemann-interface`, defaulting to the article's 0.8,
and an invariant counts the cells of the upper right quadrant to check it lands
where it is asked to. No reference moves: the default is unchanged.

Three smaller ones. The three-dimensional branch hard-coded its table instead
of reading the configuration number the option had just validated; it goes
through a lookup that throws for anything but 3, so a configuration added to
the option without its octants fails loudly rather than silently running
configuration 3. A collision between two case options is caught in the registry
and reported with the name of the case that lost, CLI11 knowing the option but
not the cases. And one comment in the octant table was a column out.
@gouarin
gouarin merged commit c2b2d29 into main Sep 13, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant