Files

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Fixed 2:1 patch preparation — implementation handoff, 2026-10-13

Delivered: one production module, src/CelerisLab/lbm/refinement.py (138 lines),
and tests/unit/test_refinement.py (167 lines). No existing code was modified.
The API produces real layer geometry and compact exchange tables. It does not
advance a coupled simulation; numerical coupling remains a joint review item.

Usage (existing config, no CUDA required):
  from CelerisLab.config import load_lbm_config
  from CelerisLab.lbm.refinement import FixedPatch2D
  cfg = load_lbm_config()
  patch = FixedPatch2D.from_config(cfg, (4, 4, 12, 12))
  patch.check_synchronization(0, 0, phase="postcollision_g")
The supplied configuration must satisfy the documented initial backend subset.
Bounds are (x0,y0,x1,y1), half-open, in coarse cells. Shapes are (ny,nx).

Current architecture and data path
  Simulation
    -> LBMConfig -> compiler_v2 -> generated per-domain module
    -> LBMField: Q-major GPU DDF buffers, flags, host mirror, macro buffers
    -> LBMStepper: OneStep + buffer swap, completed coarse-step count
        -> pull -> physical BC -> collision -> stored postcollision_g

  New opt-in preparation path (no change to the above path):
    LBMConfig -> FixedPatch2D.from_config
      -> copied/validated config; coarse/fine tau and layer dimensions
      -> fine_kind: active / inner halo / outer halo (uint8)
      -> paired ghost_fine/ghost_coarse cell indices (uint32)
      -> coalesce_coarse + four coalesce_fine population slots (uint64)
      -> future transfer/step kernels (not implemented in this increment)

Choices and actual implementation
The initial contract is D2Q9/SRT/FP32/unshifted/double_buffer, without LES.
Existing Python lattice descriptors and CUDA Q-major index conventions are
reused. Existing configuration is copied before validation; both layers must
respect its omega guards. Fixed 2:1 acoustic scaling gives tau_f=.5+2*(tau_c-.5).
Fine coordinates use the patch's physical offset, dx=dt=.5 and a four-cell halo.
Only the outer coarse ring is searched for closed-midpoint coalescence targets;
all eight corner-pass links are included. No coarse-domain-sized masks or DDF
arrays are allocated. Standard [4,12)^2 patch tables total 7136 bytes; enlarging
only the coarse grid leaves table size unchanged. Arrays are contiguous/read-only.
An explicit import enables the API; no eager package imports or default-path
branches were added. No tree, dynamic AMR framework, new solver, field hierarchy,
fake stepper, fine LBMField allocation or premature config/runtime switches.

The synchronization method checks count/phase metadata only. It does not inspect
populations or prove that a caller's buffer really holds g. Two coarse cells of
geometric margin certify donor indices, not fluid ownership or physical BC safety.
Runtime forcing, objects and domain BCs still need explicit coupling validation.

Numerical coupling proposal for Claude/Grok joint review — NOT implemented
Let F_n be the reference arrival state and G_n=C(F_n) the production state.
Start from stored G_n, without re-colliding it:
  1. Explode coarse G_n into fine halo once (unscaled, as in pinned CPUREF).
  2. Fine hop 1 -> arrival F_(n+1/2); collide fine active cells once.
  3. Fine hop 2 -> arrival F_(n+1); fine halo ghosts never collide.
  4. Coarse pull -> provisional arrival; replace incoming interface populations
     with the four-child fine-halo average, including corner-pass links.
  5. Collide coarse active cells once and fine active cells a second time,
     publishing synchronized G_(n+1). Equivalent fusion may preserve this order.
Thus each coarse interval has one coarse collision and two fine collisions.
Initialization must establish G_0 consistently; no extra per-step collision may
be added to match a reference plot. Comparing C(F_ref) to production G is a test
observation conversion, not a production step. Do not overwrite postcollision
coarse slots with uncollided coalescence after ordinary OneStep has finished.
The current fused kernel therefore needs a reviewed insertion point before its
collision, with masks preserving covered/halo semantics. Its normal inlet ghost
collision behavior is separate from the fine-halo rule above.

