Trapezoidal conservation metric for 1D diffusion (restores strict tol, supersedes #566 loosening)#567
Merged
ChrisRackauckas merged 1 commit intoJun 4, 2026
Conversation
Test 03 of MOL_1D_Linear_Diffusion checks that the diffusion equation with homogeneous Neumann BCs conserves the spatial integral of u (here ∫₀^π cos(x) dx = 0). It previously used `sum(u)`, a rectangle rule that on the edge-aligned grid (nodes offset half a step outside the domain) carries an O(Δx) boundary bias and drifts to ~1e-7, which forced SciML#566 to loosen the assertion from atol=1e-10 to atol=1e-6. Integrate instead with composite trapezoidal weights built from the actual grid spacing (interior nodes get the half-spacing on each side, endpoints a single half-spacing), correct on both the center-aligned and the half-step edge-aligned grids and on non-uniform grids. The trapezoidal integral conserves down to the Tsit5 time-integration error, not the spatial quadrature error: measured max|∫u dx| over the trajectory is ~4e-13 (center) / ~6e-10 (edge) at the default Tsit5 tolerances, and both fall to ~1e-15 when the solver tolerance is tightened to 1e-12 — confirming the residual is bounded by the time integrator, not a real conservation defect. The assertion is therefore restored to a strict atol=1e-9 (1000x tighter than SciML#566's 1e-6, with headroom above the measured 6e-10 edge residual) and now compares against the initial integral so it works regardless of the analytic value. Verified locally with `GROUP=Diffusion`: 289/289 pass, both grid alignments. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
7a3c866 to
26a5215
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This supersedes the conservation-check tolerance loosening introduced in #566 with a proper grid-weighted (trapezoidal) quadrature, so the assertion in Test 03 of
test/pde_systems/MOL_1D_Linear_Diffusion.jlholds at a strict tolerance again — honestly, without any fudge.#566 (the OrdinaryDiffEq 7 / SciMLBase 3 / RecursiveArrayTools 4 migration) fixed
length(sol)for single-variable PDE solutions, which made the per-timestep mass-conservation check actually run at every saved time instead of only ati = 1. Once it ran for the whole trajectory, the crudesum(u)rectangle-rule proxy was exposed: on the edge-aligned grid (nodes sit half a step outside the domain) the rectangle rule has an O(Δx) boundary bias and drifts to ~1e-7, so #566 relaxedatolfrom1e-10to1e-6with an explanatory comment. That was a band-aid; this PR removes it.What changed
trapezoidal_weights(xs)helper that builds composite trapezoidal weights from the actual grid spacing (each interior node gets the half-spacing on either side; the two endpoints get a single half-spacing). It is correct on the center-aligned grid, the half-step-offset edge-aligned grid, and non-uniform grids.@test sum(u_approx[i, :]) ≈ 0 atol = 1e-6with@test dot(w, u_approx[i, :]) ≈ integral0 atol = 1e-9, whereintegral0 = dot(w, u_approx[1, :])is the trapezoidal integral of the initial condition. Comparing to the conserved initial integral (rather than hardcoding0) keeps the metric meaningful for any IC.Why the strict tolerance is honest, not a refit
The rectangle-rule drift was a quadrature artifact, not a conservation defect of the scheme. The MoL semi-discretization with homogeneous Neumann BCs conserves the trapezoidal integral exactly at the spatial level; the only residual is the time integrator's error. Measured
max|∫u dx|over the trajectory:Tightening the solver tolerance drives the residual to machine precision on both grids, confirming it is bounded by time integration. For comparison the old
sum(u)rectangle rule hit9.8e-11(center) /1.10e-7(edge) at the default tolerances.The test uses default Tsit5 tolerances, so the realistic worst case is the edge-aligned
5.76e-10. The newatol = 1e-9sits just above that (≈1.7x headroom on a deterministic computation) and is 1000x tighter than #566's1e-6; the center-aligned grid passes with ~4 orders of margin. Both grid configurations (discretizationanddiscretization_edge) are exercised by the existingfor disc in [...]loop.Local test evidence
289/289 pass with the strict
atol = 1e-9, both grid alignments, no skips/@test_broken/loosening anywhere.Stacking
This is stacked on #566 and includes its commits (notably the
length/sizesolution-interface fix that makes this conservation check run at every timestep). It should land with or after #566. The diff unique to this PR is a single test file.Notes