|
FhSim
3.1.0
Marine systems simulation
|
| ID | 0108 |
| Class | KNOWN-LIMITATION |
| Severity | 2 |
| Status | blocked |
Models: —
Found: 2026-10-12, feature wake-casting-trawl, by fhsim_marine_elements' TrawlCableWakes.SharedSolverCastsBothDoors (tests/TrawlCableWakes_Test.cpp:266-299 at ME c6350a5) run with WakeEvaluation="Grid".
Decision needed: whether every IndexedWakeCastingObject should default to Direct in env (as WakeGroup does), or each consumer sets it (as the trawl rig does), and whether the Grid artefact is to be isolated and fixed or only documented.
TrawlCables share one solver, the rig is mirror symmetric (two doors, two clump weights). With Grid the final door positions after 1 s differ between the two doors' mirror images and between the two input orders by 0.1 to 5 mm, as large as the wake effect itself (about 1 mm, > 5e-4 m in the test). With Direct both agree within 2e-5 m. The test runs Direct; its comment (tests/TrawlCableWakes_Test.cpp:270-272 at ME c6350a5) records the finding.src/environment/WakeCaster.cpp:38: WakeEvaluation defaults to Grid for every source set, an IndexedWakeCastingObject included; only WakeGroup defaults to Direct (src/environment/WakeGroup.cpp:13-21, owner ruling 2026-10-12). At ME c6350a5 TrawlCable kept the Grid default (src/trawl_mooring_interaction/TrawlCable.h:72); the feature moves the trawl rig to Direct (same ruling): at ME 37bbc85 TrawlCable and RundDorg default to Direct through CoRiBoDynamics::ReadDoorAndClumpWakeSettings (src/trawl_mooring_interaction/DoorAndClumpWakeBodies.cpp:13-19), unless WakeEvaluation is given.src/environment/WakeCaster.cpp:275-304): cells up to kSizedCellAlong = 2 mean source diameters along the flow (:244), 0.75 across (:247), across a rig about 100 m wide, at most 4e6 cells (:253), so x_start = 0.5 D (default WakeXStartFactor) is a fraction of one cell along the flow.src/wake/WakeBuilder.cpp:152-168: a source is deposited at the nodes with x ≥ x_start inside its truncated footprint, with hard cuts at x_start, at the footprint radius and at deficit >= cutoff; src/wake/GriddedWake.cpp:18-25 samples by trilinear interpolation of the summed log ratio. So the deficit a body takes at its own centroid includes a share of its own deposit at the downstream nodes of its cell, and that share depends on where the body sits in the node lattice.src/environment/WakeCaster.cpp:636-648); sources at equal distance along the flow keep input order (stable_sort, :533), and in the build each samples the partial grid (:669-670).WakeGroup Direct because "the sized grid of a long, sparse group smears its members' wakes upstream" (src/environment/WakeGroup.cpp:18-19): the same interpolation.Suspected mechanism (not isolated): rounding-level asymmetries in the frame from the summation order, amplified by the lattice-dependent self-sampling and the hard cuts of the deposit. Not checked which of these dominates.
For a sparse source set (a few bodies tens of metres apart) the Grid result depends on the order of the bodies in the input and breaks a symmetry the physics has, by as much as the wake effect. Nets (dense panels, cells comparable to panels) are not known to be affected.
WakeEvaluation to Direct for an IndexedWakeCastingObject (few sources, Direct is cheap: N² per build, N per sample), keeping Grid for nets. A consumer can set it today; fhsim_marine_elements' trawl rig does.Grid is for dense sets; doc/user/wake-parameters.md (WakeEvaluation).ME's TrawlCableWakes.SharedSolverCastsBothDoors with WakeEvaluation="Grid": mirror symmetry within 2e-5 m and order independence within 2e-5 m (today 0.1 to 5 mm). In env: a TestWakeCluster of two mirror-placed bodies in Grid, with the bodies in both orders: the taken deficits equal within rounding.
Option 1 changes the results of every IndexedWakeCastingObject that relies on the Grid default (TestWakeCluster; consumers that do not set WakeEvaluation); option 2 can move net baselines.