Files
CelerisLab/docs/validation/refined_dfg.md
T

10 KiB
Raw Blame History

Matched SRT uniform / refined DFG Re100 preparation

Status: CPU-preflight checked; not GPU executed or approved to execute. No physical acceptance or speedup claim. No production source changes. Root owns GPU admission and integration.

Frozen setup

Canonical source snapshot: integrated commit cd3a657f9d3833e812c3cca173525f165b48710a. Production origin remains candidate 47b05bc8abfc957fe876b0c63bdb386e3c6cbaa5 (on 5338864, on 69e9b78); production files are byte-identical. The integrated Re100 helper header/PIN records that origin explicitly. Both commit identities are retained in the manifest. tests/validation/data/refined_dfg/source_manifest.json hashes all production source files plus the existing DFG geometry/pressure helper, periodicity helper and official reference cycle. An integrated checkout may have a different commit but must have identical pinned file contents. No MRT external-reference run is reused as the matched uniform control.

Both cases: SRT, shifted FP32, double buffer, no LES, no applied force, stationary cylinder, local Zou–He parabolic inlet, halfway y walls, identical pressure-NEQ outlet with all nine nonequilibrium components damped by 0.5, backflow clamp disabled. This outlet is not the exact canonical DFG do-nothing condition. Raw cylinder reaction observation is a diagnostic, not applied forcing.

Physical units use D=0.1 m, mean U=1 m/s, ν=0.001 m²/s, density reference=1; domain 2.2×0.41 m, cylinder center (0.2,0.2) m. Uniform D80: 1761×330, dx=0.00125 m, dt=0.0000125 s, ν_lattice=.008. Refined root D40: 881×166, dx=.0025 m, dt=.000025 s, ν_lattice=.004; fine dx/dt/ν match uniform D80. All lattice mean speeds are .01.

Fixed half-open patch (40,24,320,140) in root edge coordinates maps to x=[.09875,.79875] m, y=[.0575,.3475] m. The body and about six diameters of downstream wake are fine; wall layers and far wake remain coarse. Bounds are frozen before outcomes, not tuned afterward. Geometry-only leaf-count and nominal collision-work ratios to uniform are ~.419 and ~.321. These omit real launch/transfer/halo/measurement costs and are not measured speedups. The narrow root block height is legal but potentially expensive; do not infer speed from leaf count.

Exact root dimensions are tiled by (by,bx)=(2,881); no padding. Fine allocated shape (240,568), including four-cell halos, uses (8,8). host_geometry calls production channel transfer-overlap checks and complete fine cut-link/donor/transfer guards before any CUDA import.

Half-cell conversion

Uniform integer nodes have physical coordinates (i*dx, (j-.5)*dx). Root edge coordinates therefore map to ((X-.5)*dx_root, (Y-1)*dx_root). Body edge center=(80.5,81), radius=20; wall edges Y=1,165; source planes X=.5,880.5. Fine local body nodes are (body_edge - fine_origin)/.5 - .5.

Body and physical wall planes match exactly. The axes have different phases. With fine origin O=(38,22):

  • x_f = [O_x+(j+.5)/2-.5] dx40 = (j+75.5) dx80, versus x_uniform = i dx80. Fine x samples have a half-fine-cell (quarter-root-cell) offset.
  • y_f = [O_y+(k+.5)/2-1] dx40 = (k+42.5) dx80, versus y_uniform = (l-.5) dx80. The y samples align exactly for l=k+43.

This difference follows from the inlet's ghost-node plane versus the half-way y-wall planes. The host phase test checks both mappings. Compare interpolated observables, not pointwise arrays or bitwise equality; x-phase error, the different fine collision arithmetic, wall resolution, and coarse/fine transfer effects all contribute to discrepancies. No field-difference acceptance is claimed by this runner. Initial fluid state samples the same analytic parabolic equilibrium as uniform production initialization; root boundary ghosts start at rest. It is not asserted to be bitwise identical across different grids/arithmetic.

