P6-b design 2: the Robin wall on the patch's Inner side — RobinWall { alpha, datum } with the wall velocity u_s + (t_f − datum)/α (explicit, damped by the wall's own viscous gain μ/(α d)) and the compliant-wall pressure term |S| p'/α implicit in the projection (the added-mass operator in the fluid's own response); Dirichlet bit for bit when off; MMS pin on the skewed annulus (orders 2.46/2.13 at α = 10 and 100 μ/h, the Dirichlet values; a 1e12 wall reproduces Dirichlet to 2e-6); OversetPisoSolver::patch_mut; harness knob RTX_FSI2O_ROBIN_ALPHA with the previous pass's tractions as the datum, printed in the header
CI / Build (macos-latest) (push) Waiting to run
CI / Test (macos-latest) (push) Blocked by required conditions
CI / Test (ubuntu-latest) (push) Blocked by required conditions
CI / Python Bindings (maturin) (macos-latest) (push) Blocked by required conditions
CI / Python Bindings (maturin) (ubuntu-latest) (push) Blocked by required conditions
CI / WASM Build + Size Check (push) Blocked by required conditions
CI / Distributed Training Tests (push) Blocked by required conditions
CI / CI Success (push) Blocked by required conditions
CI / Build (ubuntu-latest) (push) Failing after 7s
CI / Format Check (push) Failing after 17s
Documentation / Build User Guide (push) Successful in 19s
Documentation / Build API Documentation (push) Failing after 1m51s
CI / Build CPU-Only (Explicit) (push) Failing after 1m58s
CI / Clippy Check (push) Failing after 2m13s
Performance Benchmarks / Run Benchmarks (push) Successful in 2m54s

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01YJPeT6WA2e7YvAnS875AHL
This commit is contained in:
Omar Sobh
2026-09-15 10:46:35 -05:00
co-authored by Claude Fable 5.1
parent c144a5f733
commit c3dbd5040a
12 changed files with 333 additions and 20 deletions
@@ -100,7 +100,7 @@ pub fn run_march_overset(case: BenchmarkCase, config: &OversetMarchConfig) -> Ov
// Every setting the acceptance rule reads, printed once: P5-3 lost a
// day to a floor of 2e-4 against the overnight marches' 1e-6.
println!(
" coupling: {} (reuse {}, ω0 {}, c1 {}), floor {:.1e}, rtol {:.1e}, stall accept {:.1e}, max subit {}, predictor {}, s = {}, patch offset {} h × {} rows, patch convection {:?}, bg convection {:?}, patch stretch {}, fillet {} m, tip corner {} m, fict mass α {}",
" coupling: {} (reuse {}, ω0 {}, c1 {}), floor {:.1e}, rtol {:.1e}, stall accept {:.1e}, max subit {}, predictor {}, s = {}, patch offset {} h × {} rows, patch convection {:?}, bg convection {:?}, patch stretch {}, fillet {} m, tip corner {} m, fict mass α {}, robin α {}",
cfg.coupler,
cfg.reuse,
cfg.initial_relaxation,
@@ -119,6 +119,7 @@ pub fn run_march_overset(case: BenchmarkCase, config: &OversetMarchConfig) -> Ov
super::overset::fillet(),
super::overset::tip_corner(),
std::env::var("RTX_FSI2O_FICT_MASS").unwrap_or_else(|_| "0".into()),
std::env::var("RTX_FSI2O_ROBIN_ALPHA").unwrap_or_else(|_| "0".into()),
);
// Phase 1: rigid flag to t_release (`RTX_FSI2O_LOAD=dir` replaces the
@@ -295,6 +296,22 @@ pub fn run_march_overset(case: BenchmarkCase, config: &OversetMarchConfig) -> Ov
}
a
};
// P6-b design 2 (`docs/overset_metal_campaign.md` §5.19): the Robin wall
// on the patch — `RTX_FSI2O_ROBIN_ALPHA` (Pa·s/m; 0 = the Dirichlet wall
// bit for bit; the plate's impedance is ρ_s h_s / Δt). Each pass gives
// the fluid the tractions of the previous pass as the datum, so at the
// coupled fixed point the wall is the Dirichlet one.
let robin_alpha: f64 = std::env::var("RTX_FSI2O_ROBIN_ALPHA")
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(0.0);
if robin_alpha > 0.0 {
println!(
" Robin wall: α = {robin_alpha:.3e} Pa·s/m (ρ_s h_s / Δt = {:.3e})",
case.rho_s * 0.02 / dt
);
}
let robin_datum: RefCell<Vec<[f64; 2]>> = RefCell::new(Vec::new());
// The load with the compensating term for a given previous-subiterate acceleration.
let with_fict =
|nodal: &[(NodeId, Vector3<f64>)], accel: &[f64]| -> Vec<(NodeId, Vector3<f64>)> {
@@ -383,6 +400,9 @@ pub fn run_march_overset(case: BenchmarkCase, config: &OversetMarchConfig) -> Ov
let (predicted, _) = flag.borrow_mut().step(&flag_state).unwrap();
extract(&predicted)
};
if robin_alpha > 0.0 {
robin_datum.replace(fluid.borrow().inner_tractions());
}
let saved = fluid.borrow().snapshot();
type PassResult = (DynamicState, Vec<(NodeId, Vector3<f64>)>, f64, usize);
let latest: RefCell<Option<PassResult>> = RefCell::new(None);
@@ -390,9 +410,15 @@ pub fn run_march_overset(case: BenchmarkCase, config: &OversetMarchConfig) -> Ov
let fs = std::time::Instant::now();
let mut fl = fluid.borrow_mut();
fl.restore(&saved);
if robin_alpha > 0.0 {
fl.set_robin(robin_alpha, Some(robin_datum.borrow().clone()));
}
fl.advance_subcycled(&d_n, d_candidate, cfg.subcycle, v_n.as_deref())
.expect("fluid pass");
let (nodal, conservation, faces) = fl.sample_load(d_candidate);
if robin_alpha > 0.0 {
robin_datum.replace(fl.inner_tractions());
}
t_fluid.set(t_fluid.get() + fs.elapsed().as_secs_f64());
let ss = std::time::Instant::now();
let mut flag_ref = flag.borrow_mut();