rtx-cfd: overset_cfd23 — Turek–Hron CFD2/CFD3 on the overset (the harness's ramped inflow from rest, TVD background and patch, 3-round cap), loads by the patch wall stress with the solver-flux-form box and the CV formula beside it as window statistics, CFD3 frequency from lift crossings, the solver-metric momentum chain at the final state (solved-face residual is the pin), save/load of the fields by case; momentum_residual checks the far-upwind neighbours explicitly under a limited background (the van Albada limiter swallows a NaN silently)
CI / Test (macos-latest) (push) Canceled after 0s
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Build CPU-Only (Explicit) (push) Canceled after 0s
Documentation / Build User Guide (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 (macos-latest) (push) Canceled after 0s
CI / Build (ubuntu-latest) (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
CI / Distributed Training Tests (push) Canceled after 0s
CI / CI Success (push) Canceled after 0s
Documentation / Build API Documentation (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-06 17:10:18 -07:00
co-authored by Claude Fable 5.1
parent 36af178980
commit ce3cbcce57
2 changed files with 604 additions and 3 deletions
@@ -89,7 +89,9 @@ pub struct FaceResidual {
/// Between two fringe cells (else fringehole).
pub fringe_fringe: bool,
/// The pieces of `r` (N/m): unsteady, convective, diffusive, pressure
/// (`r = time + conv diff + pres`; upwind, interior faces).
/// (`r = time + conv diff + pres` under upwind on interior faces;
/// under a limited scheme the convective piece is the upwind part
/// only and the four do not reconstruct `r`).
pub pieces: [f64; 4],
}
@@ -201,6 +203,27 @@ impl OversetPisoSolver {
};
let vol = dx * dy;
let mut prescribed = Vec::new();
// Under a limited scheme the far-upwind value enters through
// `r > 0`, which a NaN fails silently (a silent upwind fallback),
// so the two-away neighbours are checked explicitly.
let limited = self.background.parameters().convection_scheme
!= crate::solvers::incompressible::ConvectionScheme::Upwind;
let far_ok_u =
|m: &crate::solvers::incompressible::flow_field::FlowField, j: usize, i: usize| {
!limited
|| ((i < 2 || m.u_old[(j, i - 2)].is_finite())
&& (i + 2 > nx || m.u_old[(j, i + 2)].is_finite())
&& (j < 2 || m.u_old[(j - 2, i)].is_finite())
&& (j + 2 >= ny || m.u_old[(j + 2, i)].is_finite()))
};
let far_ok_v =
|m: &crate::solvers::incompressible::flow_field::FlowField, j: usize, i: usize| {
!limited
|| ((j < 2 || m.v_old[(j - 2, i)].is_finite())
&& (j + 2 > ny || m.v_old[(j + 2, i)].is_finite())
&& (i < 2 || m.v_old[(j, i - 2)].is_finite())
&& (i + 2 >= nx || m.v_old[(j, i + 2)].is_finite()))
};
let mu = self.background.config().viscosity;
let upw = |f: f64, a: f64, b: f64| if f >= 0.0 { a } else { b };
// The upwind predictor's pieces on an interior u face, × ρ·vol.
@@ -286,7 +309,10 @@ impl OversetPisoSolver {
}
};
let rhs = self.background.u_rhs(&m, j, i, t_old);
let r = rho * ((m.u[(j, i)] - m.u_old[(j, i)]) / dt - rhs) * vol;
let mut r = rho * ((m.u[(j, i)] - m.u_old[(j, i)]) / dt - rhs) * vol;
if !far_ok_u(&m, j, i) {
r = f64::NAN;
}
bucket.add(r, true);
if ghost_u(j, i) {
prescribed.push(FaceResidual {
@@ -334,7 +360,10 @@ impl OversetPisoSolver {
}
};
let rhs = self.background.v_rhs(&m, j, i, t_old);
let r = rho * ((m.v[(j, i)] - m.v_old[(j, i)]) / dt - rhs) * vol;
let mut r = rho * ((m.v[(j, i)] - m.v_old[(j, i)]) / dt - rhs) * vol;
if !far_ok_v(&m, j, i) {
r = f64::NAN;
}
bucket.add(r, false);
if ghost_v(j, i) {
prescribed.push(FaceResidual {