Files
CelerisLab/docs/projected-explosion-experiment.md

7.8 KiB
Raw Permalink Blame History

Projected explosion: isolated spatial-interpolation experiment

Historical baseline: 9805383f9c50d867e8555471baf5dbda8333a652. This candidate does not replace or relabel its results. The TG runner records the actual candidate revision, dirty state, source hash and harness hashes, plus the historical baseline revision and selected explosion scheme.

Default remains constant. Explicit explosion="projected_linear" supports only a periodic, body-free, two-level, fully blocked single rectangle (window or singleton union representation). Dense, multilevel, multi-rectangle and body/Jet cases are rejected. Constructor guards have been statically reviewed; GPU construction is not yet exercised.

For each population, form a centered gradient only where both axis neighbors are original explosion donors, owned and uncovered. Otherwise set that axis derivative to zero. Project the gradient perpendicular to the population lattice direction (rest population retains its gradient), then evaluate at child offsets ±1/4 coarse cell. Read owner cores, never stale block halos. Repeating the donor for a missing axis avoids invalid reads. All neighbor reads remain within the original coarse transfer footprint.

Timing, two ghost-only streaming hops, four-child coalescence, relaxation, shifted-storage convention, bulk collision and legacy constant kernel are unchanged. There is no NEQ rescaling, limiter, time interpolation or new framework. Projection commutes with subtracting the constant lattice weights.

Method attribution: Schornbaum and Rüde, arXiv:1508.07982, Algorithm 2; Chen et al., Physica A 362 (2006) 158–167, DOI 10.1016/j.physa.2005.09.036. Independently implemented mathematical stencil, with no GPL implementation copied. The Chen full text was not directly audited in this experiment.

CPU checks

Run PYTHONPATH=src python -m unittest discover -s tests/unit -p test_projected_explosion.py -v.

  • Constant populations, affine available-axis gradients, characteristic constancy, quartet means and shift invariance.
  • Original donor footprint only; poison covered cells and check finite reconstruction.
  • Both window and singleton-union layouts, centered/off-axis/minimal near-edge rectangles.
  • Eight complete intervals, identity and SRT collision: actual fine pulls and coarse restriction tables, all eight grazing corner paths included; composite mass and both momentum components conserved within 2e-12 FP64 absolute tolerance.
  • Actual CUDA kernel body compiled with a CPU C++ shim: blocked address mapping, FP32 shifted/unshifted inputs, poisoned halo/covered storage, independent NumPy parity. This checks arithmetic and indexing, not CUDA compilation or execution.
  • Unprojected reconstruction is distinguished by failure of characteristic constancy. It need not fail global mass conservation in this geometry.

Next diagnostic, only on authorized Horsea GPU

Use the same candidate checkout for paired Re100 N64 depth2 runs, differing only in --explosion constant versus --explosion projected_linear:

python tests/validation/taylor_green/run_case.py --repo "$PWD" --re 100 --n 64 --depth 2 --explosion projected_linear --output <new-result-path>

Select the physical CUDA device explicitly. Never overwrite historical reports. Compare frozen TG error gates and full trajectories, including mass, energy, pressure and velocity. Amplitude/nonmodal shape decomposition can inform mechanism but cannot substitute for the gates. First establish CUDA compilation and CPU/device parity, then paired end-to-end budgets. The CPU diagnostic below establishes improvement only in its FP64 reference trajectories; it does not establish production suitability or a candidate GPU pass.

Local verification limits

Focused candidate/refinement/block-layout/build-contract checks pass (62 unittest tests). Full unittest discovery is not green: the attempted 200-test run reports 18 missing-dependency/import errors and three historical source-pin refusals (jet-circle and LES guards), plus one skipped test. Those pin refusals correctly reject the changed blocks.cu; their immutable fixtures were not weakened or rewritten. Python syntax checks and git diff --check pass. No candidate CUDA build, device execution, GPU performance or GPU TG improvement has been established.

Donor-support audit

The current support is exactly the original two-coarse-cell-wide explosion ring. Centered normal derivatives therefore vanish along straight faces: the inner donor lacks an uncovered inward neighbor, and the outer donor lacks a third-ring outward neighbor. This is an explicit limitation, not evidence of a missing donor layer. Independent inspection of the authors' LinearExplosion implementation found the same two-cell directional slabs and both-neighbors-valid condition; their union equals all 368 distinct donors in the N64 TG geometry. No upstream code was copied. This does not claim identical block-local tangential fallback at every fine/fine block seam.

A separate read-only dependency trace compared the ring to all uncovered periodic parent neighbors for four rectangles. Wider support changed some unused outer ghost populations but none consumed by final fine ACTIVE outputs or coarse restriction through the two hops, including full collision dependencies. Widening the support is not part of this candidate.

Reproducible CPU Taylor–Green A/B

Run from this checkout, with NumPy and Python installed:

python tests/validation/taylor_green/run_cpu_explosion.py --repo "$PWD" --n 32 --output-dir /tmp/explosion-ab

Repeat with --n 64 for the second retained case. These are the only supported grids. The script reuses unchanged CPUREF advance_coarse_once, existing TG initialization/metrics, actual singleton-rectangle transfer tables, and the tested projected reconstruction. The rectangular adapter verifies its coalescence children against the production table and includes all eight grazing-corner links. Only the explosion operation differs within each pair.

The reference stores physical FP64 arrival populations; production stores shifted FP32 postcollision populations. Collision preserves the macroscopic moments compared here, and initialization is equilibrium. This supports a macro-trajectory comparison, not population-by-population/device equivalence. Outputs record actual checkout/harness provenance and hashes of both imported diagnostic helpers. The compact retained tests/validation/taylor_green/cpu_explosion_summary.json records original N32/N64 results and historical GPU report hashes, without importing those reports into this branch.

At Re100, depth 2, t*=0.48:

Root N Velocity L2, constant → projected Pressure L2 Orthogonal velocity residual
32 3.24942% → 1.52264% 8.98696% → 4.85601% 2.28814% → 0.98615%
64 1.13113% → 0.49304% 3.55050% → 1.65801% 0.93699% → 0.40289%

Across sampled times, constant CPU versus historical constant GPU differs by at most 6.93e-8 in velocity L2 and 3.58e-6 in pressure L2 for N32; 1.74e-8 and 8.64e-7 for N64. Relative mass drift remains below 1.42e-13 and absolute momentum change below 2.11e-13 in these CPU pairs. Independent N32 rerunning reproduced trajectory/error metrics exactly; recomputed quadrature-factor metadata agrees to roundoff.

Amplitude is the volume-weighted projection onto the exact velocity field; the orthogonal residual isolates the remaining shape error. The energy decomposition includes the discrete composite-grid exact-energy quadrature factor recorded per row, not simply amplitude squared plus residual squared. These are bounded diagnostic improvements, not proof of complete method fidelity, uniform-grid accuracy equivalence or a validated CUDA implementation. Frozen production validation gates are unchanged.