Files
CelerisLab/tests/unit/test_refinement_mrt.py
T
ClaudeandClaude Opus 5.5 00d7a54829 feat: opt-in MRT collision for blocked/refined stepping
Additive compile-time COLLISION_MODEL == 2 branches in BlockStep,
BlockChannelStep and patch_collide repeat the uniform collide_dispatch
MRT sequence (zero forcing, omega clamp, collide_mrt_no_force). SRT
statements, including the shifted retained-delta/direct-momentum path,
are unchanged under the alternate branch. Guards accept SRT or MRT only;
TRT, LES, non-FP32, non-double-buffer and shifted dense/mixed refinement
stay rejected. Transfers, subcycling, BFL, raw ledgers, channel closures,
shifted-Jet SRT guard and PeriodicBlockStepper are untouched. Existing
MRT operator, shifted representation and fixed kinetic rates are reused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 10:26:55 +00:00

41 lines
2.0 KiB
Python

"""Host guards and source contract for MRT reuse in refined/blocked stepping (no CUDA)."""
from pathlib import Path
import pytest
from CelerisLab.config import LBMConfig
from CelerisLab.lbm.refinement import FixedPatch2D
KERNELS = Path(__file__).resolve().parents[2] / "src/CelerisLab/lbm/kernels"
@pytest.mark.parametrize("collision", ["SRT", "MRT"])
def test_patch_accepts_implemented_models(collision):
FixedPatch2D.from_config(LBMConfig(nx=24, ny=20, viscosity=.1, collision=collision), (8, 6, 16, 14))
@pytest.mark.parametrize("options", [dict(collision="TRT"), dict(collision="MRT", les_enabled=True)])
def test_patch_rejects_unimplemented(options):
with pytest.raises(ValueError):
FixedPatch2D.from_config(LBMConfig(nx=24, ny=20, viscosity=.1, **options), (8, 6, 16, 14))
def test_srt_statements_and_guards_preserved():
"""MRT is an additive compile-time branch; SRT statements and other guards remain."""
blocks = (KERNELS / "blocks.cu").read_text()
channel = (KERNELS / "step/block_channel.cu").read_text()
refinement = (KERNELS / "refinement.cu").read_text()
for text in ("compute_feq_from_momentum(drho, jx, jy, ux, uy, feq);",
"compute_feq(rho, ux, uy, feq);",
"collide_srt_no_force(f, feq, d_params.omega);"):
assert text in blocks
assert "collide_srt(f, feq, forcing, omega);" in channel
assert "collide_srt_no_force(f, feq, d_params.omega);" in refinement
for source in (blocks, refinement):
assert "(COLLISION_MODEL != 0 && COLLISION_MODEL != 2)" in source
assert "USE_LES" in source and "STORE_PRECISION != 0" in source
assert "USE_DDF_SHIFTING ||" in refinement # dense/mixed shifted stays rejected
for source in (blocks, channel, refinement):
assert source.count("collide_mrt_no_force(") == 1 # one MRT-only collision site each
for source in (blocks, refinement):
assert '#if COLLISION_MODEL == 2\n#include "operators/collision_mrt.cuh"\n#endif' in source