Observations and gates

  • Every AMR base step is individually followed by read_raw_exchange(..., window='last_base_step'): two fine substeps, root-lattice per-unit-depth impulse integrated over [n,n+1]. step(n) alone retains only its last base interval, so it cannot support averaging the whole batch.
  • Uniform Simulation.run(batch) / read_force gives the mean over that batch; multiply by batch before accumulating. Cd/Cl divide the interval mean reaction by 0.5 U_lattice² D_lattice in each case. Force unit is ρ dx³/dt² per depth, so fine-uniform lattice force is twice root force for the same physical load.
  • Force timestamps are observation-interval midpoints. Pressure uses physical decoded postcollision density at the interval end, extrapolated from fluid-only points one/two fine cells outside the cylinder using existing pressure_probes. Pressure difference is normalized by ρ_ref U_physical². Existing periodic helpers align pressure onto force cycles.
  • Public AMR downloads exclude nonleaves. Fixed geometry masks, not state-dependent finiteness masks, check all fluid populations and sum ρ dx_level²; covered root cells, body, boundaries and fine halos are excluded. Corrupt NaN fluid cannot disappear from the mass check. Mass is per-unit-depth ρ_ref·m². Uniform uses its physical fluid flags and dx². Different sampling of the circular boundary means initial discrete fluid volume can differ slightly; compare temporal stability, not identical absolute mass.
  • Flux samples root/uniform x-index 2 and -3, summed with dx and physical velocity conversion. Those planes differ by grid-scale offsets; cycle-average inlet/outlet balance is the gate, not direct pointwise flux equality.
  • Dense measurement width Δt*=.02 in the pilot and for t*≥240, otherwise .5. Pilot ends t*=5; full ends t*=300. Same existing five-cycle periodicity, mass, flux, and reference gates are imported without modification. Both official-reference diagnostics and refined-versus-uniform cycle comparisons are written. matched_case_pass refers only to matched SRT agreement, not certification of canonical DFG or the broader suite.
  • Safety stop: nonfinite state/reaction, Mach>.2, or density outside [.5,1.5]. GPU durations include required exchange reads and synchronization in stepping; full wall time also includes host measurements. Do not report pure-kernel throughput from these numbers.

Commands

From the repository root, CPU only:

PYTHONPATH=src python tests/unit/test_refined_dfg.py
python tests/validation/run_refined_dfg.py --mode plan --output /tmp/refined-dfg-plan-new

Fourteen CPU tests are retained in tests/unit/test_refined_dfg.py. Plan JSON is configuration output only; no preparation result files are committed. The initial attempt to use pytest was unavailable in this interpreter; tests use standard-library unittest and NumPy instead.

Only after root channel GPU gates pass and root explicitly admits an idle physical GPU, root may run:

CUDA_VISIBLE_DEVICES=<admitted-device> timeout --signal=TERM --kill-after=30s <caller-hard-budget>s python tests/validation/run_refined_dfg.py --mode pilot --gpu-gates-approved --max-wall-seconds <caller-soft-budget> --output <new-pilot-directory>
CUDA_VISIBLE_DEVICES=<admitted-device> timeout --signal=TERM --kill-after=30s <caller-hard-budget>s python tests/validation/run_refined_dfg.py --mode full --gpu-gates-approved --max-wall-seconds <caller-soft-budget> --pilot-results <completed-pilot-directory> --output <new-full-directory>

--gpu-gates-approved is a caller attestation, not proof that GPU tests ran. Full mode additionally requires both matched healthy pilots through t*=5 with identical source hashes, bounds and runner hash. No GPU/Mac/remote operation has been performed for this preparation. Pilot/full outputs must be new/empty. Uniform runs first; an unhealthy case stops the campaign. A full run that fails periodic/matched gates exits nonzero.

Bounded execution and receipt validation

No pilot throughput is known yet; the caller must set a finite positive --max-wall-seconds rather than treating an invented estimate as calibration. After valid pilots, the full-run calibrated budget is 3 × sum_over_cases[startup_seconds + 60 × (pilot_wall_seconds − startup_seconds)]. The full run uses the smaller of that estimate and the caller's explicit ceiling. This uses total measured pilot evolution/observation cost and the full/pilot physical-time ratio (300/5); 3× is a declared safety margin, not a runtime guarantee. The plan records both budgets.

The campaign deadline begins before the first case initialization. Cooperative checks surround initialization, every AMR root step or uniform ≤100-step batch, and measurements. On observed expiry, the runner stops, writes a nonpassing wall_time_limit receipt, and exits 3. A blocking CUDA call cannot be interrupted by these checks: the external timeout watchdog is required, with a hard budget chosen slightly above the soft budget to permit cleanup. Hard termination may leave partial CSV data and no final receipt; that never qualifies as a completed pilot.

Each case emits READY with strict finite JSON and saves ready.json only after its first healthy complete observation, after initialization, actual stepping, force readback, macro/pressure/mass/flux paths and CSV flush all succeeded. No early initialization-only READY is emitted.

Full-run pilot validation rejects nonfinite JSON constants and numeric overflow, wrong case/mode/status, nonboolean health, missing/duplicate/out-of-order rows, wrong step counts or observation times, missing numeric observations, health-limit violations, absent/mismatched READY receipts and invalid timing calibration. It requires exactly 250 observations spanning the full dense t*=5 pilot, source/runner hashes and frozen bounds. Tests include the reviewer's exact NaN-endpoint regression and malformed receipt variants. Synthetic test fixtures exist only in temporary directories and are not simulation results.

Integrated source import guard

The runner's source defaults to this repository root. Before geometry or GPU work, it verifies the pinned source/helper/reference contents and requires the imported CelerisLab package to be exactly <source>/src/CelerisLab/__init__.py. An installed DynamisLab copy or another cached checkout is rejected. Integration changes paths/readability and this explicit import assertion; geometry, numerical definitions, gates, and receipt validation remain frozen. Any new path-formatted runner has its own hash, so old preparation pilot receipts cannot authorize a full run of this integrated runner.