[petsc-users] Proper way for exception handling

Barry Smith bsmith at petsc.dev
Wed Oct 1 11:34:53 CDT 2025


No. Your callback function should not be returning a PETSC_ERR_NOT_CONVERGED since your function doesn't know anything about the status of the nonlinear solver and is not in the business of deciding if SNES is converging or not.

What are you trying to convey back to PETSc if your function is not "all good"?

There are generally two possibilities,

1) just give up and stop the entire program immediately, then return PETSC_ERR_USER

2) indicate that SNES solve is asking your function to be evaluated at a point that is not in the domain of your function. For example, say your function is the square root and x is -1. In this situation, depending on the exact nonlinear solver being used SNES may be able to continue to try to solve the nonlinear system by changing its x value.  To indicate this call SNESSetFunctionDomainError(snes); and then do a usual return PETSC_SUCCESS; If SNES can continue it will, if it cannot then IT will generate a negative SNESConvergedReason indicating that SNES did not converge.

Barry








> On Oct 1, 2025, at 11:46 AM, Zou, Ling via petsc-users <petsc-users at mcs.anl.gov> wrote:
> 
> Although I haven’t tried yet. Does it make sense and should it work to change the code this way?
>  
> ================================================================
> PetscErrorCode SNESFormFunction(SNES, Vec, Vec, void*);
> double my_function();
> ================================================================
>  
> double my_function()
> {
>   if (all_good)
> return 1;
>   else
>   {
> throw 199;
> return 0;
>   }
> }
>  
> PetscErrorCode SNESFormFunction(SNES snes, Vec u, Vec r, void* ctx)
> {
>   Try
>   {
> my_value = my_function();
>   }
>   Catch (int err)
>   {
>     return PETSC_ERR_NOT_CONVERGED;
>   }
>  
>   // compute residuals
>  
>   return PETSC_SUCCESS;
> }
>  
> int main(int argc, char **argv)
> {
>   Initialize_PETSc();
>  
>   double dt = 1, dt_min = 0.001;
>   while (dt > dt_min)
>   {
> SNESSolve(AppCtx.snes, NULL, AppCtx.u);
>  
> SNESGetConvergedReason(AppCtx.snes, &(AppCtx.snes_converged_reason));
>  
> if (not_converged)
>   dt *= 0.5;
> }
>   }
>  
>   PetscFinalize();
> }
> ================================================================
>  
>  
>  
> From: petsc-users <petsc-users-bounces at mcs.anl.gov <mailto:petsc-users-bounces at mcs.anl.gov>> on behalf of Zou, Ling via petsc-users <petsc-users at mcs.anl.gov <mailto:petsc-users at mcs.anl.gov>>
> Date: Wednesday, October 1, 2025 at 9:33 AM
> To: PETSc <petsc-users at mcs.anl.gov <mailto:petsc-users at mcs.anl.gov>>
> Subject: [petsc-users] Proper way for exception handling
> 
> Hi,
>  
> After updating to PETSc 3.23 (from a quite old version, ~3.8), I found that my old way of exception handling not working any more, on my Mac.
> I would like to learn the proper way to handle exceptions in PETSc code.
>  
> Here is my pseudo code:
>  
> ================================================================
> PetscErrorCode SNESFormFunction(SNES, Vec, Vec, void*);
> double my_function();
> ================================================================
>  
> double my_function()
> {
>   if (all_good)
> return 1;
>   else
>   {
> throw 199;
> return 0;
>   }
> }
>  
> PetscErrorCode SNESFormFunction(SNES snes, Vec u, Vec r, void* ctx)
> {
>   double my_value = my_function();
>  
>   // compute residuals
> }
>  
> int main(int argc, char **argv)
> {
>   Initialize_PETSc();
>  
>   double dt = 1, dt_min = 0.001;
>   while (dt > dt_min)
>   {
> try
> {
>   SNESSolve(AppCtx.snes, NULL, AppCtx.u);
> }
> catch (int err)
> {
>   dt *= 0.5;
> }
>   }
>  
>   PetscFinalize();
> }
> ================================================================
>  
> This piece of logic used to work well, but now giving me the following error:
>  
> Current time (the starting time of this time step) = 0.. 
>         NL step =  0, SNES Function norm =  8.60984E+03
> libc++abi: terminating due to uncaught exception of type int
> Abort trap: 6
>  
> Q1: why this exception catch logic not working any more?
> Q2: is there any good example of PETSc exception handling I can follow?
>  
> Best,
> -Ling

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/petsc-users/attachments/20251001/e17e4336/attachment-0001.html>


More information about the petsc-users mailing list