CelerisLab/output/round3_compatibility_summary.md
Frank14f d5b7e98750 feat(compat): FP16S and ddf_shifting compatibility, EsoPull curved closure
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>
2026-06-03 10:48:42 +08:00

79 lines
4.3 KiB
Markdown

# 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:
1. Unshifts `g[i] += w[i]` at entry (physical space)
2. Performs full MRT collision in physical space
3. 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 semantics
- `MacroscopicEsoPullKernel` -- GPU-side diagnostics (not host raw decode)
- `Prepare + Apply` two-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
1. **SRT/TRT are shift-invariant; MRT is NOT.** The weight vector w has non-zero moment space projection. Always shift/unshift around MRT.
2. **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.
3. **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.
4. **`compute_feq` in shifting mode returns `feq - w`, not `feq`.** This is correct for SRT/TRT (NEQ terms cancel w), but causes a bias when paired with an unshifted `g` (D3Q19 MRT case).
5. **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.