rtx-cfd: overset Schwarz stall detection is opt-in (stall_rounds, default 0): right for a steady march (n=64: 2.26 rounds mean, no cap hits, L2 identical), wrong for a transient (falsifier max spike 594 → 4044 N/m when on); the MMS harness sets 2
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 / Test (macos-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_01X2GmJXeQ2njUecEKiJZ1G2
This commit is contained in:
Omar Sobh
2026-09-05 18:35:06 -07:00
co-authored by Claude Fable 5.1
parent e2edff9b1d
commit 6b8837301f
2 changed files with 16 additions and 2 deletions
@@ -52,6 +52,14 @@ pub struct OversetParameters {
/// is pinned only through the fringe and decays weakly across the
/// overlap (measured: 4.5e-3 relative after 20 rounds).
pub anderson_depth: usize,
/// Stall detection: stop a corrector's rounds when the exchanged change
/// has not fallen by 30% over this many rounds (0 = off, the default).
/// Right for a steady march, where the step's `p'` sits at the inner
/// solvers' noise floor and rounds cannot help (at n = 64/128 the cap
/// was burned on 4% of the steps; a 7.5 h n = 128 march); WRONG for a
/// transient — on the falsifier plate it stopped rounds that were still
/// converging and raised the max force spike from 594 to 4044 N/m.
pub stall_rounds: usize,
/// Patch rows below the acceptor row kept non-hole
/// (`overlap::DEFAULT_OVERLAP_ROWS`).
pub overlap_rows: usize,
@@ -64,6 +72,7 @@ impl Default for OversetParameters {
schwarz_tolerance: 1e-3,
max_rounds: 20,
anderson_depth: 3,
stall_rounds: 0,
overlap_rows: overlap::DEFAULT_OVERLAP_ROWS,
}
}
@@ -509,13 +518,14 @@ impl OversetPisoSolver {
done = true;
break;
}
// Stall: no progress over three rounds means the exchanged
// Stall: no progress over two rounds means the exchanged
// values sit at the inner solvers' noise floor (the step's
// own p' is that small near a steady state); more rounds
// cannot help — measured as 6560 of 150k steps burning the
// 20-round cap at n = 64, and a 7.5 h n = 128 march.
history.push(change);
if history.len() >= 4 && change > 0.7 * history[history.len() - 4] {
let k = self.params.stall_rounds;
if k > 0 && history.len() > k && change > 0.7 * history[history.len() - 1 - k] {
schwarz_stalled += 1;
done = true;
break;