fix(esopull): correct init layout and pre-streaming semantics (v0.5.1)

EsoPull curved boundaries and wall BCs now use consistent backing-layout
reads; InitEsoPull writes equilibrium in t=0 EsoPull layout. Cache N_OBJS
after compile and atomic config header writes to avoid parallel races.
Adds config screening tools, flume configs, and FP16S/EsoPull diagnosis doc.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Frank14fandCursor committed 2026-06-27 22:32:01 +08:00
1 parent 00b957f904
commit 6e3756c587
28 files changed
+1536 -157

No files matched your search

+15 -6
View File
@@ -11,10 +11,19 @@
//
// EsoPull mode:
// PrepareEsoPullCurvedKernel + ApplyEsoPullCurvedKernel run before EsoPullStep.
// SensorKernel / ForceRegionKernel run after, using t = step_count+1 for
// physical-value semantics via esopull_semantic_helpers.cuh.
// Prepare uses load_physical_dir_pre_streaming() for Bouzidi force calc
// (pre-streaming semantics = matching double-buffer fi_in[k, dir]).
// SensorKernel / ForceRegionKernel run after EsoPullStep, using
// t = step_count+1 for post-streaming physical-value semantics.
// Wall boundary functions (bounce_back.cuh) use load_physical_dir_esopull
// inside EsoPullStep (post-streaming, matching load_f_esopull output).
//
// Verified: Kan99b K2 (200k steps, MRT) -- bit-identical to double-buffer.
// NOTE: The wall boundary helpers use post-streaming reads (unlike Bouzidi)
// because they operate inside EsoPullStep on f[] already reconstructed
// by load_f_esopull. Replacing post-streaming f[i] with post-streaming
// f[opp(i)] is the correct half-way bounce-back for EsoPull.
//
// Verified: Kan99b K2 (60k steps, MRT) — bit-identical to double-buffer.
// ============================================================================
#ifndef CELERIS_STEP_AUX_KERNELS_CU
@@ -118,7 +127,7 @@ __global__ void PrepareEsoPullCurvedKernel(
const float Uw = -omega * ry;
const float Vw = omega * rx;
const float f_toward = load_physical_dir_esopull(k_f, dir, fi, j_f, t);
const float f_toward = load_physical_dir_pre_streaming(k_f, dir, fi, j_f, t);
float f_reflected;
if (fallback == CURVED_FALLBACK_BOUZIDI) {
@@ -128,10 +137,10 @@ __global__ void PrepareEsoPullCurvedKernel(
coordinates(k_ff, xff, yff);
unsigned long j_ff[NQ];
compute_neighbors(xff, yff, j_ff);
const float f_toward_ff = load_physical_dir_esopull(k_ff, dir, fi, j_ff, t);
const float f_toward_ff = load_physical_dir_pre_streaming(k_ff, dir, fi, j_ff, t);
f_reflected = compute_bouzidi_reflection(f_toward, f_toward_ff, 0.0f, q, fallback);
} else {
const float f_opp_same = load_physical_dir_esopull(k_f, dir_opp, fi, j_f, t);
const float f_opp_same = load_physical_dir_pre_streaming(k_f, dir_opp, fi, j_f, t);
f_reflected = compute_bouzidi_reflection(f_toward, 0.0f, f_opp_same, q, fallback);
}
} else {