From 5c5691e17c951b95c737db6bf64b6a2eddb9a159 Mon Sep 17 00:00:00 2001 From: Saurabh Shukla <136088049+ss2098@users.noreply.github.com> Date: Tue, 15 Sep 2026 22:12:21 -0800 Subject: [PATCH] Add Python-side Stokes PC fallback recorder --- src/underworld3/systems/solvers.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/underworld3/systems/solvers.py b/src/underworld3/systems/solvers.py index a9f59bbd..ae9a2ade 100644 --- a/src/underworld3/systems/solvers.py +++ b/src/underworld3/systems/solvers.py @@ -2318,6 +2318,30 @@ def _apply_automatic_penalty(self): # Assigned through the expression, so the latch is untouched and the # value stays automatic. + def _record_pc_fallback(self, site, *, requested, installed, reason, detail=""): + """Record one preconditioner fallback / degrade / guard-skip decision. + + This mirrors the generic SNES fallback recorder for Python-side Stokes + preconditioner checks. The record is written explicitly rather than + inferred from PETSc options or timings. + """ + if not hasattr(self, "_pc_fallbacks"): + self._pc_fallbacks = {} + + self._pc_fallbacks[site] = dict( + requested=requested, + installed=installed, + reason=reason, + detail=detail, + ) + + @property + def pc_fallbacks(self): + """Preconditioner fallback records for the current solver state.""" + if not hasattr(self, "_pc_fallbacks"): + self._pc_fallbacks = {} + return self._pc_fallbacks + def _check_velocity_preconditioner(self): """After setup: did the velocity block fall back off the multigrid?