1 2 #include <petsc-private/snesimpl.h> /*I "petscsnes.h" I*/ 3 #include <petscblaslapack.h> 4 5 #undef __FUNCT__ 6 #define __FUNCT__ "SNESMonitorSolution" 7 /*@C 8 SNESMonitorSolution - Monitors progress of the SNES solvers by calling 9 VecView() for the approximate solution at each iteration. 10 11 Collective on SNES 12 13 Input Parameters: 14 + snes - the SNES context 15 . its - iteration number 16 . fgnorm - 2-norm of residual 17 - dummy - either a viewer or PETSC_NULL 18 19 Level: intermediate 20 21 .keywords: SNES, nonlinear, vector, monitor, view 22 23 .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView() 24 @*/ 25 PetscErrorCode SNESMonitorSolution(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 26 { 27 PetscErrorCode ierr; 28 Vec x; 29 PetscViewer viewer = (PetscViewer) dummy; 30 31 PetscFunctionBegin; 32 ierr = SNESGetSolution(snes,&x);CHKERRQ(ierr); 33 if (!viewer) { 34 MPI_Comm comm; 35 ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 36 viewer = PETSC_VIEWER_DRAW_(comm); 37 } 38 ierr = VecView(x,viewer);CHKERRQ(ierr); 39 40 PetscFunctionReturn(0); 41 } 42 43 #undef __FUNCT__ 44 #define __FUNCT__ "SNESMonitorResidual" 45 /*@C 46 SNESMonitorResidual - Monitors progress of the SNES solvers by calling 47 VecView() for the residual at each iteration. 48 49 Collective on SNES 50 51 Input Parameters: 52 + snes - the SNES context 53 . its - iteration number 54 . fgnorm - 2-norm of residual 55 - dummy - either a viewer or PETSC_NULL 56 57 Level: intermediate 58 59 .keywords: SNES, nonlinear, vector, monitor, view 60 61 .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView() 62 @*/ 63 PetscErrorCode SNESMonitorResidual(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 64 { 65 PetscErrorCode ierr; 66 Vec x; 67 PetscViewer viewer = (PetscViewer) dummy; 68 69 PetscFunctionBegin; 70 ierr = SNESGetFunction(snes,&x,0,0);CHKERRQ(ierr); 71 if (!viewer) { 72 MPI_Comm comm; 73 ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 74 viewer = PETSC_VIEWER_DRAW_(comm); 75 } 76 ierr = VecView(x,viewer);CHKERRQ(ierr); 77 78 PetscFunctionReturn(0); 79 } 80 81 #undef __FUNCT__ 82 #define __FUNCT__ "SNESMonitorSolutionUpdate" 83 /*@C 84 SNESMonitorSolutionUpdate - Monitors progress of the SNES solvers by calling 85 VecView() for the UPDATE to the solution at each iteration. 86 87 Collective on SNES 88 89 Input Parameters: 90 + snes - the SNES context 91 . its - iteration number 92 . fgnorm - 2-norm of residual 93 - dummy - either a viewer or PETSC_NULL 94 95 Level: intermediate 96 97 .keywords: SNES, nonlinear, vector, monitor, view 98 99 .seealso: SNESMonitorSet(), SNESMonitorDefault(), VecView() 100 @*/ 101 PetscErrorCode SNESMonitorSolutionUpdate(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 102 { 103 PetscErrorCode ierr; 104 Vec x; 105 PetscViewer viewer = (PetscViewer) dummy; 106 107 PetscFunctionBegin; 108 ierr = SNESGetSolutionUpdate(snes,&x);CHKERRQ(ierr); 109 if (!viewer) { 110 MPI_Comm comm; 111 ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 112 viewer = PETSC_VIEWER_DRAW_(comm); 113 } 114 ierr = VecView(x,viewer);CHKERRQ(ierr); 115 116 PetscFunctionReturn(0); 117 } 118 119 #undef __FUNCT__ 120 #define __FUNCT__ "SNESMonitorDefault" 121 /*@C 122 SNESMonitorDefault - Monitors progress of the SNES solvers (default). 123 124 Collective on SNES 125 126 Input Parameters: 127 + snes - the SNES context 128 . its - iteration number 129 . fgnorm - 2-norm of residual 130 - dummy - unused context 131 132 Notes: 133 This routine prints the residual norm at each iteration. 134 135 Level: intermediate 136 137 .keywords: SNES, nonlinear, default, monitor, norm 138 139 .seealso: SNESMonitorSet(), SNESMonitorSolution() 140 @*/ 141 PetscErrorCode SNESMonitorDefault(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 142 { 143 PetscErrorCode ierr; 144 PetscViewer viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm); 145 146 PetscFunctionBegin; 147 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 148 ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr); 149 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 150 PetscFunctionReturn(0); 151 } 152 153 #undef __FUNCT__ 154 #define __FUNCT__ "SNESMonitorJacUpdateSpectrum" 155 PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,void *ctx) 156 { 157 #if defined(PETSC_MISSING_LAPACK_GEEV) 158 SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_SUP,"GEEV - Lapack routine is unavailable\nNot able to provide eigen values."); 159 #elif defined(PETSC_HAVE_ESSL) 160 SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_SUP,"GEEV - No support for ESSL Lapack Routines"); 161 #else 162 Vec X; 163 Mat J,dJ,dJdense; 164 PetscErrorCode ierr; 165 PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 166 PetscInt n,i; 167 PetscBLASInt nb,lwork; 168 PetscReal *eigr,*eigi; 169 MatStructure flg = DIFFERENT_NONZERO_PATTERN; 170 PetscScalar *work; 171 PetscScalar *a; 172 173 PetscFunctionBegin; 174 if (it == 0) PetscFunctionReturn(0); 175 /* create the difference between the current update and the current jacobian */ 176 ierr = SNESGetSolution(snes,&X);CHKERRQ(ierr); 177 ierr = SNESGetJacobian(snes,&J,PETSC_NULL,&func,PETSC_NULL);CHKERRQ(ierr); 178 ierr = MatDuplicate(J,MAT_COPY_VALUES,&dJ);CHKERRQ(ierr); 179 ierr = SNESComputeJacobian(snes,X,&dJ,&dJ,&flg);CHKERRQ(ierr); 180 ierr = MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 181 /* compute the spectrum directly */ 182 ierr = MatConvert(dJ,MATSEQDENSE,MAT_INITIAL_MATRIX,&dJdense);CHKERRQ(ierr); 183 ierr = MatGetSize(dJ,&n,PETSC_NULL);CHKERRQ(ierr); 184 nb = PetscBLASIntCast(n); 185 lwork = 3*nb; 186 ierr = PetscMalloc(n*sizeof(PetscReal),&eigr);CHKERRQ(ierr); 187 ierr = PetscMalloc(n*sizeof(PetscReal),&eigi);CHKERRQ(ierr); 188 ierr = PetscMalloc(lwork*sizeof(PetscScalar),&work);CHKERRQ(ierr); 189 ierr = MatDenseGetArray(dJdense,&a);CHKERRQ(ierr); 190 #if !defined(PETSC_USE_COMPLEX) 191 { 192 PetscBLASInt lierr; 193 ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 194 LAPACKgeev_("N","N",&nb,a,&nb,eigr,eigi,PETSC_NULL,&nb,PETSC_NULL,&nb,work,&lwork,&lierr); 195 if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"geev() error %d",lierr); 196 ierr = PetscFPTrapPop();CHKERRQ(ierr); 197 } 198 #else 199 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not coded for complex"); 200 #endif 201 PetscPrintf(((PetscObject)snes)->comm,"Eigenvalues of J_%d - J_%d:\n",it,it-1);CHKERRQ(ierr); 202 for (i=0;i<n;i++) { 203 PetscPrintf(((PetscObject)snes)->comm,"%5d: %20.5g + %20.5gi\n",i,eigr[i],eigi[i]);CHKERRQ(ierr); 204 } 205 ierr = MatDenseRestoreArray(dJdense,&a);CHKERRQ(ierr); 206 ierr = MatDestroy(&dJ);CHKERRQ(ierr); 207 ierr = MatDestroy(&dJdense);CHKERRQ(ierr); 208 ierr = PetscFree(eigr);CHKERRQ(ierr); 209 ierr = PetscFree(eigi);CHKERRQ(ierr); 210 ierr = PetscFree(work);CHKERRQ(ierr); 211 PetscFunctionReturn(0); 212 #endif 213 } 214 215 #undef __FUNCT__ 216 #define __FUNCT__ "SNESMonitorRange_Private" 217 PetscErrorCode SNESMonitorRange_Private(SNES snes,PetscInt it,PetscReal *per) 218 { 219 PetscErrorCode ierr; 220 Vec resid; 221 PetscReal rmax,pwork; 222 PetscInt i,n,N; 223 PetscScalar *r; 224 225 PetscFunctionBegin; 226 ierr = SNESGetFunction(snes,&resid,0,0);CHKERRQ(ierr); 227 ierr = VecNorm(resid,NORM_INFINITY,&rmax);CHKERRQ(ierr); 228 ierr = VecGetLocalSize(resid,&n);CHKERRQ(ierr); 229 ierr = VecGetSize(resid,&N);CHKERRQ(ierr); 230 ierr = VecGetArray(resid,&r);CHKERRQ(ierr); 231 pwork = 0.0; 232 for (i=0; i<n; i++) { 233 pwork += (PetscAbsScalar(r[i]) > .20*rmax); 234 } 235 ierr = MPI_Allreduce(&pwork,per,1,MPIU_REAL,MPIU_SUM,((PetscObject)snes)->comm);CHKERRQ(ierr); 236 ierr = VecRestoreArray(resid,&r);CHKERRQ(ierr); 237 *per = *per/N; 238 PetscFunctionReturn(0); 239 } 240 241 #undef __FUNCT__ 242 #define __FUNCT__ "SNESMonitorRange" 243 /*@C 244 SNESMonitorRange - Prints the percentage of residual elements that are more then 10 percent of the maximum value. 245 246 Collective on SNES 247 248 Input Parameters: 249 + snes - iterative context 250 . it - iteration number 251 . rnorm - 2-norm (preconditioned) residual value (may be estimated). 252 - dummy - unused monitor context 253 254 Options Database Key: 255 . -snes_monitor_range - Activates SNESMonitorRange() 256 257 Level: intermediate 258 259 .keywords: SNES, default, monitor, residual 260 261 .seealso: SNESMonitorSet(), SNESMonitorDefault(), SNESMonitorLGCreate() 262 @*/ 263 PetscErrorCode SNESMonitorRange(SNES snes,PetscInt it,PetscReal rnorm,void *dummy) 264 { 265 PetscErrorCode ierr; 266 PetscReal perc,rel; 267 PetscViewer viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm); 268 /* should be in a MonitorRangeContext */ 269 static PetscReal prev; 270 271 PetscFunctionBegin; 272 if (!it) prev = rnorm; 273 ierr = SNESMonitorRange_Private(snes,it,&perc);CHKERRQ(ierr); 274 275 rel = (prev - rnorm)/prev; 276 prev = rnorm; 277 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 278 ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES preconditioned resid norm %14.12e Percent values above 20 percent of maximum %5.2f relative decrease %5.2e ratio %5.2e \n",it,(double)rnorm,(double)100.0*perc,(double)rel,(double)rel/perc);CHKERRQ(ierr); 279 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 280 PetscFunctionReturn(0); 281 } 282 283 typedef struct { 284 PetscViewer viewer; 285 PetscReal *history; 286 } SNESMonitorRatioContext; 287 288 #undef __FUNCT__ 289 #define __FUNCT__ "SNESMonitorRatio" 290 /*@C 291 SNESMonitorRatio - Monitors progress of the SNES solvers by printing the ratio 292 of residual norm at each iteration to the previous. 293 294 Collective on SNES 295 296 Input Parameters: 297 + snes - the SNES context 298 . its - iteration number 299 . fgnorm - 2-norm of residual (or gradient) 300 - dummy - context of monitor 301 302 Level: intermediate 303 304 .keywords: SNES, nonlinear, monitor, norm 305 306 .seealso: SNESMonitorSet(), SNESMonitorSolution() 307 @*/ 308 PetscErrorCode SNESMonitorRatio(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 309 { 310 PetscErrorCode ierr; 311 PetscInt len; 312 PetscReal *history; 313 SNESMonitorRatioContext *ctx = (SNESMonitorRatioContext*)dummy; 314 315 PetscFunctionBegin; 316 ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,&len);CHKERRQ(ierr); 317 ierr = PetscViewerASCIIAddTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 318 if (!its || !history || its > len) { 319 ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e \n",its,(double)fgnorm);CHKERRQ(ierr); 320 } else { 321 PetscReal ratio = fgnorm/history[its-1]; 322 ierr = PetscViewerASCIIPrintf(ctx->viewer,"%3D SNES Function norm %14.12e %14.12e \n",its,(double)fgnorm,(double)ratio);CHKERRQ(ierr); 323 } 324 ierr = PetscViewerASCIISubtractTab(ctx->viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 325 PetscFunctionReturn(0); 326 } 327 328 /* 329 If the we set the history monitor space then we must destroy it 330 */ 331 #undef __FUNCT__ 332 #define __FUNCT__ "SNESMonitorRatioDestroy" 333 PetscErrorCode SNESMonitorRatioDestroy(void **ct) 334 { 335 PetscErrorCode ierr; 336 SNESMonitorRatioContext *ctx = *(SNESMonitorRatioContext**)ct; 337 338 PetscFunctionBegin; 339 ierr = PetscFree(ctx->history);CHKERRQ(ierr); 340 ierr = PetscViewerDestroy(&ctx->viewer);CHKERRQ(ierr); 341 ierr = PetscFree(ctx);CHKERRQ(ierr); 342 PetscFunctionReturn(0); 343 } 344 345 #undef __FUNCT__ 346 #define __FUNCT__ "SNESMonitorSetRatio" 347 /*@C 348 SNESMonitorSetRatio - Sets SNES to use a monitor that prints the 349 ratio of the function norm at each iteration. 350 351 Collective on SNES 352 353 Input Parameters: 354 + snes - the SNES context 355 - viewer - ASCII viewer to print output 356 357 Level: intermediate 358 359 .keywords: SNES, nonlinear, monitor, norm 360 361 .seealso: SNESMonitorSet(), SNESMonitorSolution(), SNESMonitorDefault() 362 @*/ 363 PetscErrorCode SNESMonitorSetRatio(SNES snes,PetscViewer viewer) 364 { 365 PetscErrorCode ierr; 366 SNESMonitorRatioContext *ctx; 367 PetscReal *history; 368 369 PetscFunctionBegin; 370 if (!viewer) { 371 ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,"stdout",&viewer);CHKERRQ(ierr); 372 ierr = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr); 373 } 374 ierr = PetscNewLog(snes,SNESMonitorRatioContext,&ctx);CHKERRQ(ierr); 375 ierr = SNESGetConvergenceHistory(snes,&history,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 376 if (!history) { 377 ierr = PetscMalloc(100*sizeof(PetscReal),&ctx->history);CHKERRQ(ierr); 378 ierr = SNESSetConvergenceHistory(snes,ctx->history,0,100,PETSC_TRUE);CHKERRQ(ierr); 379 } 380 ctx->viewer = viewer; 381 ierr = SNESMonitorSet(snes,SNESMonitorRatio,ctx,SNESMonitorRatioDestroy);CHKERRQ(ierr); 382 PetscFunctionReturn(0); 383 } 384 385 /* ---------------------------------------------------------------- */ 386 #undef __FUNCT__ 387 #define __FUNCT__ "SNESMonitorDefaultShort" 388 /* 389 Default (short) SNES Monitor, same as SNESMonitorDefault() except 390 it prints fewer digits of the residual as the residual gets smaller. 391 This is because the later digits are meaningless and are often 392 different on different machines; by using this routine different 393 machines will usually generate the same output. 394 */ 395 PetscErrorCode SNESMonitorDefaultShort(SNES snes,PetscInt its,PetscReal fgnorm,void *dummy) 396 { 397 PetscErrorCode ierr; 398 PetscViewer viewer = dummy ? (PetscViewer) dummy : PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm); 399 400 PetscFunctionBegin; 401 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 402 if (fgnorm > 1.e-9) { 403 ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %G \n",its,fgnorm);CHKERRQ(ierr); 404 } else if (fgnorm > 1.e-11) { 405 ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm %5.3e \n",its,fgnorm);CHKERRQ(ierr); 406 } else { 407 ierr = PetscViewerASCIIPrintf(viewer,"%3D SNES Function norm < 1.e-11\n",its);CHKERRQ(ierr); 408 } 409 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 410 PetscFunctionReturn(0); 411 } 412 /* ---------------------------------------------------------------- */ 413 #undef __FUNCT__ 414 #define __FUNCT__ "SNESDefaultConverged" 415 /*@C 416 SNESDefaultConverged - Convergence test of the solvers for 417 systems of nonlinear equations (default). 418 419 Collective on SNES 420 421 Input Parameters: 422 + snes - the SNES context 423 . it - the iteration (0 indicates before any Newton steps) 424 . xnorm - 2-norm of current iterate 425 . snorm - 2-norm of current step 426 . fnorm - 2-norm of function at current iterate 427 - dummy - unused context 428 429 Output Parameter: 430 . reason - one of 431 $ SNES_CONVERGED_FNORM_ABS - (fnorm < abstol), 432 $ SNES_CONVERGED_SNORM_RELATIVE - (snorm < stol*xnorm), 433 $ SNES_CONVERGED_FNORM_RELATIVE - (fnorm < rtol*fnorm0), 434 $ SNES_DIVERGED_FUNCTION_COUNT - (nfct > maxf), 435 $ SNES_DIVERGED_FNORM_NAN - (fnorm == NaN), 436 $ SNES_CONVERGED_ITERATING - (otherwise), 437 438 where 439 + maxf - maximum number of function evaluations, 440 set with SNESSetTolerances() 441 . nfct - number of function evaluations, 442 . abstol - absolute function norm tolerance, 443 set with SNESSetTolerances() 444 - rtol - relative function norm tolerance, set with SNESSetTolerances() 445 446 Level: intermediate 447 448 .keywords: SNES, nonlinear, default, converged, convergence 449 450 .seealso: SNESSetConvergenceTest() 451 @*/ 452 PetscErrorCode SNESDefaultConverged(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy) 453 { 454 PetscErrorCode ierr; 455 456 PetscFunctionBegin; 457 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 458 PetscValidPointer(reason,6); 459 460 *reason = SNES_CONVERGED_ITERATING; 461 462 if (!it) { 463 /* set parameter for default relative tolerance convergence test */ 464 snes->ttol = fnorm*snes->rtol; 465 } 466 if (PetscIsInfOrNanReal(fnorm)) { 467 ierr = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr); 468 *reason = SNES_DIVERGED_FNORM_NAN; 469 } else if (fnorm < snes->abstol) { 470 ierr = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e\n",(double)fnorm,(double)snes->abstol);CHKERRQ(ierr); 471 *reason = SNES_CONVERGED_FNORM_ABS; 472 } else if (snes->nfuncs >= snes->max_funcs) { 473 ierr = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRQ(ierr); 474 *reason = SNES_DIVERGED_FUNCTION_COUNT; 475 } 476 477 if (it && !*reason) { 478 if (fnorm <= snes->ttol) { 479 ierr = PetscInfo2(snes,"Converged due to function norm %14.12e < %14.12e (relative tolerance)\n",(double)fnorm,(double)snes->ttol);CHKERRQ(ierr); 480 *reason = SNES_CONVERGED_FNORM_RELATIVE; 481 } else if (snorm < snes->stol*xnorm) { 482 ierr = PetscInfo3(snes,"Converged due to small update length: %14.12e < %14.12e * %14.12e\n",(double)snorm,(double)snes->stol,(double)xnorm);CHKERRQ(ierr); 483 *reason = SNES_CONVERGED_SNORM_RELATIVE; 484 } 485 } 486 PetscFunctionReturn(0); 487 } 488 489 #undef __FUNCT__ 490 #define __FUNCT__ "SNESSkipConverged" 491 /*@C 492 SNESSkipConverged - Convergence test for SNES that NEVER returns as 493 converged, UNLESS the maximum number of iteration have been reached. 494 495 Logically Collective on SNES 496 497 Input Parameters: 498 + snes - the SNES context 499 . it - the iteration (0 indicates before any Newton steps) 500 . xnorm - 2-norm of current iterate 501 . snorm - 2-norm of current step 502 . fnorm - 2-norm of function at current iterate 503 - dummy - unused context 504 505 Output Parameter: 506 . reason - SNES_CONVERGED_ITERATING, SNES_CONVERGED_ITS, or SNES_DIVERGED_FNORM_NAN 507 508 Notes: 509 Convergence is then declared after a fixed number of iterations have been used. 510 511 Level: advanced 512 513 .keywords: SNES, nonlinear, skip, converged, convergence 514 515 .seealso: SNESSetConvergenceTest() 516 @*/ 517 PetscErrorCode SNESSkipConverged(SNES snes,PetscInt it,PetscReal xnorm,PetscReal snorm,PetscReal fnorm,SNESConvergedReason *reason,void *dummy) 518 { 519 PetscErrorCode ierr; 520 521 PetscFunctionBegin; 522 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 523 PetscValidPointer(reason,6); 524 525 *reason = SNES_CONVERGED_ITERATING; 526 527 if (fnorm != fnorm) { 528 ierr = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRQ(ierr); 529 *reason = SNES_DIVERGED_FNORM_NAN; 530 } else if (it == snes->max_its) { 531 *reason = SNES_CONVERGED_ITS; 532 } 533 PetscFunctionReturn(0); 534 } 535 536 #undef __FUNCT__ 537 #define __FUNCT__ "SNESDefaultGetWork" 538 /*@ 539 SNESDefaultGetWork - Gets a number of work vectors. 540 541 Input Parameters: 542 . snes - the SNES context 543 . nw - number of work vectors to allocate 544 545 Level: developer 546 547 Notes: 548 Call this only if no work vectors have been allocated 549 @*/ 550 PetscErrorCode SNESDefaultGetWork(SNES snes,PetscInt nw) 551 { 552 PetscErrorCode ierr; 553 554 PetscFunctionBegin; 555 if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);} 556 snes->nwork = nw; 557 ierr = VecDuplicateVecs(snes->vec_sol,snes->nwork,&snes->work);CHKERRQ(ierr); 558 ierr = PetscLogObjectParents(snes,nw,snes->work);CHKERRQ(ierr); 559 PetscFunctionReturn(0); 560 } 561