|
FhSim
3.1.0
Marine systems simulation
|
| ID | 0122 |
| Class | KNOWN-LIMITATION |
| Severity | 2 |
| Status | blocked |
Models: Net/NetStructure and any net model with a dense Jacobian, under <Integrator Method="BDF"> with no <LinearSolver>
Found: 2026-09-27, WP-D2 (MARE-0101) test S6; diagnosed by the lead's diagnostic agent (scratch branch diag/bdf-step cb3af26, never merged)
Decision needed: Upstream, in FhSim: FHSIM-0028 (filed on fhsim branch review/sundials-spgmr-default, not yet on main). Nothing to decide here; re-enable DISABLED_S6_SundialsBdfDefaultLinearSolverStepsDoNotCollapseAtARebuild once FhSim's default is fixed.
The cause is in FhSim, not in this library: FHSIM-0028. Without a <LinearSolver> element, the Sundials backend runs SPGMR (IntegratorConfig.h:201 at fhsim e0bbf4ea) with maxl 5 (SundialsSolverBuilder.cpp:200-205, maxl 0 → SUNSPGMR_MAXL_DEFAULT). For a model whose Jacobian resolves to DenseLU, such as a NetStructure, it adds no preconditioner (SundialsSolverBuilder.cpp:136-137). In a smooth transient, the GMRES solve of the second Newton iteration returns SUNLS_RES_REDUCED. SUNDIALS 7.5 cvLsSolve turns this into SUN_NLS_CONV_RECVR, and CVODE cuts the step by 0.25 on each failure. The FhSim log hides this: it prints Linear solver : DenseLU, Preconditioner : none (FHSIM-0029).
Numbers on test S6 (tests/NetValidation_ZhanCylinder_Test.cpp: the Zhan cylinder, s = 0.223, 1 m/s, 720 states, 192 panels, Freeze wake built at 1 s, tow k = 1e4 N/m, StepMax 0.1 s, tolerances 1e-6):
| Linear solver | Steps | Wall | Step during the transients |
|---|---|---|---|
| default (unpreconditioned SPGMR) | 761 | 11 s | 0.1 s → 2.0e-4 s (first blend, t = 1.10 s) and 3.5e-5 s (second, t = 6.12 s) |
Preconditioner="jacobi" | — | — | still collapses, to 1.35e-4 s |
<LinearSolver Type="DENSE"/><Jacobian Type="dense"/> | 379 | 1 s | steady at 0.1 s |
gdb counted 77 and 36 SUN_NLS_CONV_RECVR failures in the two blends and none elsewhere. A load ramp with the wake off collapses the step in the same way (to 9.7e-5 s), so the wake blend is only one trigger. Any smooth transient will do.
Red and green on branch wp/S6-bdf-dense (the S6 case with the two solvers, one gtest run with --gtest_also_run_disabled_tests):
With DENSE the minimum step after each rebuild equals the 0.1 s before it (ratio 1.00 > 0.5). With the default solver it is 1/490 and 1/2857 of it. The full VALIDATION run's report (NetValidation_ZhanCylinder_report.txt) gives BDF with DENSE 379 steps and 0.98 s wall, against 761 steps and 11.87 s with the default solver. The drag at the end is 61.4603 N with DENSE, the same as RK45_i (25888 steps) to the printed digits, and 61.4883 N with the default solver.
Two things were not diagnosed. With DENSE, the stiffer diagnostic variant at tow stiffness k = 1e2 N/m aborts at t = 2.59 s with repeated error-test failures. With DENSE, a 0.1 s wake blend still dips the step to 5e-4 … 1.5e-3 s. Neither is covered by S6, which runs k = 1e4 N/m and the default 2 s blend.
Owner ruling R135 (batch B3, MARE-0345) held the net's own private field per step with the blend weight of the step start, a staircase in time during a blend. That made this collapse five times worse on S6 with the default solver: 3798 steps, 1232 Newton convergence failures, 43.3 s, and a minimum step of 4.3e-6 s in the first blend (features/net-hydrodynamics/docs/review/impact/R135-implicit.md). Owner ruling R136 (batch B8, MARE-0349; fhsim_environment ENV-0099, marenv MENV-0066) keeps the blend weight live: S6 with the default solver takes 472 steps, 173 Newton convergence failures and 7.0 s (B2 in the same campaign: 542, 211, 7.5 s; median of 3 runs), with a minimum step of 1.3e-4 s in the first blend (B2: 1.4e-4 s). With WakeBlendTime="0.1", BDF DENSE keeps its B2 minimum step of 1.48e-3 s in the blend (B3: 1.0e-6 s). The collapse of this issue itself is unchanged: it waits on FHSIM-0028.
A user who runs a net model under <Integrator Method="BDF"> and names no linear solver gets steps two to three orders of magnitude below StepMax in every transient: a wake rebuild, a load or current ramp, a manoeuvre. The run is about ten times slower than it needs to be, and nothing in the log explains why.
For dense net models, name the direct dense solver:
The user guide's "Casting a wake" section says so. Test S6 runs BDF this way.
Upstream only (FHSIM-0028): (a) default to the SUNDIALS DENSE solver when SPGMR would run unpreconditioned on a DenseLU model, (b) a real preconditioner for SPGMR or a way to set maxl, (c) log the solver actually in use (FHSIM-0029). Nothing changes in this library, apart from re-enabling the disabled test when the upstream fix lands.
NetValidation_ZhanCylinder_VALIDATION.DISABLED_S6_SundialsBdfDefaultLinearSolverStepsDoNotCollapseAtARebuild: the minimum step after each rebuild must be more than half the minimum step before it. It fails today and should pass once FhSim's default is fixed.
None in this library. The upstream fix changes the default solver of every Sundials run that names none, so regression baselines that use Sundials BDF without a <LinearSolver> would move.