|
FhSim
3.1.0
Marine systems simulation
|
Status of every baseline below: reviewed and approved by the owner, 2026-09-25, except NetStructure_Regression and SimObject.Disk, which were regenerated on 2026-09-27 on branch review/A12-baselines after the net-hydrodynamics programme and approved by the owner on 2026-09-28 (MARE-0099, resolved; old against new in Regression baselines: review of the 2026-09-27 regeneration (MARE-0099, WP-A12)). Each one freezes what the code at the time produced, and the owner has confirmed the plots are correct. Cable_Regression and NetStructure_Regression were regenerated once more for 3.0.1 (2026-10-11, owner decision), with new inputs only, so that one baseline holds for every compiler; see Conditioning. NetStructure_Regression was regenerated again on 2026-10-13 for the owner's MARE-0110 ruling (the default law's lift from the MF2022 Eq. 10 lift-to-drag ratio, fhsim_environment 3.1.1); that change alone moves it (see its page). MARE-0032 is resolved; MARE-0033 stays open, narrowed to Cable/Branched, which has no baseline yet.
Each baseline is a gtest, SimObject.<ID>, that runs tests/in/<dir>/<ID>_in.xml with RunAndCompareRegressionXmlTiming (tests/TestUtils.h) and compares its output with <ID>_ref.csv under the limits in <ID>.ref, as SimObject.Disk does. Each page shows every compared output against time, says what should happen physically and checks the numbers against a hand calculation.
| Object | Issue | Test and page | Fixture | Compared outputs | Hand check |
|---|---|---|---|---|---|
Net/Sphere | MARE-0033 | Sphere_Regression | 1000 kg, 1 m sphere sinking from rest in a 0.5 m/s current, 5 s | Position, Velocity | RK4 of the drag law on the relative velocity, with the added mass 0.5 ρV in the inertia: within 5e-6 m |
Cable/LumpedMass | MARE-0033 | Cable_Regression | 10 m cable, ends 8 m apart, 0.5 m/s cross current, 10 s | Node states, ForceA, ForceB | Sideways drag 76.4 N against 76.9 N; vertical end forces 375.2 N, 0.99 of the 380.4 N wet weight (380.4 N in still water) |
RbCable/CableConnector | MARE-0033 | CableConnector_Regression | 50 kg connector under a decaying and a constant end force, 5 s | Pos, Vel, PosA, PosB | Closed form: within 5e-7 |
TrawlBeam | MARE-0033 | TrawlBeam_Regression | PID from rest to 1.5 m/s against a 2 × 2e4 N pull on a 0.3 rad track, 30 s | States, ShipForce, tow-point positions | Steady ShipForce 38212.7 N against 4e4 cos 0.3 = 38213.5 N |
TrawlCable | MARE-0003 | TrawlCable_HeunRegression (no page) | The TrawlCable smoke fixture under Heun_i at a fixed 1 ms step, one solver thread, 1 s | WinchForce, TopBridleEndForce, BottomBridleEndForce, TrawlDoorPosition | None: it guards the constraint solver's symplectic step under Heun_i (the full step, owner ruling 2026-10-13); made 2026-10-13, regenerated 2026-10-14 for owner rulings C3 Q10/Q1 (SolveCatenary initial layout; last printed digit only), not yet reviewed by the owner |
TrawlCable | plan C3 | TrawlCable_EulerRegression (no page) | TrawlCable_HeunRegression's fixture under Euler_i, 1 s | WinchForce, TopBridleEndForce, BottomBridleEndForce, TrawlDoorPosition | None: it pins the trawl rig wiring and the cable segment setup before task C3 of fhsim_workspace's plan architecture-deepening-2026-10; made 2026-10-14, regenerated the same day for owner rulings C3 Q10/Q1 (SolveCatenary initial layout), not yet reviewed by the owner |
RundDorg | plan C3 | RundDorg_Regression (no page) | The RundDorg smoke fixture (Euler_i, fixed 2 ms step, one solver thread) for the clump's first 2 s | MainForceVector, Line1ForceVector, Line2ForceVector, WeightPosition | None: as TrawlCable_EulerRegression; made 2026-10-14, regenerated the same day for owner rulings C3 Q10/Q1 (SolveCatenary initial layout), not yet reviewed by the owner |
TrawlCable + MooringCable | plan C3 | TrawlCable_JoinedRegression (no page) | A joined rig on one solver: CableS owns it, CableP (its mirror image) and a MooringCable join it; Euler_i, 1 ms, one solver thread, 1 s | Both cables' end forces and door positions, the mooring's ForceA and ForceB | None: it pins the owner/joined rule; made 2026-10-14, regenerated the same day for owner rulings C3 Q10/Q1 (SolveCatenary initial layout), not yet reviewed by the owner |
Net/NetStructure | MARE-0032 (b) | NetStructure_Regression | 1 m² panel, unstretched, in a 0.5 m/s current, pulled 2 N upstream, 15 s | Node positions and velocities | LocalThroughFlow drag at the steady drift 2.048 N against the 2.034 N it balances; without the pull the panel drifts at the current speed |
Net/NetStructureWithConstraints | plan C1 | NetStructureWithConstraints_Regression, NetStructureWithConstraints_RegressionThreads (no page) | Two quadrilaterals in a 0.5 m/s current and one Airy wave, the first's four nodes driven by the two rigid-element chains, the second's outer nodes free; 2 s serial, and 0.2 s on two threads with MassFactor 2 and MaxVelocity 5 | Every state | None: it pins the node-state reads (rigid elements against own states) before task C1 of fhsim_workspace's plan architecture-deepening-2026-10; made 2026-10-14, reviewed and accepted by the owner 2026-10-14 |
Cable/Branched has no baseline yet: it waits for MARE-0036 and MARE-0037, whose answers change its numbers.
Each fix regenerated the baselines it changed.
Cable/LumpedMass and Cable/Branched (MARE-0082): the end forces carried twice the cable's weight in water, as CableElBasics::CalcMassAndWeight gave each end node of an element the element's whole weight in water. Each node now carries half, as its mass already did.Net/Sphere (MARE-0084) read the current but took its drag on its own velocity. It now uses the velocity relative to the water, as Net/Disk does, and its fixture has a current.Net/NetStructure (MARE-0083): the panel drag scaled the water velocity, not the velocity relative to the net, by the Kristiansen-Faltinsen solidity factor (1.159 here), so a free panel drifted at 1.159 times the current. It now scales the relative velocity, and a free panel drifts at the current speed. Net/NetStructureWakeEffect and Net/NetStructureWithConstraints had the same defect and have the same fix.Sphere_Regression was regenerated once more when Net/Sphere got the added mass of a sphere, 0.5 ρV, in its inertia (MARE-0086, a known limitation, not a hand-check finding). The owner had approved the previous baseline; the change is that fix alone.
The harness (FhSim TestResult::CompareRegression) supports one limit, output_rms_max: the root mean square over time of the difference between run and baseline, absolute, applied to every column of the output file alike. There is no relative limit and no per-column limit, and it compares whole files: the columns are chosen by the fixture's <FileOutput Select=...>, and every column of the file is compared.
Every baseline uses output_rms_max 1e-8, the owner's "slightly looser than Disk's 1e-10". The compared columns are SI values whose peaks are between 0.37 and 7.7e5 (the smallest are the net's y positions and the Cable node velocities), so 1e-8 absolute is at most about 3e-8 of any column's peak. FhSim writes the result file with e, seven significant digits, so a change of one unit in the last printed digit of one row already exceeds 1e-8 in every column above about 0.1: in practice each test passes only while the output is unchanged to printed precision, as Disk's does. A relative 1e-8 would be below that print resolution and could not be checked.
A baseline can hold on every compiler only if a change of the inputs in their last bit moves the outputs by far less than 1e-8: other compilers and math libraries round differently, by about that much. In 3.0.0 Cable_Regression and NetStructure_Regression did not: on Linux a one-ulp change of one input position moved the cable's ForceA by 1.6e-3 N and the net's Vel_2_1 by 2e-3 m/s, and MSVC differed from the gcc baselines by up to 1.7e-3, so MSVC skipped the comparison. Two input choices caused it, not the models:
<StepControl Step="0.001"/>).Check (2026-10-11, gcc, Release): each input of each fixture (end and node positions, Density, E, Diameter, DampingRatio, Length, node forces, current) moved by 1 and by 4 ulp moves no column by more than an RMS of 1e-11; the only differences are single flips of the seventh printed digit of values below 1e-4. A relative change of 1e-8 moves them by an RMS of at most 1e-4 (cable ForceA) and 7e-7 (net), so the conditioning is that of the physics (the cable's end force goes with its axial stiffness), not of the integration. The hand checks did not move.
Sphere, CableConnector and TrawlBeam also run the default Jacobian check. Cable/LumpedMass and Net/NetStructure do not, see the comments in their tests.Delete <ID>.ref and <ID>_ref.csv and run the test: the harness writes both again (ReferenceMode::CreateIfMissing), with output_rms_max 1e-10; set it back to 1e-8. Then rerun python3 tests/plot_baselines.py from the repository root, which rewrites the pages here and prints the hand checks.