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>
79 lines
4.3 KiB
Markdown
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.
|