test: add opt-in shifted FP32 Jet CV control

This commit is contained in:
2026-10-18 02:34:54 -07:00
parent 80546a0d95
commit 17f3f11007
3 changed files with 73 additions and 4 deletions
+35
View File
@@ -28,6 +28,41 @@ def eq(rho, u, v):
class Host(unittest.TestCase):
def test_shifted_storage_receipt_preserves_physical_case(self):
for scale in (1, 2):
base = case(scale)
shifted = case(scale, ddf_shifting=True)
self.assertFalse(base.pop("ddf_shifting"))
self.assertTrue(shifted.pop("ddf_shifting"))
self.assertEqual(base.pop("storage_variant")["name"], "unshifted_fp32")
self.assertEqual(shifted.pop("storage_variant")["name"], "shifted_fp32")
self.assertEqual(base, shifted)
def test_shifted_physical_download_roundtrip(self):
from CelerisLab.lbm.population_storage import _encode_physical, _decode_stored
from run_jet_circle_cv import moments
from jet_cv_measurements import primitives
for speed in (0.03, 0.015):
seed = state((9, 48, 64), speed)
self.assertEqual(seed.dtype, np.float32)
plain = _decode_stored(_encode_physical(seed, False), False)
decoded = _decode_stored(_encode_physical(seed, True), True)
self.assertEqual(decoded.dtype, np.float64)
np.testing.assert_array_equal(plain, seed)
# Same FP32 physical seed; only encoding quantization may differ.
np.testing.assert_allclose(decoded, seed, rtol=0, atol=3e-10)
rho, momentum, velocity = moments(decoded)
rho2, velocity2 = primitives(decoded, CX, CY)
np.testing.assert_array_equal(rho, rho2)
np.testing.assert_array_equal(velocity, velocity2)
np.testing.assert_allclose(momentum, rho * velocity, atol=1e-17)
fluid = np.ones(seed.shape[1:], bool)
inv, flux = cv(decoded, fluid, (0, 0), (5, 4, 25, 20), 0.0072)
expected, _ = cv(seed, fluid, (0, 0), (5, 4, 25, 20), 0.0072)
np.testing.assert_allclose(inv, expected, rtol=0, atol=1e-6)
np.testing.assert_allclose(flux, 0, atol=1e-14)
def test_descriptor_and_uniform_closed_flux(self):
from CelerisLab.lbm.descriptors import D2Q9_EX, D2Q9_EY
+24 -4
View File
@@ -18,11 +18,24 @@ CY = np.array([0, 0, 0, 1, -1, 1, -1, -1, 1])
W = np.array([4 / 9] + [1 / 9] * 4 + [1 / 36] * 4)
def case(scale=1, re=100, steps=800):
def case(scale=1, re=100, steps=800, ddf_shifting=False):
u = 0.03 / scale
d = 24.084 * scale
return dict(
scale=scale,
ddf_shifting=bool(ddf_shifting),
storage_variant=dict(
name="shifted_fp32" if ddf_shifting else "unshifted_fp32",
device_populations="g=f-w" if ddf_shifting else "f",
device_dtype="float32",
equilibrium_path=(
"compute_feq_from_momentum" if ddf_shifting else "compute_feq"
),
initial_physical_seed="historical FP32-rounded equilibrium, identical in both variants",
downloaded_populations="physical f, decoded by public stepper.download()",
downloaded_dtype="float64" if ddf_shifting else "float32",
raw_exchange="physical reaction and mass; no host weight correction",
),
re_d=re,
beta=0.1,
nx=192 * scale,
@@ -226,7 +239,7 @@ def run_case(c, ctx, output, provenance, continuation=False):
collision="SRT",
streaming="double_buffer",
store_precision="FP32",
ddf_shifting=False,
ddf_shifting=c.get("ddf_shifting", False),
les_enabled=False,
)
fine_cfg = LBMConfig(
@@ -237,7 +250,7 @@ def run_case(c, ctx, output, provenance, continuation=False):
collision="SRT",
streaming="double_buffer",
store_precision="FP32",
ddf_shifting=False,
ddf_shifting=c.get("ddf_shifting", False),
les_enabled=False,
)
obj = SimObject(
@@ -579,8 +592,15 @@ def main():
action="store_true",
help="Bounded ref0..800 scalar diagnostics at every root interval; sparse rays/fields",
)
p.add_argument(
"--shifted-fp32",
action="store_true",
help="Opt-in shifted numerical-representation control for --dense-root; historical unshifted default unchanged",
)
p.add_argument("--plan", action="store_true")
a = p.parse_args()
if a.shifted_fp32 and not a.dense_root:
p.error("--shifted-fp32 requires the bounded --dense-root campaign")
if a.steps <= 0 or a.steps > 3200:
p.error("steps must be 1..3200")
if a.re == 400 and not a.allow_re400:
@@ -593,7 +613,7 @@ def main():
if a.continuation:
if a.scale not in (1, 2) or a.re != 100 or a.steps != 3200:
p.error("--continuation requires --re 100 --scale 1/2 --steps 3200")
c = case(a.scale, a.re, a.steps)
c = case(a.scale, a.re, a.steps, ddf_shifting=a.shifted_fp32)
if a.continuation:
from jet_cv_measurements import sample_steps, factors