Phase A: FP16S store precision verification - Kan99b K2 FP16S: quantization sensitivity documented (St 0.170 -> 0.142) - Sah04 S2 FP16S: PASS (St error 1.53% within 5% gate) - Sah04 S4 FP16S: diverges at high blockage (known limitation) Phase B: ddf_shifting code fixes - Fix inlet west_velocity_rho_closure for shifted DDF (common.cuh) - Fix curved force/torque accumulation for shifted DDF (curved_boundary.cuh, aux_kernels.cu) - Fix host upload_ddf() asymmetry (field.py) - Add checkpoint streaming/ddf_shifting match check (checkpoint.py) - MRT shifting fix: MRT is NOT shift-invariant; unshift/reshift around collision - Generalize inlet knowns repair from Zou-He to all west inlet schemes Phase C: EsoPull curved boundary semantic closure (from round 2) - streaming/esopull_semantic_helpers.cuh: single truth for physical-value semantics - step/esopull_macro.cu: MacroscopicEsoPullKernel for correct GPU diagnostics - SensorKernel, ForceRegionKernel share semantic helpers - Kan99b K2: bit-identical to double-buffer - Code-level comments document compatibility boundaries - README updated with compatibility matrix - output/round3_compatibility_summary.md: full round documentation Co-authored-by: Cursor <cursoragent@cursor.com>
4.3 KiB
Round 3: FP16S and ddf_shifting compatibility
Date: 2026-06-03 Duration: 8+ hours of code + testing
Summary of work
This round added and verified FP16S store precision and ddf_shifting mode compatibility across the body module, curved boundary, and diagnostics pipeline.
Primary achievements
1. MRT shifting fix (critical)
Problem discovered: D2Q9 MRT is NOT shift-invariant in moment space because M(w) produces non-zero entries in m[1] (energy) and m[2] (energy^2). Previous assumption that "f - feq cancels weights pairwise" only holds for SRT/TRT (per-direction collision), not for MRT (moment-space collision).
Fix applied: When USE_DDF_SHIFTING=1, collide_mrt now:
- Unshifts
g[i] += w[i]at entry (physical space) - Performs full MRT collision in physical space
- Reshifts
g[i] -= w[i]at exit
Verified: MRT + ddf_shifting + zou_he_local produces K2 results with amp_CL recovering from 0.007 to 0.476.
Note on D3Q19: Has a compute_feq inconsistency (shifted feq applied to unshifted g) that needs fixing before D3Q19 shifting is usable.
2. ddf_shifting code fixes
| Fix | File | Status |
|---|---|---|
| Inlet west_velocity_rho_closure +5/6 correction | inlet/common.cuh |
Verified, both D2Q9 and D3Q19 |
| Curved force/torque +2*w_i correction | curved_boundary.cuh, aux_kernels.cu |
Verified |
| Host upload_ddf() asymmetry (subtract weights before upload) | field.py |
Verified |
| Checkpoint streaming and ddf_shifting match check | checkpoint.py |
Implemented |
3. Inlet knowns repair generalization (partial)
The repair_zou_he_west_knowns_d2q9 function was moved from Zou-He-only to all west inlet schemes in inlet_outlet.cuh. This fixes free-slip y-wall contamination of ghost-node populations. However, this alone was insufficient to fix the regularized+shifting issue.
4. EsoPull curved boundary (from Round 2, documented here for posterity)
Verified against Kan99b K2: bit-identical metrics between double_buffer and esopull streaming.
Key architectural decisions:
streaming/esopull_semantic_helpers.cuh-- single source of truth for physical-value semanticsMacroscopicEsoPullKernel-- GPU-side diagnostics (not host raw decode)Prepare + Applytwo-phase curved boundary
Current compatibility matrix
Verified (passes K2/Sah04 benchmarks)
| Config | Details |
|---|---|
| FP32 + MRT + double_buffer | Full validation (all Kan99b, Sah04) |
| FP32 + MRT + esopull | K2 bit-identical to double_buffer |
| FP16S + MRT + double_buffer | Sah04 S2 passes |
| ddf_shifting + MRT + zou_he_local | K2 amp_CL recovered, full validation pending |
Known limitations
| Issue | Severity | Status |
|---|---|---|
| FP16S K2 St deviation (0.170 vs 0.142) | Medium -- quantization noise in curved region | Documented, acceptable for low-Re research |
| FP16S S4 divergence at step 71420 | Medium -- high-blockage quantization + wall-gap | Use FP32 for high-blockage |
| ddf_shifting + regularized inlet + MRT | High -- suppressed shedding even after inlet repair | Regularized in shifting needs root cause. Use zou_he_local for now. |
| D3Q19 MRT shifting patch incomplete | Medium -- shifted feq applied to unshifted g | Not in 2D scope, TODO noted in code |
| ddf_shifting + esopull combined | Not verified | Both paths validated separately but not together |
Key lessons recorded
-
SRT/TRT are shift-invariant; MRT is NOT. The weight vector w has non-zero moment space projection. Always shift/unshift around MRT.
-
Repair_zou_he_west_knowns is NOT Zou-He-specific. Every west inlet scheme using
west_velocity_rho_closure_d2q9()needs it under free-slip y-walls. -
FP16S failure modes are specific: Low-blockage (S2) is fine; rotating cylinder (K2) shows quantization sensitivity; high-blockage (S4) can diverge. Test all three regimes before claiming FP16S works.
-
compute_feqin shifting mode returnsfeq - w, notfeq. This is correct for SRT/TRT (NEQ terms cancel w), but causes a bias when paired with an unshiftedg(D3Q19 MRT case). -
Host DDF path is not symmetric under shifting.
download_ddf()adds back w;upload_ddf()(before fix) did not subtract w. This breaks host-side initialization, snapshot/restore, and add_vortex under shifting.