First numerical scope proposed: fixed, unforced, object-free doubly periodic
patch, same baseline tau pair; <=8-step same-phase CPU/GPU comparison after
the coupling design is jointly reviewed. Reuse existing collision/layout
helpers rather than reproduce a solver. Simulation currently constructs channel
flags/wall corrections, so reusing its default initializer does NOT create this
periodic fixture. Boundary selection and level-module ownership must be agreed
before attaching a coupled backend to Simulation. No GPU budget was requested
or consumed in this architecture-only increment; any later GPU run needs an
occupancy check and a specific allocation budget before execution.

The observed ~2.9% excess shear decay does not block topology preparation or a
bounded equivalence implementation, but remains an interface-accuracy concern.
Neither a future <=8-step comparison nor this geometry test establishes 32-step
accuracy, convergence or a stress-transfer mechanism. No nonequilibrium scaling
or time-interpolated ghosts were mixed into the pinned route. Claude's previous
local_stress implementation-code review remains incomplete.

Reference/architecture guard traceability
Read .github/skills/lbm-ref-architecture-guard/SKILL.md; no applicable AGENTS.md
was found in the project/source/test ancestor paths. Concrete source findings:
  - src/CelerisLab/lbm/descriptors.py and kernels/core/layout.cuh define paired
    D2Q9 and q*N+y*nx+x; maps use them rather than a second direction convention.
  - src/CelerisLab/lbm/kernels/step/one_step_double.cu fuses pull/BC/collision;
    src/CelerisLab/lbm/stepper.py swaps the stored g buffers afterward.
  - src/CelerisLab/lbm/field.py builds channel topology and allocates full field
    resources: unsuitable as an implicit fine-patch initializer.
  - ref/lbmpy/src/lbmpy/relaxationrates.py: relaxation_rate_scaling agrees with
    tau_f=.5+2*(tau_c-.5); no population rescaling is inferred from this formula.
  - ref/palabos/src/multiGrid/multiGridGenerator2D.hh: two fine substeps and
    separate interface processors support keeping topology separate from steps.
    Its interpolation/rescaling is a different scheme and was NOT adopted.
  - Pinned CPUREF-0.3 supplies the reviewed closed-corner volumetric geometry.
    Its SHA remains bba2a06a9f6517b32079ffff15e4060d8c3b7ed35f16ca134e1877226c9e4e1e.

Review and validation
Independent local subagent /root/refinement_review read the production module
and related sources and found no blocking issue. Its two suggestions were
adopted: explicitly distinguish fine halo ghosts from inlet ghosts, and cover
the smallest 1x1 patch at the two-coarse-cell margin. This is not a completed
Claude/Grok review of the new coupling proposal.
Ran only tests/unit/test_refinement.py: 9/9 passed, no numerical advance.
Coverage: all exchange maps against pinned reference, eight corner passes,
400 unique fine-slot reads, translated rectangle geometry/child centers,
minimal halo edges, tau/config isolation, compact read-only arrays, index
overflow rejection before allocation, unsupported backend/omega guards,
phase/count rejection, exact source provenance and no CUDA/Simulation imports.
No old diagnostics, physical matrix, Jet replay or GPU tests were rerun.
Python 3.10.13 / NumPy 1.26.4 from existing pycuda_3_10 environment.
PYTHONPATH=/home/frank14f/CelerisLab/src; process-only BLAS thread=1, bytecode
disabled, user site disabled, assertions enabled. Parent and child limited by
prlimit to 256 MiB address space, 2 MiB output file and core=0.
Peak child RSS 36.00390625 MiB, parent 18.5 MiB; child elapsed .274485 s;
combined test stdout/stderr 873 bytes. Full commands, times and source hash
are in validation.json; actual unittest output is validation.txt.

Audit artifacts
baseline.json freezes HEAD, full dirty status and 303 old-file hashes, including
all preceding validation materials. Scope excludes read-only ref, symlinks and
bytecode, as stated in the baseline. incremental.patch is only the two new code
files, relative to the preserved starting tree. manifest.json records final old
file checks and new paths/sizes/SHA. No staging, commit, push or DynamisLab work.
Stopped at the numerical coupling joint-review point.

Authorization, verbatim as relayed by the coordinating thread
<transcript_evidence>
user(Sentinel_ed1ee5edd5e88191a1aaa4d710ce523f): 推进吧,~/CelerisLab就是开发环境,可以改动,只要符合架构风格。遇到问题可以用undermind看文献,也可以让grok搜索互联网信息,还可以参考开源项目。
user(Sentinel_d0d3a42b2c088191aa8aebc105fb1b27): 允许,你用GPU验证都行
</transcript_evidence>