rtx-fsi: spike-clamp the force-measurement probe
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 / 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
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 / 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 / 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
Documentation / Build API Documentation (push) Canceled after 0s
Documentation / Build User Guide (push) Canceled after 0s
measure_force integrated raw traction samples while the coupling loads carried the 20x-median clamp — so the s = 1 benchmark run's REPORTED drag/lift were +-4,000-scale garbage against a +-78 reference while its displacements matched the benchmark to 0.1%. Collect, clamp, then integrate, both probes. Reporting only: the committed FSI2 default reproduces its trajectory to every printed digit (uy 3.7732 / 3.7920 mm) and its rigid-phase drag (121.4) with the clamp in. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Lnyrw33Lu6rUhW42E9KHwq
This commit is contained in:
co-authored by
Claude Fable 5
parent
c1bcdc408e
commit
555a72cbc0
@@ -449,8 +449,13 @@ impl Fsi2Harness {
|
||||
let mask = solver.mask().unwrap();
|
||||
let body = solver.body().unwrap();
|
||||
let vertices = self.shared.read().unwrap().0.clone();
|
||||
let mut drag = 0.0;
|
||||
let mut lift = 0.0;
|
||||
// Collect, then clamp, then integrate: the same 20x-median spike
|
||||
// clamp the coupling loads carry. Without it the REPORTED
|
||||
// drag/lift at large deformation are dominated by the rare wild
|
||||
// reconstructions (the s = 1 benchmark run printed +-4,000-scale
|
||||
// load swings against a +-78 reference while its displacements
|
||||
// matched the benchmark to 0.1%).
|
||||
let mut samples: Vec<(f64, f64, f64)> = Vec::new();
|
||||
let poly_probe = EmbeddedBody::polygon(vertices.clone());
|
||||
for s in poly_probe.surface_samples(0.5 * self.h) {
|
||||
if circle_sdf(s.x, s.y) < 1e-9 {
|
||||
@@ -459,8 +464,7 @@ impl Fsi2Harness {
|
||||
if let Some((tx, ty)) = mask.traction_at(
|
||||
body, &field.u, &field.v, &field.p, self.mu, 0.0, s.x, s.y, s.nx, s.ny,
|
||||
) {
|
||||
drag += tx * s.ds;
|
||||
lift += ty * s.ds;
|
||||
samples.push((tx, ty, s.ds));
|
||||
}
|
||||
}
|
||||
let circle_probe = EmbeddedBody::circle(0.2, 0.2, 0.05);
|
||||
@@ -471,10 +475,28 @@ impl Fsi2Harness {
|
||||
if let Some((tx, ty)) = mask.traction_at(
|
||||
body, &field.u, &field.v, &field.p, self.mu, 0.0, s.x, s.y, s.nx, s.ny,
|
||||
) {
|
||||
drag += tx * s.ds;
|
||||
lift += ty * s.ds;
|
||||
samples.push((tx, ty, s.ds));
|
||||
}
|
||||
}
|
||||
let mut magnitudes: Vec<f64> = samples
|
||||
.iter()
|
||||
.map(|(tx, ty, _)| (tx * tx + ty * ty).sqrt())
|
||||
.collect();
|
||||
magnitudes.sort_by(|a, b| a.partial_cmp(b).unwrap());
|
||||
let median = magnitudes.get(magnitudes.len() / 2).copied().unwrap_or(0.0);
|
||||
let cap = 20.0 * median;
|
||||
let mut drag = 0.0;
|
||||
let mut lift = 0.0;
|
||||
for (tx, ty, ds) in samples {
|
||||
let norm = (tx * tx + ty * ty).sqrt();
|
||||
let scale = if median > 0.0 && norm > cap {
|
||||
cap / norm
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
drag += tx * scale * ds;
|
||||
lift += ty * scale * ds;
|
||||
}
|
||||
(drag, lift)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user