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
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:
co-authored by
Claude Fable 5.1
parent
c144a5f733
commit
c3dbd5040a
@@ -18,7 +18,7 @@ use rtx_cfd::solvers::incompressible::{
|
||||
AleBoundaries, ConvectionScheme, CurvilinearParameters, CurvilinearPisoSolver,
|
||||
EmbeddedParameters, EmbeddedPisoSolver, FlowField, MgPrecision, NormalDiffusion, OversetField,
|
||||
OversetParameters, OversetPisoSolver, OversetResult, OversetSolverState, PatchConvection,
|
||||
PatchField, PoissonSolverKind, SideBoundary,
|
||||
PatchField, PoissonSolverKind, RobinWall, SideBoundary,
|
||||
};
|
||||
use rtx_cfd::{CfdConfig, CfdResult};
|
||||
use rtx_fea::mesh::{Mesh, NodeId};
|
||||
@@ -967,6 +967,24 @@ impl OversetFluid {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// The fluid's traction on every Inner (wall) face, in the patch's
|
||||
/// Inner-face order — the Robin wall's datum for the next pass.
|
||||
pub fn inner_tractions(&self) -> Vec<[f64; 2]> {
|
||||
self.solver
|
||||
.patch()
|
||||
.wall_tractions(&self.field.patch, PatchSide::Inner, self.solver.time())
|
||||
.into_iter()
|
||||
.map(|(_, _, _, t)| t)
|
||||
.collect()
|
||||
}
|
||||
/// Put the Robin wall (impedance `alpha`, datum per Inner face) on the
|
||||
/// patch, or remove it.
|
||||
pub fn set_robin(&mut self, alpha: f64, datum: Option<Vec<[f64; 2]>>) {
|
||||
self.solver
|
||||
.patch_mut()
|
||||
.set_robin_wall(datum.map(|d| RobinWall { alpha, datum: d }));
|
||||
}
|
||||
|
||||
/// Drag and lift on cylinder + flag from the patch's wall stress.
|
||||
pub fn measure_force(&self) -> (f64, f64) {
|
||||
let f = self
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user