P6-b: the fictitious added mass for the partitioned loop — rtx-fea NonlinearDynamicStepper::set_added_lumped_mass (a lumped per-DOF mass in the Newmark inertial residual and effective tangent, never the consistent mass or the rest state; zero = the plain stepper bit for bit) with its pin (compensated step reproduces the plain step to 2.5e-9, uncompensated moves it 11 %); the FSI2 overset harness carries RTX_FSI2O_FICT_MASS=α (α × ρ_f π (c/2)² spread over the wetted nodes) and adds the compensating load M_f ü_k of the previous subiterate to every structure solve (predictor and passes), printed in the header
CI / Format Check (push) Failing after 7s
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 / Clippy Check (push) Failing after 5s
CI / Build (ubuntu-latest) (push) Failing after 5s
Performance Benchmarks / Run Benchmarks (push) Failing after 6s
Documentation / Build User Guide (push) Successful in 6s
Documentation / Build API Documentation (push) Failing after 25s
CI / Build CPU-Only (Explicit) (push) Failing after 1m15s
CI / Format Check (push) Failing after 7s
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 / Clippy Check (push) Failing after 5s
CI / Build (ubuntu-latest) (push) Failing after 5s
Performance Benchmarks / Run Benchmarks (push) Failing after 6s
Documentation / Build User Guide (push) Successful in 6s
Documentation / Build API Documentation (push) Failing after 25s
CI / Build CPU-Only (Explicit) (push) Failing after 1m15s
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
e54729241d
commit
a2086a59de
@@ -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",
|
||||
" 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 α {}",
|
||||
cfg.coupler,
|
||||
cfg.reuse,
|
||||
cfg.initial_relaxation,
|
||||
@@ -118,6 +118,7 @@ pub fn run_march_overset(case: BenchmarkCase, config: &OversetMarchConfig) -> Ov
|
||||
super::overset::patch_stretch(),
|
||||
super::overset::fillet(),
|
||||
super::overset::tip_corner(),
|
||||
std::env::var("RTX_FSI2O_FICT_MASS").unwrap_or_else(|_| "0".into()),
|
||||
);
|
||||
|
||||
// Phase 1: rigid flag to t_release (`RTX_FSI2O_LOAD=dir` replaces the
|
||||
@@ -236,6 +237,57 @@ pub fn run_march_overset(case: BenchmarkCase, config: &OversetMarchConfig) -> Ov
|
||||
}
|
||||
v
|
||||
};
|
||||
let extract_accel = |state: &DynamicState| -> Vec<f64> {
|
||||
let mut a = vec![0.0; 2 * wetted_dofs.len()];
|
||||
for (k, dofs) in wetted_dofs.iter().enumerate() {
|
||||
a[2 * k] = state.acceleration[dofs[0]];
|
||||
a[2 * k + 1] = state.acceleration[dofs[1]];
|
||||
}
|
||||
a
|
||||
};
|
||||
// P6-b (`docs/overset_metal_campaign.md` §5.17): the fictitious added
|
||||
// mass — `RTX_FSI2O_FICT_MASS=α` puts α × ρ_f π (c/2)² (the flag's heave
|
||||
// added mass per unit depth, c = 0.35) as a lumped mass spread over the
|
||||
// wetted nodes, and every structure solve carries the compensating load
|
||||
// M_f ü_k of the previous subiterate, so the fixed point is unchanged
|
||||
// and the loop contracts at any mass ratio. α = 0 is the plain loop.
|
||||
let fict_alpha: f64 = std::env::var("RTX_FSI2O_FICT_MASS")
|
||||
.ok()
|
||||
.and_then(|v| v.parse().ok())
|
||||
.unwrap_or(0.0);
|
||||
let fict_per_node = fict_alpha * 1000.0 * std::f64::consts::PI * (0.35_f64 / 2.0).powi(2)
|
||||
/ wetted_dofs.len() as f64;
|
||||
let wetted_nodes: Vec<NodeId> = fluid.interface.wetted.clone();
|
||||
if fict_alpha != 0.0 {
|
||||
let entries: Vec<(NodeId, f64)> =
|
||||
wetted_nodes.iter().map(|&n| (n, fict_per_node)).collect();
|
||||
flag.borrow_mut().set_added_lumped_mass(&entries);
|
||||
println!(
|
||||
" fictitious added mass: α = {fict_alpha}, {:.3} kg per wetted node ({} nodes, {:.1} kg total)",
|
||||
fict_per_node,
|
||||
wetted_dofs.len(),
|
||||
fict_per_node * wetted_dofs.len() as f64
|
||||
);
|
||||
}
|
||||
// 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>)> {
|
||||
if fict_alpha == 0.0 {
|
||||
return nodal.to_vec();
|
||||
}
|
||||
let mut out = nodal.to_vec();
|
||||
for (k, &n) in wetted_nodes.iter().enumerate() {
|
||||
out.push((
|
||||
n,
|
||||
Vector3::new(
|
||||
fict_per_node * accel[2 * k],
|
||||
fict_per_node * accel[2 * k + 1],
|
||||
0.0,
|
||||
),
|
||||
));
|
||||
}
|
||||
out
|
||||
};
|
||||
|
||||
// Phase 2: release under the current load.
|
||||
let (nodal0, conservation0, faces0) = fluid.sample_load(&zero_d);
|
||||
@@ -293,15 +345,21 @@ pub fn run_march_overset(case: BenchmarkCase, config: &OversetMarchConfig) -> Ov
|
||||
.unwrap_or(0);
|
||||
let phase_start = std::time::Instant::now();
|
||||
|
||||
// The previous subiterate's interface acceleration (the fictitious mass's
|
||||
// compensating load): the committed state's at each step's start.
|
||||
let last_accel: RefCell<Vec<f64>> = RefCell::new(extract_accel(&flag_state));
|
||||
for step in 0..coupled_steps {
|
||||
last_accel.replace(extract_accel(&flag_state));
|
||||
let d_n = extract(&flag_state);
|
||||
let v_n: Option<Vec<f64>> = cfg.c1_interface.then(|| extract_velocity(&flag_state));
|
||||
let d_predicted = if cfg.predictor == "kinematic" {
|
||||
let v = extract_velocity(&flag_state);
|
||||
d_n.iter().zip(&v).map(|(d, v)| d + dt * v).collect()
|
||||
} else {
|
||||
flag.borrow_mut().set_nodal_forces(&committed_nodal);
|
||||
flag.borrow_mut()
|
||||
.set_nodal_forces(&with_fict(&committed_nodal, &extract_accel(&flag_state)));
|
||||
let (predicted, _) = flag.borrow_mut().step(&flag_state).unwrap();
|
||||
last_accel.replace(extract_accel(&predicted));
|
||||
extract(&predicted)
|
||||
};
|
||||
let saved = fluid.borrow().snapshot();
|
||||
@@ -317,8 +375,9 @@ pub fn run_march_overset(case: BenchmarkCase, config: &OversetMarchConfig) -> Ov
|
||||
t_fluid.set(t_fluid.get() + fs.elapsed().as_secs_f64());
|
||||
let ss = std::time::Instant::now();
|
||||
let mut flag_ref = flag.borrow_mut();
|
||||
flag_ref.set_nodal_forces(&nodal);
|
||||
flag_ref.set_nodal_forces(&with_fict(&nodal, &last_accel.borrow()));
|
||||
let (candidate_state, _) = flag_ref.step(&flag_state).unwrap();
|
||||
last_accel.replace(extract_accel(&candidate_state));
|
||||
t_structure.set(t_structure.get() + ss.elapsed().as_secs_f64());
|
||||
let d_new = extract(&candidate_state);
|
||||
if step < cfg.trace_steps {
|
||||
|
||||
Reference in New Issue
Block a user