c1bcdc408e751ebca34d324922bb330afcd3773b
6
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c0666bf22a |
rtx-fsi: C3 — FSI3 opened: the added-mass regime, its impulse artefact, and the coupler hygiene it demanded
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
The march is extracted from the FSI2 test into a shared tests/fsi2_harness/march.rs (MarchConfig from env / MarchResult / window statistics), the harness parameterised by BenchmarkCase (FSI2, FSI3: inflow, solid density, modulus, rigid-flag drag reference), and turek_hron_fsi3.rs written on top (Re 200, density ratio 1, E 5.6e6). The committed FSI2 default is bit-identical through all of it — every new knob defaults to FSI2's behaviour; re-verified twice to every printed digit (uy 3.7732 / 3.7920 mm). FSI3's first contact, traced pass by pass (RTX_FSI3_TRACE), exposed the added-mass instability in its purest form and, one measured mechanism at a time, what a partitioned coupling at unit density ratio needs: - C^1 interface motion (MarchConfig::c1_interface): a constant per-step interface velocity is a velocity JUMP at each step start, and the incompressible fluid answers with an impulsive added-mass load ~ rho L dv / dt_fluid (8x the physical reaction under subcycling): 1,600 N at release, 48,000 N and a 59 mm response one step later, the flag's Newton dead the pass after. Constant acceleration from the previous end velocity to 2 dd/dt - v_n removes the impulse (loads 1,700-2,400 N). - IQN first-pass relaxation as a knob (initial_relaxation, FSI3 0.05): |1 - omega (1 + g)| must contract; 0.5 diverges past gain 3. - The divergence verdict waits for the secant (IqnIls): the exploratory second pass on a high-gain map legitimately overshoots 10x before the first secant column exists. Pinned by a gain-40 model test. - Kinematic predictor (predictor: "kinematic", velocity only): the structure-alone predictor ignores an added mass comparable to the flag's and overshoots 2-5x, drawing 5-6x loads every first pass; and NOT with the acceleration — Newmark average acceleration carries an inconsistent initial acceleration as a sign-alternating mode (d + dt v + dt^2 a / 2 predicted 22 mm at release; converged 0.14). - Quiescent release (quiescent_release): the structure-alone "consistent" initial acceleration M^-1 F ignores the added mass. - Coupler hygiene (IqnIls): a stalled or diverged step's secant columns are no longer retained (a bistable mask flip's columns extrapolated a 30 mm interface jump on the next step); two-window stagnation detection reports a plateau early instead of bouncing to the budget (a single-window test misjudged a slowly converging step and is recorded as such); trust region tightened to 10x the residual. A noise-column filter at the tolerance was measured to HURT (stalled a converging step at 5.5e-4) and is disabled (threshold 0). - The floor measured, not borrowed (fsi2_interface_noise.rs gains RTX_NOISE_CASE=fsi3): flip jumps 3.6e-4 (12x FSI2's), the subcycle-8 release map stalling near 1e-6, the subcycle-2 map converging to 9e-10; and through the release transient (flag at ~0.3 m/s) the subcycle-8 floor rides up to ~1e-3 with the motion — which moved the FSI3 default to subcycle 2 at a 3e-5 floor. FSI3 committed default (ny 62, release t = 4, t_end 4.2, subcycle 2): 581 steps, 3.8 subit/step (max 8), 0 stalls, 0 retries, conservation 4.3e-13; uy 10.1 +- 27.5 mm and ux -3.1 +- 3.2 mm over the first 0.2 s (reference cycle 1.45 +- 34.90, -2.86 +- 2.70). Machinery invariants pinned; physics bands await the study record. Rigid-flag drag 426.9 vs CFD3's 439.45 (-2.9%). The FSI2 mode-2 study pin (IQN / subcycle 2, t_end >= 16) was measured with the pre-hygiene coupler; re-verify on the next s = 2 study run. 48 lib tests green, clippy clean. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Lnyrw33Lu6rUhW42E9KHwq |
||
|
|
be04e0e233 |
rtx-fsi: pin the mode-2 flapping cycle under the IQN / subcycle-2 configuration
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
Study horizons (t_end >= 16) under RTX_FSI2_COUPLER=iqn RTX_FSI2_SUBCYCLE=2 now assert the measured mode-2 cycle: frequency in [2.05, 2.45] Hz and uy amplitude in [45, 70] mm — bands that admit the settled cycle at either grid (ny=62: 57.6 mm / 2.227 Hz at t=16, 55.9 / 2.224 at t=30; ny=82: 57.1 / 2.236 at t=20) and reject both the wake attractor (3.73 Hz, ±17 mm) and the reference itself (1.93 Hz, ±82 mm) as material changes. The default configuration's pins are unchanged. Module docs brought up to the eleventh-session record. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Lnyrw33Lu6rUhW42E9KHwq |
||
|
|
a342e703a4 |
rtx-fsi: trust-region cap on the IQN step + increment-scaled stall acceptance
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
The s = 1 FSI2 march (deepest rung: 1.955 Hz, ±73 mm mid-growth) found two coupler failure modes at peak motion: - run 1 (budget 12): NotConverged at residual 6.1e-4 = 9% of the step's own increment, after the history-reset retry — killed at t = 11.1 s. - run 2 (budget 30): the deeper budget let an ill-conditioned secant model extrapolate the locally violent map into a candidate interface that swept to the domain wall and crashed the mask build BEFORE any residual guard could fire (t ~ 9.9 s). Fixes, both scale-relative per the absolute-threshold rule: - STEP_CAP = 50: the full quasi-Newton step r + W alpha is capped at 50x the current residual norm, direction kept. Legitimate large Newton steps (near-marginal gains) pass; thousand-fold geometric extrapolations cannot. Pinned by a noisy-map test asserting every iterate's step stays within the cap. - The march accepts a stalled step at residual < max(5 x tolerance, 0.1 x the step's own increment) — the rare violent step near peak motion carries an order-below-increment error, counted like every stall and bounded by the existing stall-fraction assert; the retry trigger mirrors the same bound. 46 lib tests green, clippy clean. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Lnyrw33Lu6rUhW42E9KHwq |
||
|
|
d5f19ea497 |
rtx-fsi: IqnIls::reset_history — stale secant columns overshoot in rapid transients
Documentation / Build API Documentation (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 User Guide (push) Canceled after 0s
The s = 2 ladder march (resonant growth finally open: 2.3 Hz, amplitude through ±46 mm — 2.7x the wake attractor the loose coupling locked) died at t = 11.12 s with CouplingDiverged at iteration 2: the predictor left a 1e-4 first residual, and the first quasi-Newton update drove it to 1.1e-3. Cross-step secant history assumes the interface Jacobian drifts slowly; columns recorded at much smaller amplitude steered the least-squares direction wrong at 2.7x that amplitude, and the divergence guard read the overshoot as added mass. The map itself converges deeply from a clean start (the noise probe's stall measurement), so the recovery is: reset the history, retry the step once from the predictor. - IqnIls::reset_history(), with a cold-start-equivalence test. - turek_hron_fsi2: on an unaccepted coupling verdict under the IQN coupler, reset + one retry from the predictor (Aitken carries no history — a retry would repeat the identical iteration, so the path is IQN-only); retried steps counted and reported like stalls. Verified end-to-end: the re-run crossed the killing step and marched on (t = 11.18: uy +56 mm, window amp ±50 mm, 1.4 subit/step). 45 lib tests green, clippy clean. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Lnyrw33Lu6rUhW42E9KHwq |
||
|
|
140310b223 |
rtx-fsi: the noise floor interrogated — smoothing refuted, IQN-ILS lands, tight coupling reopened
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
The tenth session ended on "lower the interface noise floor". This builds the levers and measures them, and the measurements overturn the diagnosis: - smooth_tractions: arclength moving average over the wetted surface, area-weighted, smooth normal-similarity factor so corners do not mix and the smoothed load stays continuous in the geometry. Nine unit tests. MEASURED NEGATIVE RESULT: the flip-scan floor is unchanged to 0.2% at radii 1-3h — the flip's load jump is coherent through the fluid field (mask rebuild shifts the pressure around the flipped cell), and a surface average preserves coherent shifts. Default off; the probe pins the attribution so nobody re-reaches for this lever. - IqnIls: interface quasi-Newton with inverse least squares (Degroote 2009) — filtered MGS least squares over secant columns (filter RELATIVE to column norm), cross-step history reuse, per-step set_tolerance. Model-map tests: exact on anisotropic linear maps within dim+2 passes (scalar Aitken provably cannot be), scale invariant, history reuse shortens the next step, stalls at the noise scale instead of diverging (fixture lesson: per-pass noise, not state-dependent noise — the latter has a genuine fixed point). - tests/fsi2_harness/: the FSI2 machinery extracted shared; verified pure code motion (committed release response reproduced to every printed digit). March gains RTX_FSI2_SMOOTH / RTX_FSI2_COUPLER=iqn / RTX_FSI2_REUSE knobs; pinned bands guard the default configuration. - tests/fsi2_interface_noise.rs: the probe. Flip-scan floor at subcycle 8: 3.05e-5 (pinned); smoothing attribution pinned; the cross-subcycle scan recorded but unpinned (the fixed geometry increment's wall-velocity trend, increment/dt_c, swamps the flip signal at small dt_c — a dt_c^2 scaling hypothesis died in that operationalization). THE OPERATIONAL FLOOR — the real release step subiterated at tolerance 1e-9 with residuals traced — converges DEEP at both subcycles: s8 aitken 3.4e-9 / iqn 1.6e-9, s2 both ~6.4e-10 in 5-6 passes. The flip jumps are events at specific geometries, not a floor under every step: the tenth session's subcycle-2 blowup was tolerance mis-budgeting (2e-4 held fixed while dt_c shrank), not an impassable floor. Probe bug found and fixed on the way: stale shared geometry leaked a 4.5e-5 phantom first residual into the first stall run; every measurement now resets the geometry on entry. All 924+17 tests green: lib 44 (was 27), piston 2, curved edge 1, FSI1, the committed FSI2 march (release response identical), the probe. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Lnyrw33Lu6rUhW42E9KHwq |
||
|
|
4e90177aa9 |
rtx-fsi: C2 — FSI2's coupled march, and the wrong attractor measured
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
The unsteady coupling on the piston pattern with the real solvers: per TIME STEP, Aitken subiterations of (8x-subcycled embedded TVD/multigrid fluid <-> flag nonlinear-Newmark step), the fluid re-runnable through snapshot/restore + a field clone, the flag re-runnable because the stepper commits nothing, the moving polygon carrying the flag's actual interface velocity. Conservation 8.3e-12 over 9,263 coupled steps; the rigid phase reproduces this solver's own CFD2 values at both grids before anything couples. What the 30 s studies measured (ny = 62 AND 82, three protocols): the coupled system self-excites into a wake-forced cycle at 3.729/3.728 Hz with uy(A) +-17.3 mm at both grids - grid-converged, protocol- independent, kinematically genuine (ux locks 2x uy) - and NOT the benchmark's mode-2 resonant cycle (1.93 Hz / 81.6 mm; the flag's vacuum mode 2 is 1.9245 Hz). Diagnosis measured stepwise: the staggered phase lag starves the resonant channel (a subcycle=2 probe redirected growth to 1.9 Hz as predicted), and tighter dt_c is blocked because wall- velocity noise = displacement-tolerance / dt_c while the needed tolerance sits below the discrete interface noise floor (~1.3e-4 at full inflow, mask flips through beta dt^2/m). The route to the benchmark cycle is lowering that floor, not iterating against it. Robustness, both measured: rare wild tractions (19 samples in 2.4M) clamped at 20x the sample median - clamped, not dropped: a hard drop makes the pass discontinuous and the subiteration bounces at step scale; and Aitken "divergence" verdicts within 5x tolerance accepted as noise bounces over well-predicted steps (counted, bounded). The committed default (t_end = 7, ~9.5 min) pins the deterministic release response (uy 3.773 +- 3.792 mm, band +-35%); study horizons >= 25 s pin the measured 3.73 Hz attractor so any material change is loud. Full study record in the module docs and omni-cortex solver_status.md. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Lnyrw33Lu6rUhW42E9KHwq |