rtx-cfd: overset A-P3 — the falsifier plate on the overset (FAILS the registered gates by one order less than the staircase); wall force; composite pressure-level pin; Schwarz stall detection
Documentation / Build API Documentation (push) Canceled after 0s
Documentation / Build User Guide (push) Canceled after 0s
Performance Benchmarks / Run Benchmarks (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
CI / Distributed Training Tests (push) Canceled after 0s
CI / CI Success (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
Documentation / Build API Documentation (push) Canceled after 0s
Documentation / Build User Guide (push) Canceled after 0s
Performance Benchmarks / Run Benchmarks (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
CI / Distributed Training Tests (push) Canceled after 0s
CI / CI Success (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
patch_gen::{stadium, graded_fractions}: the falsifier plate as a stadium O-grid
(semicircular ends r = half-thickness; 16 cells per end arc, straights graded
0.30 h -> h at 1.15, offset 6 h, 12 rows stretched 4x; 148x12 cells, every ray
a normal, worst non-orthogonality 4 deg). CurvilinearPisoSolver::surface_force
(+ PatchLoad): F = sum(-p_f S_f + mu (grad u + grad u^T)_f . S_f) on the wall
faces with the wall cell's LSQ gradients (wall Dirichlet in the velocity fit);
HELD on the phantom circle against the exact stress integral: 1.3e-2 / 6.3e-3 /
3.6e-3 at n = 32/64/128 (orders 1.05 / 0.81), 22x the staircase's accuracy.
OversetPisoSolver: the composite p' level pinned to zero mean over the active
cells every round (the coupled problem is pure Neumann; the temporal warm start
handed each step's level to the next — background pressure 1e7 growing 5e4 per
step on the falsifier; an unpinned level also inflated the relative Schwarz
stop); stall detection (no progress over three rounds = the inner solvers'
noise floor; 6560 of 150k steps burned the 20-round cap at n = 64, a 7.5 h
n = 128 march); schwarz_stalled in the result.
tests/overset_falsifier.rs (records; RTX_OVERSET_FALSIFIER_STRICT asserts the
registered gates, _LADDER runs dt/2 and dt/4, _TRACE the top-12 spike steps):
max spike 594 / 981 / 1720 N/m at dt / dt/2 / dt/4 (staircase 6490 / 12600 /
25600), rms spike 61-89 (810), far probe 502-1509 (7900), KE injection 0.16-0.21
J/m per event on the common cell set (2.6) — every large spike a ~104-cell
full-row reclassification; exponent -0.77 (-1.0). The registered 5% gate (8.75
N/m) is missed 68x: the overset's own reclassification impulse is the finding
(omni-cortex overset_metal_campaign.md §5.10); P3b = locate per cell, then the
fringe flux balance. tests/patch_stadium.rs, curvilinear_loads.rs,
overset_common::plate_patch.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01X2GmJXeQ2njUecEKiJZ1G2
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
afd1bff6ee
commit
e2edff9b1d
@@ -85,6 +85,9 @@ pub struct OversetResult {
|
||||
pub rounds: Vec<usize>,
|
||||
/// Whether every corrector's Schwarz iteration met its stop.
|
||||
pub schwarz_converged: bool,
|
||||
/// Correctors whose rounds stalled at the inner solvers' noise floor
|
||||
/// (no progress over three rounds) and were stopped there.
|
||||
pub schwarz_stalled: usize,
|
||||
/// Background mass residual after the last corrector (its own measure).
|
||||
pub background_residual: f64,
|
||||
/// Largest patch cell imbalance after the last corrector.
|
||||
@@ -296,6 +299,33 @@ impl OversetPisoSolver {
|
||||
self.background.initialize(&mut field.background)
|
||||
}
|
||||
|
||||
/// Subtract the mean of `p'` over the active background cells (the
|
||||
/// composite level pin; the fringe cells' Dirichlet values shift with
|
||||
/// it so the face corrections across active–fringe faces are unchanged).
|
||||
fn remove_background_mean(&self, field: &mut FlowField) {
|
||||
let (nx, ny, _, _) = self.grid;
|
||||
let (mut sum, mut count) = (0.0, 0usize);
|
||||
for j in 0..ny {
|
||||
for i in 0..nx {
|
||||
if self.overlap.class(j, i) == CellClass::Active {
|
||||
sum += field.p_prime[(j, i)];
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if count == 0 {
|
||||
return;
|
||||
}
|
||||
let mean = sum / count as f64;
|
||||
for j in 0..ny {
|
||||
for i in 0..nx {
|
||||
if self.overlap.class(j, i) != CellClass::Hole {
|
||||
field.p_prime[(j, i)] -= mean;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The exchange for the next step: prescribed background faces and
|
||||
/// fringe `p` from the patch's cell field; acceptor `u, v, p` from the
|
||||
/// background.
|
||||
@@ -410,6 +440,7 @@ impl OversetPisoSolver {
|
||||
let n_acc = self.overlap.acceptors.len();
|
||||
let mut rounds = Vec::with_capacity(self.params.corrector_steps);
|
||||
let mut schwarz_converged = true;
|
||||
let mut schwarz_stalled = 0usize;
|
||||
let mut residual_history = Vec::new();
|
||||
let mut final_residual = f64::INFINITY;
|
||||
let mut patch_iterations = 0usize;
|
||||
@@ -432,6 +463,7 @@ impl OversetPisoSolver {
|
||||
let mut patch_pc = vec![0.0; self.patch.mesh().cell_count()];
|
||||
let mut done = false;
|
||||
let mut used = 0usize;
|
||||
let mut history: Vec<f64> = Vec::new();
|
||||
for round in 0..self.params.max_rounds.max(1) {
|
||||
used = round + 1;
|
||||
// Patch with Dirichlet a.
|
||||
@@ -453,6 +485,14 @@ impl OversetPisoSolver {
|
||||
dt,
|
||||
corrector == 0 || round > 0,
|
||||
)?;
|
||||
// Pin the composite level: the coupled p' problem is pure
|
||||
// Neumann (walls everywhere), so its constant mode is
|
||||
// undamped by the rounds and the warm start hands each
|
||||
// step's level to the next — measured as a background
|
||||
// pressure of 1e7 growing 5e4 per step on the falsifier.
|
||||
// A constant in p' moves no velocity; zero mean over the
|
||||
// active cells pins it.
|
||||
self.remove_background_mean(&mut field.background);
|
||||
let g = self.overlap.acceptor_scalar(&field.background.p_prime);
|
||||
let r: Vec<f64> = g.iter().zip(&a).map(|(x, y)| x - y).collect();
|
||||
let g_max = g.iter().fold(0.0_f64, |m, v| m.max(v.abs()));
|
||||
@@ -469,6 +509,17 @@ impl OversetPisoSolver {
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
// Stall: no progress over three 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] {
|
||||
schwarz_stalled += 1;
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
let next = anderson.next(&a, &r);
|
||||
// Guard: an extrapolation far beyond the data is noise-driven;
|
||||
// take the plain Schwarz step instead.
|
||||
@@ -525,6 +576,7 @@ impl OversetPisoSolver {
|
||||
Ok(OversetResult {
|
||||
rounds,
|
||||
schwarz_converged,
|
||||
schwarz_stalled,
|
||||
background_residual: bg.solver_result.final_residual,
|
||||
patch_max_divergence: patch_max_div,
|
||||
patch_poisson_iterations: patch_iterations,
|
||||
|
||||
Reference in New Issue
Block a user