P5 audit exact on the moving path: the composite rebuilt around a saved instant carries the march's dt (from the mesh the march started on — the warm base under RTX_FSI2O_WARM_SWEEPS — whatever patch the instant holds; 0.2 % of dt read as 0.3–5 N/m of solved-face residual), and instants save dt; over 131 instants of the FSI2 march to t = 16 s the solved-face residual is 1.7e-10 at every one
CI / Build (macos-latest) (push) Failing after 18s
CI / Distributed Training Tests (push) Canceled after 0s
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Build CPU-Only (Explicit) (push) Canceled after 0s
CI / Python Bindings (maturin) (macos-latest) (push) Canceled after 0s
CI / Python Bindings (maturin) (ubuntu-latest) (push) Canceled after 0s
CI / WASM Build + Size Check (push) Canceled after 0s
Performance Benchmarks / Run Benchmarks (push) Canceled after 0s
CI / Format Check (push) Canceled after 0s
CI / Clippy Check (push) Canceled after 0s
CI / Build (ubuntu-latest) (push) Canceled after 0s
CI / Test (macos-latest) (push) Canceled after 0s
CI / CI Success (push) Canceled after 0s
Documentation / Build API Documentation (push) Canceled after 0s
Documentation / Build User Guide (push) Canceled after 0s

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_0116sg1Qz1gMv9hdcKP1XUam
This commit is contained in:
Omar Sobh
2026-09-07 12:32:38 -07:00
co-authored by Claude Fable 5.1
parent 06229dd9a2
commit 2c1143076e
@@ -227,15 +227,13 @@ impl OversetFluid {
sweeps,
)?;
// With the warm-started regeneration (`RTX_FSI2O_WARM_SWEEPS`), the
// initial patch is the converged fixed point of the warm build's
// march starts on the converged fixed point of the warm build's
// sweep + re-spacing map, so the chain starts where it stays.
let warm_sweeps: usize = std::env::var("RTX_FSI2O_WARM_SWEEPS")
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(0);
let patch_mesh = if let Some(m) = initial {
m
} else if warm_sweeps > 0 {
let start_mesh = if warm_sweeps > 0 {
let t0 = std::time::Instant::now();
let (m, (it, last)) = rtx_cfd::mesh::patch_gen::cylinder_flag_patch_deformed_from(
Some(&cold_mesh),
@@ -259,13 +257,15 @@ impl OversetFluid {
} else {
cold_mesh
};
// The patch's along-body explicit limit (its wall row is
// line-implicit) beside the background's combined criterion.
// The fluid step is the march's: from the mesh the march started
// on, whatever patch this composite is built around (a saved
// deformed instant) — 0.2 % of dt read as 0.35 N/m of solved-face
// residual in the audit before this.
let mut hs = f64::INFINITY;
for c in 0..patch_mesh.cell_count() {
for (f, _) in patch_mesh.cell_faces(c) {
if patch_mesh.is_sface(f) {
let d = patch_mesh.faces()[f].d;
for c in 0..start_mesh.cell_count() {
for (f, _) in start_mesh.cell_faces(c) {
if start_mesh.is_sface(f) {
let d = start_mesh.faces()[f].d;
hs = hs.min((d[0] * d[0] + d[1] * d[1]).sqrt());
}
}
@@ -273,6 +273,7 @@ impl OversetFluid {
let dt_bg = 0.25 / (2.0 * u_peak / h + 4.0 * NU_F / (h * h));
let dt_patch = 0.4 * (hs * hs / (4.0 * NU_F)).min(hs / u_peak);
let dt_fluid = dt_bg.min(dt_patch);
let patch_mesh = initial.unwrap_or(start_mesh);
let shared = Arc::new(RwLock::new(WallMotion {
polygon: interface
@@ -417,7 +418,11 @@ impl OversetFluid {
}
std::fs::write(
dir.join("meta.txt"),
format!("t {:.17e}\nns {ns}\nnn {nn}\n", self.solver.time()),
format!(
"t {:.17e}\nns {ns}\nnn {nn}\ndt {:.17e}\n",
self.solver.time(),
self.dt_fluid
),
)
.expect("meta");
Ok(())
@@ -444,12 +449,14 @@ impl OversetFluid {
let meta = std::fs::read_to_string(dir.join("meta.txt")).expect("meta");
let mut t = 0.0;
let (mut ns, mut nn) = (0usize, 0usize);
let mut dt_saved: Option<f64> = None;
for line in meta.lines() {
let mut it = line.split_whitespace();
match (it.next(), it.next()) {
(Some("t"), Some(v)) => t = v.parse().expect("t"),
(Some("ns"), Some(v)) => ns = v.parse().expect("ns"),
(Some("nn"), Some(v)) => nn = v.parse().expect("nn"),
(Some("dt"), Some(v)) => dt_saved = v.parse().ok(),
_ => {}
}
}
@@ -483,6 +490,9 @@ impl OversetFluid {
fluid.field.patch.flux = read("flux");
fluid.solver.set_time(t);
fluid.last_d = d.clone();
if let Some(dt) = dt_saved {
fluid.dt_fluid = dt;
}
Ok((fluid, d, t))
}