Skip to content

UWTN: update the time-derivatives note for the composing solvers - #53

Open
lmoresi wants to merge 2 commits into
mainfrom
note/time-derivatives-supg
Open

lmoresi wants to merge 2 commits into
mainfrom
note/time-derivatives-supg

Conversation

@lmoresi

@lmoresi lmoresi commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

AdvDiffusion and NavierStokes now take their transport from the history
manager rather than owning it, and default to EulerianSUPG; the semi-Lagrangian
solvers keep their SLCN names. Verified against development after #688
merged — EulerianSUPG is present with time_derivative, advection,
stabilisation_flux and spatial_weights; AdvDiffusionSUPG correctly does
not exist.

The note

  • the DDt hierarchy gains a fifth flavour, and the two Eulerian ones are
    distinguished: one corrects the history explicitly and pays a CFL condition,
    the other assembles the advection in the residual and does not
  • "What the Solver Sees" is rewritten in the composing form, keeping the older
    bdf()/adams_moulton_flux() pair as what a semi-Lagrangian manager reduces
    to — the clearest way to show the manager is the plug
  • "Choosing a Time Derivative" gets the new defaults and the order= that a
    supplied manager now requires
  • ## History entry at 1.1.0, saying what did not change (the scheme theory;
    the viscoelastic stress history, still semi-Lagrangian)

A correction I had to make to my own draft

I first wrote that the default moved because the benchmarks gave "the same
answers, about a tenth of the cost per step". Running the example against the
merged code contradicted both halves:

Courant 0.5, 24 cells L2 error s/step
Eulerian SUPG 0.0038 0.023
Semi-Lagrangian 0.0007 0.259
Eulerian 0.1813 0.079

Semi-Lagrangian is more accurate at every Courant number tried, and the design
note's own table puts the cost ratio at 1 : 6.3 rather than a tenth.

The two tests disagree because they measure different things: the design note
carries a blob once around a rotating flow, where interpolation error
accumulates over a circuit and lands SLCN at 21%. The example translates a blob
uniformly, which is the easiest case a semi-Lagrangian scheme ever gets.

So the note now says the default moved on cost and stability, not accuracy,
and says plainly that semi-Lagrangian remains more accurate on smooth
translation — which is why it keeps its place.

The example

examples/timestepping.py — one Gaussian blob, three managers, same solver,
scored against the exact answer. Dimensional (m, s, K) with the
non-dimensionalisation stated where it is applied, per #52. It compares at equal
physical distance rather than equal step count, since a larger Courant number
buying fewer steps is the point of an unconditionally stable scheme, and it says
in its own docstring what it does not show.

Underworld development team with AI support from Claude Code

AdvDiffusion and NavierStokes now take their transport from the history
manager rather than owning it, and default to the Eulerian SUPG manager;
the semi-Lagrangian solvers keep their SLCN names. The note described the
old arrangement throughout.

Changed: the DDt hierarchy gains a fifth flavour, and the difference
between the two Eulerian ones is stated -- one corrects the history
explicitly and pays a CFL condition, the other assembles the advection in
the residual and does not. "What the Solver Sees" is rewritten in the
composing form, with the older bdf()/adams_moulton_flux() pair kept as
what a semi-Lagrangian manager reduces to, since that is the clearest way
to show the manager is the plug. "Choosing a Time Derivative" gets the
new defaults, the order= that a supplied manager now requires, and one
sentence on why the default moved.

Unchanged, and said so in the History entry: the scheme theory, and the
viscoelastic stress history, which is still semi-Lagrangian.

examples/timestepping.py is new -- one Gaussian blob advected and
diffused, scored against the exact answer, with only the history manager
changing between runs. Dimensional (metres, seconds, kelvin) with the
non-dimensionalisation stated where it is applied, per the examples rule.
It runs today: semi-Lagrangian 0.0004, Eulerian 0.1451 at 16 cells. The
SUPG row reports that it needs the release shipping EulerianSUPG rather
than failing, so the script works now and gains the row when it lands.

Underworld development team with AI support from Claude Code
Running the example against the merged #688 contradicted the sentence I had
written for why the default moved, so the sentence is wrong rather than
the code.

I had written "the same answers, about a tenth of the cost per step".
Neither half survived contact. On this problem the semi-Lagrangian scheme
is MORE accurate at every Courant number tried (0.0007 against 0.0038 at
Courant 0.5), not the same; and the design note's own table measures the
cost ratio at 1 : 6.3, not a tenth.

The reason the two disagree is the test. The design note carries a blob
once around a rotating flow, where the interpolation error accumulates
over a full circuit and lands SLCN at 21%. The example translates a blob
uniformly, which is the easiest case a semi-Lagrangian scheme ever gets:
the characteristic is a straight line and one interpolation per step is
nearly exact.

So the note now says the default moved on cost and stability rather than
accuracy, and says plainly that semi-Lagrangian remains the more accurate
on smooth translation -- which is why it keeps its name and its place. The
example says what it does and does not show, and points at the design note
for the case that actually decided it.

The example also now compares at equal PHYSICAL distance instead of equal
step count, since a larger Courant number buying fewer steps is the whole
point of an unconditionally stable scheme, and reports seconds per step:
0.023 against 0.259 at Courant 0.5, which is where the cost argument
actually lives.

Underworld development team with AI support from Claude Code
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