Add jet, surface and fixed-patch tests and runnable examples

This commit is contained in:
Frank14f
2026-10-15 10:13:49 +08:00
parent ed1a6ee54e
commit cdbb9c42f6
48 changed files with 9267 additions and 210 deletions
+84 -85
View File
@@ -26,7 +26,6 @@ from dataclasses import dataclass
from typing import Any, Dict, List, Optional, Sequence, Tuple
import numpy as np
import pycuda.driver as cuda
_PKG_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))
_DEFAULT_LBM = os.path.join(_PKG_ROOT, "src", "CelerisLab", "configs", "config_lbm.json")
@@ -288,95 +287,92 @@ def run_one_simulation(
]
}
tmpd = tempfile.mkdtemp(prefix="celeris_sah04_mrt_")
lbm_tmp = os.path.join(tmpd, "config_lbm.json")
body_tmp = os.path.join(tmpd, "config_body.json")
_write_json(lbm_tmp, cfg)
_write_json(body_tmp, body_doc)
from CelerisLab import Simulation
from CelerisLab import Simulation # noqa: WPS433
with tempfile.TemporaryDirectory(prefix="celeris_sah04_mrt_") as tmpd:
lbm_tmp = os.path.join(tmpd, "config_lbm.json")
body_tmp = os.path.join(tmpd, "config_body.json")
_write_json(lbm_tmp, cfg)
_write_json(body_tmp, body_doc)
with Simulation(lbm_config_path=lbm_tmp, body_config_path=body_tmp) as sim, sim.ctx.activate():
sim.initialize()
sim = Simulation(lbm_config_path=lbm_tmp, body_config_path=body_tmp)
sim.initialize()
stream = sim.stream
rec_every = max(1, int(record_every))
lift_hist: List[float] = []
fx_hist: List[float] = []
step_hist: List[int] = []
stream = cuda.Stream()
rec_every = max(1, int(record_every))
lift_hist: List[float] = []
fx_hist: List[float] = []
step_hist: List[int] = []
n_curved = int(sim.field.n_curved)
fallback_links = int(sim.bodies.fallback_link_count())
low_q_links = int(sim.bodies.low_q_link_count())
n_curved = int(sim.field.n_curved)
fallback_links = int(sim.bodies.fallback_link_count())
low_q_links = int(sim.bodies.low_q_link_count())
for step in range(1, int(steps) + 1):
sim.bodies.zero_force_segment_async(stream)
sim.stepper.step(
1,
action_gpu=sim.bodies.action_gpu,
obs_gpu=sim.bodies.obs_gpu,
stream=stream,
)
if step % rec_every == 0 or step == int(steps):
stream.synchronize()
sim.bodies.download_obs_full_async(stream)
stream.synchronize()
fvec = sim.bodies.read_force(0, normalize=False)
lift = float(fvec[1])
drag = float(fvec[0])
if not np.isfinite(lift) or not np.isfinite(drag):
crash_npz_path: Optional[str] = None
crash_png_path: Optional[str] = None
if crash_dump_dir:
os.makedirs(crash_dump_dir, exist_ok=True)
for step in range(1, int(steps) + 1):
sim.bodies.zero_force_segment_async(stream)
sim.stepper.step(
1,
action_gpu=sim.bodies.action_gpu,
obs_gpu=sim.bodies.obs_gpu,
stream=stream,
)
if step % rec_every == 0 or step == int(steps):
stream.synchronize()
macro_bad = sim.get_macroscopic()
ux_bad = np.asarray(macro_bad["ux"], dtype=np.float64).reshape(geometry.ny, geometry.nx)
uy_bad = np.asarray(macro_bad["uy"], dtype=np.float64).reshape(geometry.ny, geometry.nx)
rho_bad = np.asarray(macro_bad["rho"], dtype=np.float64).reshape(geometry.ny, geometry.nx)
prefix = f"{case.case_id.lower()}_{str(collision).lower()}_crash_step{step}"
crash_npz_path = os.path.join(crash_dump_dir, f"{prefix}.npz")
np.savez_compressed(
crash_npz_path,
rho=rho_bad.astype(np.float32),
ux=ux_bad.astype(np.float32),
uy=uy_bad.astype(np.float32),
step=np.array([int(step)], dtype=np.int64),
case_id=np.array([case.case_id]),
collision=np.array([str(collision)]),
inlet_scheme=np.array([str(inlet_scheme)]),
outlet_mode=np.array([str(outlet_mode)]),
)
crash_png_path = os.path.join(crash_dump_dir, f"{prefix}.png")
try:
save_final_vorticity_png(
crash_png_path,
ux_bad,
uy_bad,
title=(
f"Sah04 {case.case_id} {collision} crash@{step} "
f"D={int(geometry.diameter)} H={geometry.h_fluid}"
),
)
except Exception: # noqa: BLE001
crash_png_path = None
sim.close()
msg = f"NaN/Inf force at step {step}"
if crash_npz_path:
msg += f"; crash_npz={crash_npz_path}"
if crash_png_path:
msg += f"; crash_png={crash_png_path}"
raise RuntimeError(msg)
lift_hist.append(lift)
fx_hist.append(drag)
step_hist.append(step)
sim.bodies.download_obs_full_async(stream)
stream.synchronize()
fvec = sim.bodies.read_force(0, normalize=False)
lift = float(fvec[1])
drag = float(fvec[0])
if not np.isfinite(lift) or not np.isfinite(drag):
crash_npz_path: Optional[str] = None
crash_png_path: Optional[str] = None
if crash_dump_dir:
os.makedirs(crash_dump_dir, exist_ok=True)
stream.synchronize()
macro_bad = sim.get_macroscopic()
ux_bad = np.asarray(macro_bad["ux"], dtype=np.float64).reshape(geometry.ny, geometry.nx)
uy_bad = np.asarray(macro_bad["uy"], dtype=np.float64).reshape(geometry.ny, geometry.nx)
rho_bad = np.asarray(macro_bad["rho"], dtype=np.float64).reshape(geometry.ny, geometry.nx)
prefix = f"{case.case_id.lower()}_{str(collision).lower()}_crash_step{step}"
crash_npz_path = os.path.join(crash_dump_dir, f"{prefix}.npz")
np.savez_compressed(
crash_npz_path,
rho=rho_bad.astype(np.float32),
ux=ux_bad.astype(np.float32),
uy=uy_bad.astype(np.float32),
step=np.array([int(step)], dtype=np.int64),
case_id=np.array([case.case_id]),
collision=np.array([str(collision)]),
inlet_scheme=np.array([str(inlet_scheme)]),
outlet_mode=np.array([str(outlet_mode)]),
)
crash_png_path = os.path.join(crash_dump_dir, f"{prefix}.png")
try:
save_final_vorticity_png(
crash_png_path,
ux_bad,
uy_bad,
title=(
f"Sah04 {case.case_id} {collision} crash@{step} "
f"D={int(geometry.diameter)} H={geometry.h_fluid}"
),
)
except Exception: # noqa: BLE001
crash_png_path = None
msg = f"NaN/Inf force at step {step}"
if crash_npz_path:
msg += f"; crash_npz={crash_npz_path}"
if crash_png_path:
msg += f"; crash_png={crash_png_path}"
raise RuntimeError(msg)
lift_hist.append(lift)
fx_hist.append(drag)
step_hist.append(step)
stream.synchronize()
macro_last = sim.get_macroscopic()
ux_last = np.asarray(macro_last["ux"], dtype=np.float64).reshape(geometry.ny, geometry.nx)
uy_last = np.asarray(macro_last["uy"], dtype=np.float64).reshape(geometry.ny, geometry.nx)
rho_last = np.asarray(macro_last["rho"], dtype=np.float64).reshape(geometry.ny, geometry.nx)
sim.close()
stream.synchronize()
macro_last = sim.get_macroscopic()
ux_last = np.asarray(macro_last["ux"], dtype=np.float64).reshape(geometry.ny, geometry.nx)
uy_last = np.asarray(macro_last["uy"], dtype=np.float64).reshape(geometry.ny, geometry.nx)
rho_last = np.asarray(macro_last["rho"], dtype=np.float64).reshape(geometry.ny, geometry.nx)
if final_vorticity_png_path:
out_dir = os.path.dirname(os.path.abspath(final_vorticity_png_path))
@@ -652,7 +648,10 @@ def main() -> int:
},
)
print(f"Wrote: {json_out_path}", flush=True)
return 0
failed = evaluation["cases_failed"] > 0
if not args.smoke:
failed |= not evaluation["pass_gate_all_completed"]
return int(failed)
if __name__ == "__main__":