FhSim  3.1.0
Marine systems simulation
Loading...
Searching...
No Matches
0104 — Seine/Vessel, Trawl/Vessel and Seine/Operation port values depend on the order of the calls
ID 0104
Class BUG
Severity 2
Status blocked

Models: Trawl/Vessel (ToVessel), Seine/Vessel (VesselDeploy), Seine/Operation, Seine/Cable (the shared attractors)

Found: 2026-10-06, feature trawlwriter (thread-race review). The data races were fixed (locks and atomics); the order dependence they exposed is left, because removing it moves the SeineOperation and SeineCable baselines.

Decision needed: Owner: may the seine baselines move so that these values become functions of (T, X)? The phase schedule looks meant as a function of time, but the latch is what the baselines record.

Evidence

  • src/trawl/TrawlVessel.cpp CalcOutput: the Vel and WarpVel ports use the speed command the latest OdeFcn stored (m_desiredSpeed), not the Vel input at the port's (T, X). Before the first OdeFcn it is InitialSpeed. OdeJacobian uses the same stored value.
  • src/seine/SeineOperation.cpp SetOperationalPhase: the phase is a latch on the largest time any caller has passed, never stepped down. A rejected or overshooting step past a phase start switches the phase for the retried, earlier evaluations too, and every extra caller (the vessel reading VesselSpeed from its port calculation, say) can move it.
  • WarpConnectedVessel latches BuoyPos from the vessel position of the latest call in Phase_NotSet.
  • src/seine/VesselDeploy.cpp DoDerivedOutputUpdate: the attractors are moved to the vessel position at the (T, X) of whichever port read ran last; Seine/Cable reads them in OdeFcn.

Effect

With NumCores > 1 a value can come from another stage than the reader's, so runs need not be reproducible. The SeineCable case gives identical output on 1 and 8 cores today (test SeineCable_SameOutputOnOneAndEightCores), because every object reads at the same time within a stage and the speed command does not change before 15 s; a command that changes inside a step is exposed.

Possible fix

TrawlVessel::DesiredSpeed(T, X)/DesiredHeading(T, X) read the inputs wherever they are needed (OdeFcn, CalcOutput, OdeJacobian with the model-global state X - m_IStatePos), and SeineOperation::PhaseAt(T) is a pure function of time used by every port. Tried on 2026-10-06: the trawl Vessel baseline holds; SeineOperation and SeineCable move (vessel position RMS up to 9e-2 m, the vessel turns at the phase start rather than at the first evaluation past it). The buoy latch needs the vessel position at the start of Phase_SetFirstLeg, for example latched in AcceptedStep.

Test that would prove it

A port read at one (T, X), an OdeFcn at another, and the same port read again gives the first value; a VesselSpeed read at an earlier time after a WarpConnectedVessel read at a later one gives the earlier phase's speed.

Risk

Moves the seine baselines; the seine cases are format illustrations, not validated scenarios.