FhSim  3.1.0
Marine systems simulation
Loading...
Searching...
No Matches
0003 — `TrawlCable`'s `Heun_i` branch is commented out while `RundDorg`'s is live
ID 0003
Class BUG
Severity 2
Status blocked
Models TrawlCable
Found 2026-09-15 audit (e3f3107)
Decision needed State the intended step size per object; the code change is then a few lines plus a regression baseline.

Evidence

src/trawl_mooring_interaction/TrawlCable.cpp:750-754

if (integratorMethod.compare("Euler_i") == 0) {
m_ConstraintSolver->SetSymplecticStepSize(setup->step);
} /*else if(integratorMethod.compare("Heun_i") == 0){
m_ConstraintSolver->SetSymplecticStepSize(setup->step/2.0);
}*/

src/trawl_mooring_interaction/RundDorg.cpp:530-534

if (integratorMethod.compare("Euler_i") == 0) {
m_ConstraintSolver->SetSymplecticStepSize(setup->step);
} else if (integratorMethod.compare("Heun_i") == 0) {
m_ConstraintSolver->SetSymplecticStepSize(setup->step); // /2.0);

src/net/Test/NetStructureTest.cpp:126-131

if ((integratorMethod.compare("Euler_i")) == 0) {
m_symplecticStepsize = setup->step;
} else if ((integratorMethod.compare("Heun_i") == 0)) {
m_symplecticStepsize = 0.5 * setup->step;

Effect

Three classes that share the same symplectic-step-size mechanism disagree about Heun_i in three different ways: TrawlCable never sets it (the solver keeps whatever default it has), RundDorg sets the full step, and NetStructureTest sets half the step. A trawl model run under Heun_i therefore uses a different constraint-solver step for its warp (TrawlCable) than for its mooring interaction (RundDorg), which is exactly the kind of asymmetry that looks like a physical result and is not one.

The /2.0 appears commented out in both trawl classes and live in NetStructureTest, which suggests the halving was deliberately removed at some point — but only from two of the three places.

Possible fix

  • (a) Uncomment the TrawlCable branch to set setup->step, matching RundDorg.
  • (b) Uncomment it to set setup->step / 2.0, matching NetStructureTest.
  • (c) Extract the branch into one shared helper used by all three, so the question can only be answered once.

Owner question, open

for a symplectic Heun step, is the constraint-solver step the full integrator step or half of it? This is a numerics question about the solver, not a style question, and it decides between (a) and (b). Until it is answered, none of the three sites should be touched — changing any of them changes results under Euler_i/Heun_i.

Test that would prove it

A regression over a Heun_i trawl input, run twice with TrawlCable and with RundDorg as the cable, asserting the two agree on a shared quantity. Simpler and enough for the inconsistency itself: a unit test on the extracted helper of option (c) asserting one step rule for Euler_i and Heun_i, which fails to compile against three divergent copies.

Risk

High for results. CHANGELOG.md already records that fixing the 2.x-to-3.x method-name comparison changed numerical behaviour under Euler_i and Heun_i; this would change it again, for Heun_i only. Any stored reference produced under Heun_i must be regenerated and inspected, not just re-blessed.


Why not solved (fix pass 2026-09-15)

Re-confirmed at HEAD: TrawlCable.cpp:750-754 has the Heun_i branch commented out, RundDorg.cpp:530-534 sets a full step for the same integrator and NetStructureTest.cpp:126-131 sets a half step. Any change here alters simulation results under Heun_i for whichever object is changed. Which constraint-solver step is correct for the symplectic Heun scheme (full or half, and whether TrawlCable should have the branch at all) is a numerics question that only the model owner can answer, and there is no reference result in the repository to test against. Smallest owner decision: state the intended step size per object, after which the code change is a few lines plus a regression baseline.