|
FhSim
3.1.0
Marine systems simulation
|
| ID | 0027 |
| Class | ARCHITECTURE |
| Severity | 1 |
| Status | blocked |
Models: Net/NetStructure
Found: 2026-09-22, on landing MARE-0026 (2ae2738)
Decision needed: none. Closes with the removal of NetStructureWakeEffect and NetElement3NWakeEffect in 5.0 (owner ruling R38).
MARE-0026 extracted the net panel force path into src/net/NetElement3NForces.h templated on the scalar type, and MARE-0004 closed with an exact panel Jacobian built on it. Three things were deliberately left out of that change because each carries its own verification burden. None is a regression; each is listed separately because they are unrelated.
tests/NetStructure_Jacobian_Test.cpp sets jacCfg.perturbationEps = 1e-5 in SimObject.NetStructure_PanelJacobian, against the checker's default of 1e-8.
The block under test is exact, so the only approximate side of the comparison is the checker's own central difference. PanelNet_Jacobian_in.xml has enough curvature that the reference is still dominated by rounding noise at 1e-8: sweeping the step gives absolute errors of 82271, 109.7, 1.097, 0.0486 and 0.597 at 1e-4 through 1e-8, so the accurate window is around 1e-5 to 1e-6 and the default sits past the bottom of the V. The test therefore verifies the block at a chosen step rather than at the checker's default, which is a weaker statement than the other Jacobian tests in this directory make.
1e-8 falls below absTol. Then drop the perturbationEps line. This is the option MARE-0004 recorded as its (c). Done in 6c320c0; see Progress below.SimObject.NetStructure_PanelJacobian passing with no perturbationEps override, at relTol = 1e-3 or tighter.
None to shipped code; this is a test fixture only.
NetElement3NWithConstraints, NetElement3NWakeEffect and ScreenElement3N each contain their own copy of the twine tension, the Reynolds-dependent normal drag, the coordinate rotations and the damping, including their own m_meshOpeningAngle member — the same member whose removal from NetElement3N was a precondition for differentiating that class.
Four copies of one force law. A correction to the Ersdal-Faltinsen branch or to the drag saturation has to be made four times or the copies drift, which is how the NumElements/numElements drift in MARE-0006 happened. None of the three has a Jacobian of its own, so a net using them falls back to a numerical difference of the whole right-hand side.
Point each of the three at net_element_forces::AddNodeForces, extending PanelParams with the fields the variants add. net_element_forces::AddNodeForces was made a free function rather than a member for exactly this reason.
The same method that verified MARE-0026: a reference translation unit transformed by script from each class's pre-change source, compared against the shared core over randomised states and required to agree bit-for-bit, before anything else changes.
These are load-bearing force paths with no force test of their own in this repository, which is why the bit-for-bit comparison rather than a tolerance is the required evidence.
src/net/NetStructure.cpp includes sfh/ad/Dual.h, which is new in fhlib 4.3.0. conanfile.py does not require fhlib at all: it arrives transitively through fhsim, which requires fhlib/[^4.2.0]@sintef/stable.
The build resolves 4.3.0 only because that package happens to be present. A checkout that sees only 4.2.x fails at compile time with a missing header instead of at dependency resolution with a version message. The same applies to the several other sfh/... includes in this library, which have never been declared either; only the version floor is new.
fhsim's floor to fhlib/[^4.3.0]@sintef/stable. Done on the fhsim branch feature/require-fhlib-4.3.0 (commit aa0a831d), which is pushed but not merged. It must not merge before fhlib 4.3.0 is released, because until then the range resolves for nobody but a machine that built 4.3.0 locally. This part of the issue closes when that branch merges.fhlib directly here. This makes the existing sfh/... includes honest as well, but departs from the convention the rest of the tree follows.A build against fhlib 4.2.x that fails during conan install with a version conflict rather than during compilation.
Option (b) adds a direct dependency edge; the resolved version does not change, since [^4.3.0] and fhsim's [^4.2.0] both select 4.3.0.
Re-confirmed at 8a1772d: (a) tests/NetStructure_Jacobian_Test.cpp still pins perturbationEps = 1e-5; (b) the three sibling panel classes still carry their own force arithmetic; (c) conanfile.py still does not require fhlib.
Not done, and why: (a) needs a new, lower-curvature panel fixture whose error at the checker default is below tolerance; that is fixture design with a numeric sweep to prove it, not a mechanical change. (b) moves three load-bearing force paths onto the shared core and must be proven bit-for-bit, per the issue; it touches production physics code and is out of scope for a safe-fix pass. (c) is waiting for the fhsim branch feature/require-fhlib-4.3.0 to merge after fhlib 4.3.0 is released; nothing to do in this repository. Status stays ready.
(a) is done in 6c320c0 and 22716e3. PanelNet_Jacobian_in.xml now uses LowStrainPanelNet.xml: the same two panels with 20 meshes per edge instead of one, nodes about 1 m apart and twines stretched by about 1 % instead of 10 %. Worst absolute error of the net block, over every sample of the test's configuration (seed 42):
| eps | 1e-4 | 1e-5 | 1e-6 | 1e-7 | 1e-8 | 1e-9 |
|---|---|---|---|---|---|---|
| old fixture | 82271 | 127.9 | 1.279 | 0.0486 | 0.597 | 5.67 |
| new fixture | 0.0235 | 2.3e-4 | 5.1e-5 | 5.2e-4 | 0.0031 | 0.0403 |
At the checker's default 1e-8 the new fixture passes relTol = 1e-3, absTol = 0.01 with no mismatch, which is this part's "Test that would prove it", and 6c320c0 ran the test there. The margin on absTol is only about 3, though: over 40 seeds the worst error on a small entry is 0.0032, and the largest maxAbsErr, 0.0040, is on a large entry that passes by relTol. 22716e3 therefore sets the step to 1e-6, the bottom of the V, where the worst error over the same 40 seeds is 5.1e-5, and tightens absTol tenfold to 1e-3, a margin of about 20. Unlike the old 1e-5 pin, this is a choice of accuracy, not a necessity. Scaling one panel entry of the analytical block by 1.01 fails the test (relErr 0.011 on entries of order 1e5).
(b) and (c) are unchanged and still open. For (b): Net/NetStructureArray's flat-array panel force in src/net/FNetElement.cpp (AddNetPanelNodeForces, with a single-precision twin in FNetElementFloat.cpp) is a further copy of the same force law, found while writing the MARE-0030 fixture.
(b), the NetElement3NWithConstraints copy: done in ab7f71f (WP-A8 of the net-hydrodynamics programme; record in MARE-0095). Its private twine drag and the tension, mesh-contact and damping computations whose results it discarded are deleted; its load is now ComputePanelFrame and EvaluatePanelLoad of the shared core with the panel load law, fluid and solidity read as NetStructure reads them (src/net/NetPanelSetup.h).
The bit-for-bit reference translation unit this item named as its proof ("Test that would prove
it") is no longer needed for this copy: the net-hydrodynamics plan changes the physics on purpose (the twine drag is now one of four panel load laws, the default a screen law, with the caller's solidity), so there is no old behaviour to reproduce bit for bit. The evidence instead is that a free panel in NetStructureWithConstraints moves as in NetStructure to 1e-9, for the default law and for TwineCrossFlow (NetStructureWithConstraints_FreePanelMatchesNetStructure*), with the old-against-new load table in MARE-0095.
Still open under (b): NetElement3NWakeEffect (kept building until the owner decides on NetStructureWakeEffect, lead ruling R6), ScreenElement3N (to be deleted, WP-A10) and FNetElement/FNetElementFloat (WP-A9, WP-A10). (c) is unchanged. The issue stays open.
(b): the ScreenElement3N copy and the single-precision FNetElementFloat copy are resolved by deletion in 8a40f10 (WP-A10; record in MARE-0097). FNetElement itself is on the shared core since MARE-0096. Still open under (b): NetElement3NWakeEffect, kept building until the owner decides on NetStructureWakeEffect (OWNER_QUESTIONS Q3, lead ruling R6). (c) is unchanged. The issue stays open.
(b): the owner has decided Q3. NetStructureWakeEffect and NetElement3NWakeEffect are kept in 4.x, deprecated (MARE-0117), and their setup warning and documentation name removal in fhsim_marine_elements 5.0. They are frozen, not ported onto the shared panel core, so the NetElement3NWakeEffect copy of the force arithmetic stays until they are deleted in 5.0; (b) stays open until that deletion. (c) is unchanged. The issue stays open.
(a) is done (see above). (c) is done upstream: fhsim main (3.3.1, which this library requires) now requires fhlib/[^4.3.0]@sintef/stable (aa0a831d, merged), so a checkout that sees only fhlib 4.2.x fails at dependency resolution. Only (b) remains, the NetElement3NWakeEffect copy of the force arithmetic, which stays until NetStructureWakeEffect is deleted in 5.0 (owner ruling R38); NetStructureArray/FNetElement were removed in 4.0 (MARE-0080). Nothing to do before 5.0.