163dd3a1aSKris Buschelman #define PETSCSNES_DLL 2e7e93795SLois Curfman McInnes 3b9147fbbSdalcinl #include "include/private/snesimpl.h" /*I "petscsnes.h" I*/ 4e7e93795SLois Curfman McInnes 54a2ae208SSatish Balay #undef __FUNCT__ 6a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSolution" 73f1db9ecSBarry Smith /*@C 8a6570f20SBarry Smith SNESMonitorSolution - Monitors progress of the SNES solvers by calling 936851e7fSLois Curfman McInnes VecView() for the approximate solution at each iteration. 103f1db9ecSBarry Smith 113f1db9ecSBarry Smith Collective on SNES 123f1db9ecSBarry Smith 133f1db9ecSBarry Smith Input Parameters: 143f1db9ecSBarry Smith + snes - the SNES context 153f1db9ecSBarry Smith . its - iteration number 164b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 173f1db9ecSBarry Smith - dummy - either a viewer or PETSC_NULL 183f1db9ecSBarry Smith 1936851e7fSLois Curfman McInnes Level: intermediate 203f1db9ecSBarry Smith 2136851e7fSLois Curfman McInnes .keywords: SNES, nonlinear, vector, monitor, view 223f1db9ecSBarry Smith 23a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView() 243f1db9ecSBarry Smith @*/ 25a6570f20SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorSolution(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 263f1db9ecSBarry Smith { 27dfbe8321SBarry Smith PetscErrorCode ierr; 283f1db9ecSBarry Smith Vec x; 29b0a32e0cSBarry Smith PetscViewer viewer = (PetscViewer) dummy; 303f1db9ecSBarry Smith 313f1db9ecSBarry Smith PetscFunctionBegin; 323f1db9ecSBarry Smith ierr = SNESGetSolution(snes,&x);CHKERRQ(ierr); 333f1db9ecSBarry Smith if (!viewer) { 343f1db9ecSBarry Smith MPI_Comm comm; 353f1db9ecSBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 36b0a32e0cSBarry Smith viewer = PETSC_VIEWER_DRAW_(comm); 373f1db9ecSBarry Smith } 383f1db9ecSBarry Smith ierr = VecView(x,viewer);CHKERRQ(ierr); 393f1db9ecSBarry Smith 403f1db9ecSBarry Smith PetscFunctionReturn(0); 413f1db9ecSBarry Smith } 423f1db9ecSBarry Smith 434a2ae208SSatish Balay #undef __FUNCT__ 44a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorResidual" 455ed2d596SBarry Smith /*@C 46a6570f20SBarry Smith SNESMonitorResidual - Monitors progress of the SNES solvers by calling 475ed2d596SBarry Smith VecView() for the residual at each iteration. 485ed2d596SBarry Smith 495ed2d596SBarry Smith Collective on SNES 505ed2d596SBarry Smith 515ed2d596SBarry Smith Input Parameters: 525ed2d596SBarry Smith + snes - the SNES context 535ed2d596SBarry Smith . its - iteration number 544b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 555ed2d596SBarry Smith - dummy - either a viewer or PETSC_NULL 565ed2d596SBarry Smith 575ed2d596SBarry Smith Level: intermediate 585ed2d596SBarry Smith 595ed2d596SBarry Smith .keywords: SNES, nonlinear, vector, monitor, view 605ed2d596SBarry Smith 61a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView() 625ed2d596SBarry Smith @*/ 63a6570f20SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorResidual(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 645ed2d596SBarry Smith { 65dfbe8321SBarry Smith PetscErrorCode ierr; 665ed2d596SBarry Smith Vec x; 675ed2d596SBarry Smith PetscViewer viewer = (PetscViewer) dummy; 685ed2d596SBarry Smith 695ed2d596SBarry Smith PetscFunctionBegin; 705ed2d596SBarry Smith ierr = SNESGetFunction(snes,&x,0,0);CHKERRQ(ierr); 715ed2d596SBarry Smith if (!viewer) { 725ed2d596SBarry Smith MPI_Comm comm; 735ed2d596SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 745ed2d596SBarry Smith viewer = PETSC_VIEWER_DRAW_(comm); 755ed2d596SBarry Smith } 765ed2d596SBarry Smith ierr = VecView(x,viewer);CHKERRQ(ierr); 775ed2d596SBarry Smith 785ed2d596SBarry Smith PetscFunctionReturn(0); 795ed2d596SBarry Smith } 805ed2d596SBarry Smith 815ed2d596SBarry Smith #undef __FUNCT__ 82a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSolutionUpdate" 83d132466eSBarry Smith /*@C 84a6570f20SBarry Smith SNESMonitorSolutionUpdate - Monitors progress of the SNES solvers by calling 85d132466eSBarry Smith VecView() for the UPDATE to the solution at each iteration. 86d132466eSBarry Smith 87d132466eSBarry Smith Collective on SNES 88d132466eSBarry Smith 89d132466eSBarry Smith Input Parameters: 90d132466eSBarry Smith + snes - the SNES context 91d132466eSBarry Smith . its - iteration number 924b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 93d132466eSBarry Smith - dummy - either a viewer or PETSC_NULL 94d132466eSBarry Smith 95d132466eSBarry Smith Level: intermediate 96d132466eSBarry Smith 97d132466eSBarry Smith .keywords: SNES, nonlinear, vector, monitor, view 98d132466eSBarry Smith 99a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView() 100d132466eSBarry Smith @*/ 101a6570f20SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorSolutionUpdate(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 102d132466eSBarry Smith { 103dfbe8321SBarry Smith PetscErrorCode ierr; 104d132466eSBarry Smith Vec x; 105b0a32e0cSBarry Smith PetscViewer viewer = (PetscViewer) dummy; 106d132466eSBarry Smith 107d132466eSBarry Smith PetscFunctionBegin; 108d132466eSBarry Smith ierr = SNESGetSolutionUpdate(snes,&x);CHKERRQ(ierr); 109d132466eSBarry Smith if (!viewer) { 110d132466eSBarry Smith MPI_Comm comm; 111d132466eSBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 112b0a32e0cSBarry Smith viewer = PETSC_VIEWER_DRAW_(comm); 113d132466eSBarry Smith } 114d132466eSBarry Smith ierr = VecView(x,viewer);CHKERRQ(ierr); 115d132466eSBarry Smith 116d132466eSBarry Smith PetscFunctionReturn(0); 117d132466eSBarry Smith } 118d132466eSBarry Smith 1194a2ae208SSatish Balay #undef __FUNCT__ 120a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefault" 1214b828684SBarry Smith /*@C 122a6570f20SBarry Smith SNESMonitorDefault - Monitors progress of the SNES solvers (default). 123e7e93795SLois Curfman McInnes 124c7afd0dbSLois Curfman McInnes Collective on SNES 125c7afd0dbSLois Curfman McInnes 126e7e93795SLois Curfman McInnes Input Parameters: 127c7afd0dbSLois Curfman McInnes + snes - the SNES context 128e7e93795SLois Curfman McInnes . its - iteration number 1294b27c08aSLois Curfman McInnes . fgnorm - 2-norm of residual 130c7afd0dbSLois Curfman McInnes - dummy - unused context 131fee21e36SBarry Smith 132e7e93795SLois Curfman McInnes Notes: 1334b27c08aSLois Curfman McInnes This routine prints the residual norm at each iteration. 134e7e93795SLois Curfman McInnes 13536851e7fSLois Curfman McInnes Level: intermediate 13636851e7fSLois Curfman McInnes 137e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, monitor, norm 138e7e93795SLois Curfman McInnes 139a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution() 140e7e93795SLois Curfman McInnes @*/ 141a6570f20SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 142e7e93795SLois Curfman McInnes { 143dfbe8321SBarry Smith PetscErrorCode ierr; 144a34d58ebSBarry Smith PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor) dummy; 145d132466eSBarry Smith 1463a40ed3dSBarry Smith PetscFunctionBegin; 147a34d58ebSBarry Smith if (!dummy) { 148a34d58ebSBarry Smith ierr = PetscViewerASCIIMonitorCreate(snes->comm,"stdout",0,&viewer);CHKERRQ(ierr); 149a34d58ebSBarry Smith } 150a34d58ebSBarry Smith ierr = PetscViewerASCIIMonitorPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,fgnorm);CHKERRQ(ierr); 151a34d58ebSBarry Smith if (!dummy) { 152a34d58ebSBarry Smith ierr = PetscViewerASCIIMonitorDestroy(viewer);CHKERRQ(ierr); 153a34d58ebSBarry Smith } 1543a40ed3dSBarry Smith PetscFunctionReturn(0); 155e7e93795SLois Curfman McInnes } 1563f1db9ecSBarry Smith 157eabae89aSBarry Smith typedef struct { 158a34d58ebSBarry Smith PetscViewerASCIIMonitor viewer; 159eabae89aSBarry Smith PetscReal *history; 160a6570f20SBarry Smith } SNESMonitorRatioContext; 161eabae89aSBarry Smith 1623a7fca6bSBarry Smith #undef __FUNCT__ 163a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatio" 1643a7fca6bSBarry Smith /*@C 165a6570f20SBarry Smith SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio 1664b27c08aSLois Curfman McInnes of residual norm at each iteration to the previous. 1673a7fca6bSBarry Smith 1683a7fca6bSBarry Smith Collective on SNES 1693a7fca6bSBarry Smith 1703a7fca6bSBarry Smith Input Parameters: 1713a7fca6bSBarry Smith + snes - the SNES context 1723a7fca6bSBarry Smith . its - iteration number 1733a7fca6bSBarry Smith . fgnorm - 2-norm of residual (or gradient) 174eabae89aSBarry Smith - dummy - context of monitor 1753a7fca6bSBarry Smith 1763a7fca6bSBarry Smith Level: intermediate 1773a7fca6bSBarry Smith 1783a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm 1793a7fca6bSBarry Smith 180a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution() 1813a7fca6bSBarry Smith @*/ 182a6570f20SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 1833a7fca6bSBarry Smith { 184dfbe8321SBarry Smith PetscErrorCode ierr; 18577431f27SBarry Smith PetscInt len; 18687828ca2SBarry Smith PetscReal *history; 187a6570f20SBarry Smith SNESMonitorRatioContext *ctx = (SNESMonitorRatioContext*)dummy; 1883a7fca6bSBarry Smith 1893a7fca6bSBarry Smith PetscFunctionBegin; 1903a7fca6bSBarry Smith ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,&len);CHKERRQ(ierr); 191958c9bccSBarry Smith if (!its || !history || its > len) { 192a34d58ebSBarry Smith ierr = PetscViewerASCIIMonitorPrintf(ctx->viewer,"%3D SNES Function norm %14.12e \n",its,fgnorm);CHKERRQ(ierr); 1933a7fca6bSBarry Smith } else { 19487828ca2SBarry Smith PetscReal ratio = fgnorm/history[its-1]; 195a34d58ebSBarry Smith ierr = PetscViewerASCIIMonitorPrintf(ctx->viewer,"%3D SNES Function norm %14.12e %G \n",its,fgnorm,ratio);CHKERRQ(ierr); 1963a7fca6bSBarry Smith } 1973a7fca6bSBarry Smith PetscFunctionReturn(0); 1983a7fca6bSBarry Smith } 1993a7fca6bSBarry Smith 2003a7fca6bSBarry Smith /* 2013a7fca6bSBarry Smith If the we set the history monitor space then we must destroy it 2023a7fca6bSBarry Smith */ 2033a7fca6bSBarry Smith #undef __FUNCT__ 204a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorRatioDestroy" 205a6570f20SBarry Smith PetscErrorCode SNESMonitorRatioDestroy(void *ct) 2063a7fca6bSBarry Smith { 207dfbe8321SBarry Smith PetscErrorCode ierr; 208a6570f20SBarry Smith SNESMonitorRatioContext *ctx = (SNESMonitorRatioContext*)ct; 2093a7fca6bSBarry Smith 2103a7fca6bSBarry Smith PetscFunctionBegin; 21105b42c5fSBarry Smith ierr = PetscFree(ctx->history);CHKERRQ(ierr); 212a34d58ebSBarry Smith ierr = PetscViewerASCIIMonitorDestroy(ctx->viewer);CHKERRQ(ierr); 213eabae89aSBarry Smith ierr = PetscFree(ctx);CHKERRQ(ierr); 2143a7fca6bSBarry Smith PetscFunctionReturn(0); 2153a7fca6bSBarry Smith } 2163a7fca6bSBarry Smith 2173a7fca6bSBarry Smith #undef __FUNCT__ 218a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSetRatio" 2193a7fca6bSBarry Smith /*@C 220a6570f20SBarry Smith SNESMonitorSetRatio - Sets SNES to use a monitor that prints the 2214b27c08aSLois Curfman McInnes ratio of the function norm at each iteration. 2223a7fca6bSBarry Smith 2233a7fca6bSBarry Smith Collective on SNES 2243a7fca6bSBarry Smith 2253a7fca6bSBarry Smith Input Parameters: 226eabae89aSBarry Smith + snes - the SNES context 227eabae89aSBarry Smith - viewer - ASCII viewer to print output 2283a7fca6bSBarry Smith 2293a7fca6bSBarry Smith Level: intermediate 2303a7fca6bSBarry Smith 2313a7fca6bSBarry Smith .keywords: SNES, nonlinear, monitor, norm 2323a7fca6bSBarry Smith 233a6570f20SBarry Smith .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault() 2343a7fca6bSBarry Smith @*/ 235a34d58ebSBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorSetRatio(SNES snes,PetscViewerASCIIMonitor viewer) 2363a7fca6bSBarry Smith { 237dfbe8321SBarry Smith PetscErrorCode ierr; 238a6570f20SBarry Smith SNESMonitorRatioContext *ctx; 23987828ca2SBarry Smith PetscReal *history; 2403a7fca6bSBarry Smith 2413a7fca6bSBarry Smith PetscFunctionBegin; 242eabae89aSBarry Smith if (!viewer) { 243a34d58ebSBarry Smith ierr = PetscViewerASCIIMonitorCreate(snes->comm,"stdout",0,&viewer);CHKERRQ(ierr); 244eabae89aSBarry Smith ierr = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr); 245eabae89aSBarry Smith } 246a6570f20SBarry Smith ierr = PetscNew(SNESMonitorRatioContext,&ctx); 2473a7fca6bSBarry Smith ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 2483a7fca6bSBarry Smith if (!history) { 249eabae89aSBarry Smith ierr = PetscMalloc(100*sizeof(PetscReal),&ctx->history);CHKERRQ(ierr); 250eabae89aSBarry Smith ierr = SNESSetConvergenceHistory(snes,ctx->history,0,100,PETSC_TRUE);CHKERRQ(ierr); 2513a7fca6bSBarry Smith } 252eabae89aSBarry Smith ctx->viewer = viewer; 253a6570f20SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRatio,ctx,SNESMonitorRatioDestroy);CHKERRQ(ierr); 2543a7fca6bSBarry Smith PetscFunctionReturn(0); 2553a7fca6bSBarry Smith } 2563a7fca6bSBarry Smith 257e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 2584a2ae208SSatish Balay #undef __FUNCT__ 259a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorDefaultShort" 260be1f7002SBarry Smith /* 261a6570f20SBarry Smith Default (short) SNES Monitor, same as SNESMonitorDefault() except 262be1f7002SBarry Smith it prints fewer digits of the residual as the residual gets smaller. 263be1f7002SBarry Smith This is because the later digits are meaningless and are often 264be1f7002SBarry Smith different on different machines; by using this routine different 265be1f7002SBarry Smith machines will usually generate the same output. 266be1f7002SBarry Smith */ 267a6570f20SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 268e7e93795SLois Curfman McInnes { 269dfbe8321SBarry Smith PetscErrorCode ierr; 270a34d58ebSBarry Smith PetscViewerASCIIMonitor viewer = (PetscViewerASCIIMonitor) dummy; 271d132466eSBarry Smith 2723a40ed3dSBarry Smith PetscFunctionBegin; 273a34d58ebSBarry Smith if (!dummy) { 274a34d58ebSBarry Smith ierr = PetscViewerASCIIMonitorCreate(snes->comm,"stdout",0,&viewer);CHKERRQ(ierr); 275a34d58ebSBarry Smith } 2768f240d10SBarry Smith if (fgnorm > 1.e-9) { 277a34d58ebSBarry Smith ierr = PetscViewerASCIIMonitorPrintf(viewer,"%3D SNES Function norm %G \n",its,fgnorm);CHKERRQ(ierr); 2783a40ed3dSBarry Smith } else if (fgnorm > 1.e-11){ 279a34d58ebSBarry Smith ierr = PetscViewerASCIIMonitorPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,fgnorm);CHKERRQ(ierr); 2803a40ed3dSBarry Smith } else { 281a34d58ebSBarry Smith ierr = PetscViewerASCIIMonitorPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr); 282a34d58ebSBarry Smith } 283a34d58ebSBarry Smith if (!dummy) { 284a34d58ebSBarry Smith ierr = PetscViewerASCIIMonitorDestroy(viewer);CHKERRQ(ierr); 285e7e93795SLois Curfman McInnes } 2863a40ed3dSBarry Smith PetscFunctionReturn(0); 287e7e93795SLois Curfman McInnes } 288e7e93795SLois Curfman McInnes /* ---------------------------------------------------------------- */ 2894a2ae208SSatish Balay #undef __FUNCT__ 2904b27c08aSLois Curfman McInnes #define __FUNCT__ "SNESConverged_LS" 2914b828684SBarry Smith /*@C 2924b27c08aSLois Curfman McInnes SNESConverged_LS - Monitors the convergence of the solvers for 293f525115eSLois Curfman McInnes systems of nonlinear equations (default). 294e7e93795SLois Curfman McInnes 295c7afd0dbSLois Curfman McInnes Collective on SNES 296c7afd0dbSLois Curfman McInnes 297e7e93795SLois Curfman McInnes Input Parameters: 298c7afd0dbSLois Curfman McInnes + snes - the SNES context 29906ee9f85SBarry Smith . it - the iteration (0 indicates before any Newton steps) 300e7e93795SLois Curfman McInnes . xnorm - 2-norm of current iterate 301e7e93795SLois Curfman McInnes . pnorm - 2-norm of current step 3027f3332b4SBarry Smith . fnorm - 2-norm of function at current iterate 303c7afd0dbSLois Curfman McInnes - dummy - unused context 304e7e93795SLois Curfman McInnes 305184914b5SBarry Smith Output Parameter: 306184914b5SBarry Smith . reason - one of 30770441072SBarry Smith $ SNES_CONVERGED_FNORM_ABS - (fnorm < abstol), 3083304466cSBarry Smith $ SNES_CONVERGED_PNORM_RELATIVE - (pnorm < xtol*xnorm), 309184914b5SBarry Smith $ SNES_CONVERGED_FNORM_RELATIVE - (fnorm < rtol*fnorm0), 310184914b5SBarry Smith $ SNES_DIVERGED_FUNCTION_COUNT - (nfct > maxf), 311184914b5SBarry Smith $ SNES_DIVERGED_FNORM_NAN - (fnorm == NaN), 312184914b5SBarry Smith $ SNES_CONVERGED_ITERATING - (otherwise), 313e7e93795SLois Curfman McInnes 314e7e93795SLois Curfman McInnes where 315c7afd0dbSLois Curfman McInnes + maxf - maximum number of function evaluations, 316c7afd0dbSLois Curfman McInnes set with SNESSetTolerances() 317c7afd0dbSLois Curfman McInnes . nfct - number of function evaluations, 31870441072SBarry Smith . abstol - absolute function norm tolerance, 319c7afd0dbSLois Curfman McInnes set with SNESSetTolerances() 320c7afd0dbSLois Curfman McInnes - rtol - relative function norm tolerance, set with SNESSetTolerances() 321fee21e36SBarry Smith 32236851e7fSLois Curfman McInnes Level: intermediate 32336851e7fSLois Curfman McInnes 324e7e93795SLois Curfman McInnes .keywords: SNES, nonlinear, default, converged, convergence 325e7e93795SLois Curfman McInnes 326*71f87433Sdalcinl .seealso: SNESSetConvergenceTest() 327e7e93795SLois Curfman McInnes @*/ 32806ee9f85SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESConverged_LS(SNES snes,PetscInt it,PetscReal xnorm,PetscReal pnorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy) 329e7e93795SLois Curfman McInnes { 33063ba0a88SBarry Smith PetscErrorCode ierr; 33163ba0a88SBarry Smith 3323a40ed3dSBarry Smith PetscFunctionBegin; 33306ee9f85SBarry Smith *reason = SNES_CONVERGED_ITERATING; 33406ee9f85SBarry Smith 33506ee9f85SBarry Smith if (!it) { 33606ee9f85SBarry Smith /* set parameter for default relative tolerance convergence test */ 33706ee9f85SBarry Smith snes->ttol = fnorm*snes->rtol; 33806ee9f85SBarry Smith } 339d252947aSBarry Smith if (fnorm != fnorm) { 340ae15b995SBarry Smith ierr = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr); 341184914b5SBarry Smith *reason = SNES_DIVERGED_FNORM_NAN; 34270441072SBarry Smith } else if (fnorm < snes->abstol) { 343ae15b995SBarry Smith ierr = PetscInfo2(snes,"Converged due to function norm %G < %G\n",fnorm,snes->abstol);CHKERRQ(ierr); 344184914b5SBarry Smith *reason = SNES_CONVERGED_FNORM_ABS; 34543e71028SBarry Smith } else if (snes->nfuncs >= snes->max_funcs) { 346ae15b995SBarry Smith ierr = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr); 347184914b5SBarry Smith *reason = SNES_DIVERGED_FUNCTION_COUNT; 34806ee9f85SBarry Smith } 34906ee9f85SBarry Smith 35006ee9f85SBarry Smith if (it && !*reason) { 35106ee9f85SBarry Smith if (fnorm <= snes->ttol) { 35206ee9f85SBarry Smith ierr = PetscInfo2(snes,"Converged due to function norm %G < %G (relative tolerance)\n",fnorm,snes->ttol);CHKERRQ(ierr); 35306ee9f85SBarry Smith *reason = SNES_CONVERGED_FNORM_RELATIVE; 35406ee9f85SBarry Smith } else if (pnorm < snes->xtol*xnorm) { 35506ee9f85SBarry Smith ierr = PetscInfo3(snes,"Converged due to small update length: %G < %G * %G\n",pnorm,snes->xtol,xnorm);CHKERRQ(ierr); 35606ee9f85SBarry Smith *reason = SNES_CONVERGED_PNORM_RELATIVE; 35706ee9f85SBarry Smith } 358e7e93795SLois Curfman McInnes } 3593a40ed3dSBarry Smith PetscFunctionReturn(0); 360e7e93795SLois Curfman McInnes } 361