rtx-cfd (18,715 lines) and rtx-fea (36,576 lines) both exist and nothing
connects them -- rtx-fea is commented out of rtx-cfd's dependencies. This
is the coupling layer, and it is the piece Prof. Charbel Farhat's 2026
Guggenheim Medal citation is actually about.
It depends on NEITHER solver. The properties that make a partitioned
coupling correct -- conservation of force, moment and interface work --
are statements about the transfer operators alone, so they can be
validated now, on solvers whose canonical-benchmark validation is still
outstanding. Adapters to the concrete solvers belong above this.
TRANSFER (transfer.rs). Weights satisfy two constraints:
sum(w_i) = 1 partition of unity -> force conserved
sum(w_i x_i) = x_face linear reproduction -> MOMENT conserved
The second is the one that gets skipped. Inverse-distance weighting
satisfies the first and generally violates the second, conserving force
while corrupting moment -- which shows up as slow spurious rotation rather
than as an obvious error. Underdetermined for >4 nodes, so it takes the
minimum-norm solution w = A^T (A A^T)^+ b.
That is a PSEUDO-inverse, and not for defensiveness. A wetted surface is a
surface, so its nodes are usually planar, and for a planar patch the z
constraint row is an affine multiple of the ones row -- A A^T is genuinely
rank-deficient. The constraint is redundant there, not unsatisfiable. An
ordinary inverse rejects the most ordinary interface there is; I found
this because my first test fixture was collinear and the code correctly
refused it. Constraints are then verified against the weights actually
obtained, since a pseudo-inverse returns a least-squares answer whether or
not the system was consistent.
Motion transfer uses the TRANSPOSE of the load operator, which makes
interface work conserved identically: (Hf).v = f.(H^T v). Any other
pairing leaks energy every step, and the leak looks like physics until it
destabilises.
COUPLING (coupling.rs). Staggered and Aitken-relaxed subiteration. The
decisive tests reproduce the added-mass effect: at a gain of 2.5 the
fixed-relaxation scheme DIVERGES and is reported as CouplingDiverged
rather than as an exhausted budget, and Aitken recovers the same case. A
partitioned coupling that cannot reproduce its own classic failure mode is
not being tested hard enough. Aitken is exact for a linear fixed point, so
convergence is asserted at <=4 iterations -- pinning that this is the real
delta-squared formula and not an under-relaxation that happens to work.
SCOPE, stated up front in the crate docs: small-displacement transpiration
coupling on a fixed mesh. Deliberately not ALE and not embedded-boundary,
so the Discrete Geometric Conservation Law does not yet apply -- the mesh
does not move. Large motion needs an embedded boundary treatment; that is
the next phase, not an oversight.
External comparator named at entry: Turek-Hron FSI2/FSI3, not yet reached.
26 tests written red-first; cargo test/fmt/clippy -D warnings clean.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Whole-workspace rustfmt pass picked up while iterating on Mamba GPU
backward work. Verified formatting-only via diff sampling; no logic
changed.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Declared but never referenced; forced openblas-build (no good Apple-Silicon
backend) and broke the macOS build.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
The workspace root was upgraded to thiserror = "2" in an earlier commit,
but 56 per-crate Cargo.toml files still independently declared "1.0".
These crates do not use workspace.dependencies inheritance for thiserror.
All updated to thiserror = "2" for complete fleet alignment.
Includes: rtx-backend, rtx-tensor, rtx-losses, rtx-backend-cuda/rocm/metal,
all training crates (rtx-auto, rtx-rl, rtx-distributed, rtx-federated, etc.),
specialized crates (rtx-science, rtx-platform, rtx-nmf, rtx-neuro-*),
production crates (rtx-streaming, rtx-serving-api), and all demo crates.
cargo check --workspace: PASSES.