Skip to content

fix(solve-report): SNES converged-reason table is off by one against PETSc#444

Open
lmoresi wants to merge 1 commit into
developmentfrom
bugfix/snes-converged-reason-table
Open

fix(solve-report): SNES converged-reason table is off by one against PETSc#444
lmoresi wants to merge 1 commit into
developmentfrom
bugfix/snes-converged-reason-table

Conversation

@lmoresi

@lmoresi lmoresi commented Jul 27, 2026

Copy link
Copy Markdown
Member

The bug

solve_report's SNES converged-reason table is shifted by one against PETSc, and claims a
code 1 that PETSc does not define:

code PETSc reported as
2 CONVERGED_FNORM_ABS CONVERGED_FNORM_RELATIVE
3 CONVERGED_FNORM_RELATIVE CONVERGED_SNORM_RELATIVE
4 CONVERGED_SNORM_RELATIVE CONVERGED_ITS
5 CONVERGED_ITS UNKNOWN_5

Why the direction matters

A solve that stopped on the step norm — the weakest criterion, and what a stalled
viscoplastic solve reports — was labelled CONVERGED_ITS. A genuine residual convergence
was labelled CONVERGED_SNORM_RELATIVE.

Reading a difficulty report is how a continuation driver decides whether a parameter
station is reachable, so a mislabelled convergence is exactly the kind of error that puts
false rescues on a regime map without anyone noticing.

Found while checking why a hard Drucker–Prager station was reporting CONVERGED_ITS on a
solve that had no iteration cap in play. It had actually converged on the step norm — a
different and much weaker claim.

Also fixed

DIVERGED_OBJECTIVE_DOMAIN (-13) and DIVERGED_OBJECTIVE_NANORINF (-14) were unmapped
and surfaced as UNKNOWN_n; -4 is DIVERGED_FUNCTION_NANORINF in PETSc, not
DIVERGED_FNORM_NAN.

How it survived

The table is hand-written on purpose — the module must import without the Cython
extension present — so it can drift. The existing test pinned it to itself:

assert reason_string(2) == "CONVERGED_FNORM_RELATIVE"    # asserts the bug

The KSP table sitting next to it was checked against petsc4py and is correct. Only the
SNES one was never pinned.

test_snes_reason_table_matches_petsc now checks both directions: every label matches the
enum, and every reason PETSc can return is mapped — so a PETSc renumbering or a future
hand-edit fails the test instead of silently mislabelling solves.

Verified against petsc4py 3.25; the reason-table tests pass.

Underworld development team with AI support from Claude Code

… PETSc

Every positive SNES reason was shifted by one slot, and the table claimed a
code 1 that PETSc does not define:

  reason 2  PETSc CONVERGED_FNORM_ABS       reported as CONVERGED_FNORM_RELATIVE
  reason 3  PETSc CONVERGED_FNORM_RELATIVE  reported as CONVERGED_SNORM_RELATIVE
  reason 4  PETSc CONVERGED_SNORM_RELATIVE  reported as CONVERGED_ITS
  reason 5  PETSc CONVERGED_ITS             reported as UNKNOWN_5

The direction matters. A solve that stopped on the STEP norm -- the weakest
criterion, and what a stalled viscoplastic solve reports -- was labelled
CONVERGED_ITS, while a genuine residual convergence was labelled
CONVERGED_SNORM_RELATIVE. Reading a difficulty report is how a continuation
driver decides whether a parameter station is reachable, so a mislabelled
convergence is the kind of error that quietly puts false rescues on a regime
map. Found while checking why a hard plastic station was reporting
CONVERGED_ITS.

Also adds DIVERGED_OBJECTIVE_DOMAIN (-13) and DIVERGED_OBJECTIVE_NANORINF
(-14), which were unmapped and surfaced as UNKNOWN_n, and corrects -4 to its
PETSc name DIVERGED_FUNCTION_NANORINF.

The table is hand-written on purpose -- the module must import without the
Cython extension -- so it can drift, and the existing test pinned it to ITSELF
(reason_string(2) == 'CONVERGED_FNORM_RELATIVE') rather than to the enum, which
is how this survived. The KSP table next to it WAS checked against petsc4py and
was correct. test_snes_reason_table_matches_petsc now checks both directions:
every label matches the enum, and every reason PETSc can return is mapped.

Underworld development team with AI support from Claude Code
Copilot AI review requested due to automatic review settings July 27, 2026 09:13

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants