1 #include <petsc/private/snesimpl.h> /*I "petscsnes.h" I*/ 2 #include <petscdmshell.h> 3 #include <petscdraw.h> 4 #include <petscds.h> 5 #include <petscdmadaptor.h> 6 #include <petscconvest.h> 7 8 PetscBool SNESRegisterAllCalled = PETSC_FALSE; 9 PetscFunctionList SNESList = NULL; 10 11 /* Logging support */ 12 PetscClassId SNES_CLASSID, DMSNES_CLASSID; 13 PetscLogEvent SNES_Solve, SNES_Setup, SNES_FunctionEval, SNES_JacobianEval, SNES_NGSEval, SNES_NGSFuncEval, SNES_NPCSolve, SNES_ObjectiveEval; 14 15 /*@ 16 SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged. 17 18 Logically Collective on SNES 19 20 Input Parameters: 21 + snes - iterative context obtained from SNESCreate() 22 - flg - PETSC_TRUE indicates you want the error generated 23 24 Options database keys: 25 . -snes_error_if_not_converged <true,false> - cause an immediate error condition and stop the program if the solver does not converge 26 27 Level: intermediate 28 29 Notes: 30 Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve() 31 to determine if it has converged. 32 33 .seealso: `SNESGetErrorIfNotConverged()`, `KSPGetErrorIfNotConverged()`, `KSPSetErrorIfNotConverged()` 34 @*/ 35 PetscErrorCode SNESSetErrorIfNotConverged(SNES snes,PetscBool flg) 36 { 37 PetscFunctionBegin; 38 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 39 PetscValidLogicalCollectiveBool(snes,flg,2); 40 snes->errorifnotconverged = flg; 41 PetscFunctionReturn(0); 42 } 43 44 /*@ 45 SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge? 46 47 Not Collective 48 49 Input Parameter: 50 . snes - iterative context obtained from SNESCreate() 51 52 Output Parameter: 53 . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE 54 55 Level: intermediate 56 57 .seealso: `SNESSetErrorIfNotConverged()`, `KSPGetErrorIfNotConverged()`, `KSPSetErrorIfNotConverged()` 58 @*/ 59 PetscErrorCode SNESGetErrorIfNotConverged(SNES snes,PetscBool *flag) 60 { 61 PetscFunctionBegin; 62 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 63 PetscValidBoolPointer(flag,2); 64 *flag = snes->errorifnotconverged; 65 PetscFunctionReturn(0); 66 } 67 68 /*@ 69 SNESSetAlwaysComputesFinalResidual - does the SNES always compute the residual at the final solution? 70 71 Logically Collective on SNES 72 73 Input Parameters: 74 + snes - the shell SNES 75 - flg - is the residual computed? 76 77 Level: advanced 78 79 .seealso: `SNESGetAlwaysComputesFinalResidual()` 80 @*/ 81 PetscErrorCode SNESSetAlwaysComputesFinalResidual(SNES snes, PetscBool flg) 82 { 83 PetscFunctionBegin; 84 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 85 snes->alwayscomputesfinalresidual = flg; 86 PetscFunctionReturn(0); 87 } 88 89 /*@ 90 SNESGetAlwaysComputesFinalResidual - does the SNES always compute the residual at the final solution? 91 92 Logically Collective on SNES 93 94 Input Parameter: 95 . snes - the shell SNES 96 97 Output Parameter: 98 . flg - is the residual computed? 99 100 Level: advanced 101 102 .seealso: `SNESSetAlwaysComputesFinalResidual()` 103 @*/ 104 PetscErrorCode SNESGetAlwaysComputesFinalResidual(SNES snes, PetscBool *flg) 105 { 106 PetscFunctionBegin; 107 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 108 *flg = snes->alwayscomputesfinalresidual; 109 PetscFunctionReturn(0); 110 } 111 112 /*@ 113 SNESSetFunctionDomainError - tells SNES that the input vector to your SNESFunction is not 114 in the functions domain. For example, a step with negative pressure. 115 116 Logically Collective on SNES 117 118 Input Parameters: 119 . snes - the SNES context 120 121 Level: advanced 122 123 Note: 124 You can direct `SNES` to avoid certain steps by using `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()` or 125 `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 126 127 .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction`, `SNESSetJacobianDomainError()`, `SNESVISetVariableBounds()`, 128 `SNESVISetComputeVariableBounds()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 129 @*/ 130 PetscErrorCode SNESSetFunctionDomainError(SNES snes) 131 { 132 PetscFunctionBegin; 133 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 134 PetscCheck(!snes->errorifnotconverged,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"User code indicates input vector is not in the function domain"); 135 snes->domainerror = PETSC_TRUE; 136 PetscFunctionReturn(0); 137 } 138 139 /*@ 140 SNESSetJacobianDomainError - tells SNES that computeJacobian does not make sense at the proposed step. For example there is a negative element transformation. 141 142 Logically Collective on SNES 143 144 Input Parameters: 145 . snes - the SNES context 146 147 Level: advanced 148 149 Note: 150 You can direct `SNES` to avoid certain steps by using `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()` or 151 `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 152 153 .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESVISetVariableBounds()`, 154 `SNESVISetComputeVariableBounds()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 155 @*/ 156 PetscErrorCode SNESSetJacobianDomainError(SNES snes) 157 { 158 PetscFunctionBegin; 159 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 160 PetscCheck(!snes->errorifnotconverged,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"User code indicates computeJacobian does not make sense"); 161 snes->jacobiandomainerror = PETSC_TRUE; 162 PetscFunctionReturn(0); 163 } 164 165 /*@ 166 SNESSetCheckJacobianDomainError - if or not to check jacobian domain error after each Jacobian evaluation. By default, we check Jacobian domain error 167 in the debug mode, and do not check it in the optimized mode. 168 169 Logically Collective on SNES 170 171 Input Parameters: 172 + snes - the SNES context 173 - flg - indicates if or not to check jacobian domain error after each Jacobian evaluation 174 175 Level: advanced 176 177 .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESGetCheckJacobianDomainError()` 178 @*/ 179 PetscErrorCode SNESSetCheckJacobianDomainError(SNES snes, PetscBool flg) 180 { 181 PetscFunctionBegin; 182 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 183 snes->checkjacdomainerror = flg; 184 PetscFunctionReturn(0); 185 } 186 187 /*@ 188 SNESGetCheckJacobianDomainError - Get an indicator whether or not we are checking Jacobian domain errors after each Jacobian evaluation. 189 190 Logically Collective on SNES 191 192 Input Parameters: 193 . snes - the SNES context 194 195 Output Parameters: 196 . flg - PETSC_FALSE indicates that we don't check jacobian domain errors after each Jacobian evaluation 197 198 Level: advanced 199 200 .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESSetCheckJacobianDomainError()` 201 @*/ 202 PetscErrorCode SNESGetCheckJacobianDomainError(SNES snes, PetscBool *flg) 203 { 204 PetscFunctionBegin; 205 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 206 PetscValidBoolPointer(flg,2); 207 *flg = snes->checkjacdomainerror; 208 PetscFunctionReturn(0); 209 } 210 211 /*@ 212 SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction; 213 214 Logically Collective on SNES 215 216 Input Parameters: 217 . snes - the SNES context 218 219 Output Parameters: 220 . domainerror - Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise. 221 222 Level: advanced 223 224 .seealso: `SNESSetFunctionDomainError()`, `SNESComputeFunction()` 225 @*/ 226 PetscErrorCode SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror) 227 { 228 PetscFunctionBegin; 229 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 230 PetscValidBoolPointer(domainerror,2); 231 *domainerror = snes->domainerror; 232 PetscFunctionReturn(0); 233 } 234 235 /*@ 236 SNESGetJacobianDomainError - Gets the status of the Jacobian domain error after a call to SNESComputeJacobian; 237 238 Logically Collective on SNES 239 240 Input Parameters: 241 . snes - the SNES context 242 243 Output Parameters: 244 . domainerror - Set to PETSC_TRUE if there's a jacobian domain error; PETSC_FALSE otherwise. 245 246 Level: advanced 247 248 .seealso: `SNESSetFunctionDomainError()`, `SNESComputeFunction()`, `SNESGetFunctionDomainError()` 249 @*/ 250 PetscErrorCode SNESGetJacobianDomainError(SNES snes, PetscBool *domainerror) 251 { 252 PetscFunctionBegin; 253 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 254 PetscValidBoolPointer(domainerror,2); 255 *domainerror = snes->jacobiandomainerror; 256 PetscFunctionReturn(0); 257 } 258 259 /*@C 260 SNESLoad - Loads a SNES that has been stored in binary with SNESView(). 261 262 Collective on PetscViewer 263 264 Input Parameters: 265 + newdm - the newly loaded SNES, this needs to have been created with SNESCreate() or 266 some related function before a call to SNESLoad(). 267 - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() 268 269 Level: intermediate 270 271 Notes: 272 The type is determined by the data in the file, any type set into the SNES before this call is ignored. 273 274 Notes for advanced users: 275 Most users should not need to know the details of the binary storage 276 format, since SNESLoad() and TSView() completely hide these details. 277 But for anyone who's interested, the standard binary matrix storage 278 format is 279 .vb 280 has not yet been determined 281 .ve 282 283 .seealso: `PetscViewerBinaryOpen()`, `SNESView()`, `MatLoad()`, `VecLoad()` 284 @*/ 285 PetscErrorCode SNESLoad(SNES snes, PetscViewer viewer) 286 { 287 PetscBool isbinary; 288 PetscInt classid; 289 char type[256]; 290 KSP ksp; 291 DM dm; 292 DMSNES dmsnes; 293 294 PetscFunctionBegin; 295 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 296 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 297 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary)); 298 PetscCheck(isbinary,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()"); 299 300 PetscCall(PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT)); 301 PetscCheck(classid == SNES_FILE_CLASSID,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONG,"Not SNES next in file"); 302 PetscCall(PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR)); 303 PetscCall(SNESSetType(snes, type)); 304 if (snes->ops->load) PetscCall((*snes->ops->load)(snes,viewer)); 305 PetscCall(SNESGetDM(snes,&dm)); 306 PetscCall(DMGetDMSNES(dm,&dmsnes)); 307 PetscCall(DMSNESLoad(dmsnes,viewer)); 308 PetscCall(SNESGetKSP(snes,&ksp)); 309 PetscCall(KSPLoad(ksp,viewer)); 310 PetscFunctionReturn(0); 311 } 312 313 #include <petscdraw.h> 314 #if defined(PETSC_HAVE_SAWS) 315 #include <petscviewersaws.h> 316 #endif 317 318 /*@C 319 SNESViewFromOptions - View from Options 320 321 Collective on SNES 322 323 Input Parameters: 324 + A - the application ordering context 325 . obj - Optional object 326 - name - command line option 327 328 Level: intermediate 329 .seealso: `SNES`, `SNESView`, `PetscObjectViewFromOptions()`, `SNESCreate()` 330 @*/ 331 PetscErrorCode SNESViewFromOptions(SNES A,PetscObject obj,const char name[]) 332 { 333 PetscFunctionBegin; 334 PetscValidHeaderSpecific(A,SNES_CLASSID,1); 335 PetscCall(PetscObjectViewFromOptions((PetscObject)A,obj,name)); 336 PetscFunctionReturn(0); 337 } 338 339 PETSC_EXTERN PetscErrorCode SNESComputeJacobian_DMDA(SNES,Vec,Mat,Mat,void*); 340 341 /*@C 342 SNESView - Prints the SNES data structure. 343 344 Collective on SNES 345 346 Input Parameters: 347 + SNES - the SNES context 348 - viewer - visualization context 349 350 Options Database Key: 351 . -snes_view - Calls SNESView() at end of SNESSolve() 352 353 Notes: 354 The available visualization contexts include 355 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 356 - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 357 output where only the first processor opens 358 the file. All other processors send their 359 data to the first processor to print. 360 361 The available formats include 362 + PETSC_VIEWER_DEFAULT - standard output (default) 363 - PETSC_VIEWER_ASCII_INFO_DETAIL - more verbose output for SNESNASM 364 365 The user can open an alternative visualization context with 366 PetscViewerASCIIOpen() - output to a specified file. 367 368 In the debugger you can do "call SNESView(snes,0)" to display the SNES solver. (The same holds for any PETSc object viewer). 369 370 Level: beginner 371 372 .seealso: `PetscViewerASCIIOpen()` 373 @*/ 374 PetscErrorCode SNESView(SNES snes,PetscViewer viewer) 375 { 376 SNESKSPEW *kctx; 377 KSP ksp; 378 SNESLineSearch linesearch; 379 PetscBool iascii,isstring,isbinary,isdraw; 380 DMSNES dmsnes; 381 #if defined(PETSC_HAVE_SAWS) 382 PetscBool issaws; 383 #endif 384 385 PetscFunctionBegin; 386 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 387 if (!viewer) { 388 PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&viewer)); 389 } 390 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 391 PetscCheckSameComm(snes,1,viewer,2); 392 393 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 394 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring)); 395 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary)); 396 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw)); 397 #if defined(PETSC_HAVE_SAWS) 398 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws)); 399 #endif 400 if (iascii) { 401 SNESNormSchedule normschedule; 402 DM dm; 403 PetscErrorCode (*cJ)(SNES,Vec,Mat,Mat,void*); 404 void *ctx; 405 const char *pre = ""; 406 407 PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer)); 408 if (!snes->setupcalled) { 409 PetscCall(PetscViewerASCIIPrintf(viewer," SNES has not been set up so information may be incomplete\n")); 410 } 411 if (snes->ops->view) { 412 PetscCall(PetscViewerASCIIPushTab(viewer)); 413 PetscCall((*snes->ops->view)(snes,viewer)); 414 PetscCall(PetscViewerASCIIPopTab(viewer)); 415 } 416 PetscCall(PetscViewerASCIIPrintf(viewer," maximum iterations=%" PetscInt_FMT ", maximum function evaluations=%" PetscInt_FMT "\n",snes->max_its,snes->max_funcs)); 417 PetscCall(PetscViewerASCIIPrintf(viewer," tolerances: relative=%g, absolute=%g, solution=%g\n",(double)snes->rtol,(double)snes->abstol,(double)snes->stol)); 418 if (snes->usesksp) { 419 PetscCall(PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%" PetscInt_FMT "\n",snes->linear_its)); 420 } 421 PetscCall(PetscViewerASCIIPrintf(viewer," total number of function evaluations=%" PetscInt_FMT "\n",snes->nfuncs)); 422 PetscCall(SNESGetNormSchedule(snes, &normschedule)); 423 if (normschedule > 0) PetscCall(PetscViewerASCIIPrintf(viewer," norm schedule %s\n",SNESNormSchedules[normschedule])); 424 if (snes->gridsequence) { 425 PetscCall(PetscViewerASCIIPrintf(viewer," total number of grid sequence refinements=%" PetscInt_FMT "\n",snes->gridsequence)); 426 } 427 if (snes->ksp_ewconv) { 428 kctx = (SNESKSPEW*)snes->kspconvctx; 429 if (kctx) { 430 PetscCall(PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %" PetscInt_FMT ")\n",kctx->version)); 431 PetscCall(PetscViewerASCIIPrintf(viewer," rtol_0=%g, rtol_max=%g, threshold=%g\n",(double)kctx->rtol_0,(double)kctx->rtol_max,(double)kctx->threshold)); 432 PetscCall(PetscViewerASCIIPrintf(viewer," gamma=%g, alpha=%g, alpha2=%g\n",(double)kctx->gamma,(double)kctx->alpha,(double)kctx->alpha2)); 433 } 434 } 435 if (snes->lagpreconditioner == -1) { 436 PetscCall(PetscViewerASCIIPrintf(viewer," Preconditioned is never rebuilt\n")); 437 } else if (snes->lagpreconditioner > 1) { 438 PetscCall(PetscViewerASCIIPrintf(viewer," Preconditioned is rebuilt every %" PetscInt_FMT " new Jacobians\n",snes->lagpreconditioner)); 439 } 440 if (snes->lagjacobian == -1) { 441 PetscCall(PetscViewerASCIIPrintf(viewer," Jacobian is never rebuilt\n")); 442 } else if (snes->lagjacobian > 1) { 443 PetscCall(PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %" PetscInt_FMT " SNES iterations\n",snes->lagjacobian)); 444 } 445 PetscCall(SNESGetDM(snes,&dm)); 446 PetscCall(DMSNESGetJacobian(dm,&cJ,&ctx)); 447 if (snes->mf_operator) { 448 PetscCall(PetscViewerASCIIPrintf(viewer," Jacobian is applied matrix-free with differencing\n")); 449 pre = "Preconditioning "; 450 } 451 if (cJ == SNESComputeJacobianDefault) { 452 PetscCall(PetscViewerASCIIPrintf(viewer," %sJacobian is built using finite differences one column at a time\n",pre)); 453 } else if (cJ == SNESComputeJacobianDefaultColor) { 454 PetscCall(PetscViewerASCIIPrintf(viewer," %sJacobian is built using finite differences with coloring\n",pre)); 455 /* it slightly breaks data encapsulation for access the DMDA information directly */ 456 } else if (cJ == SNESComputeJacobian_DMDA) { 457 MatFDColoring fdcoloring; 458 PetscCall(PetscObjectQuery((PetscObject)dm,"DMDASNES_FDCOLORING",(PetscObject*)&fdcoloring)); 459 if (fdcoloring) { 460 PetscCall(PetscViewerASCIIPrintf(viewer," %sJacobian is built using colored finite differences on a DMDA\n",pre)); 461 } else { 462 PetscCall(PetscViewerASCIIPrintf(viewer," %sJacobian is built using a DMDA local Jacobian\n",pre)); 463 } 464 } else if (snes->mf) { 465 PetscCall(PetscViewerASCIIPrintf(viewer," Jacobian is applied matrix-free with differencing, no explicit Jacobian\n")); 466 } 467 } else if (isstring) { 468 const char *type; 469 PetscCall(SNESGetType(snes,&type)); 470 PetscCall(PetscViewerStringSPrintf(viewer," SNESType: %-7.7s",type)); 471 if (snes->ops->view) PetscCall((*snes->ops->view)(snes,viewer)); 472 } else if (isbinary) { 473 PetscInt classid = SNES_FILE_CLASSID; 474 MPI_Comm comm; 475 PetscMPIInt rank; 476 char type[256]; 477 478 PetscCall(PetscObjectGetComm((PetscObject)snes,&comm)); 479 PetscCallMPI(MPI_Comm_rank(comm,&rank)); 480 if (rank == 0) { 481 PetscCall(PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT)); 482 PetscCall(PetscStrncpy(type,((PetscObject)snes)->type_name,sizeof(type))); 483 PetscCall(PetscViewerBinaryWrite(viewer,type,sizeof(type),PETSC_CHAR)); 484 } 485 if (snes->ops->view) PetscCall((*snes->ops->view)(snes,viewer)); 486 } else if (isdraw) { 487 PetscDraw draw; 488 char str[36]; 489 PetscReal x,y,bottom,h; 490 491 PetscCall(PetscViewerDrawGetDraw(viewer,0,&draw)); 492 PetscCall(PetscDrawGetCurrentPoint(draw,&x,&y)); 493 PetscCall(PetscStrncpy(str,"SNES: ",sizeof(str))); 494 PetscCall(PetscStrlcat(str,((PetscObject)snes)->type_name,sizeof(str))); 495 PetscCall(PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLUE,PETSC_DRAW_BLACK,str,NULL,&h)); 496 bottom = y - h; 497 PetscCall(PetscDrawPushCurrentPoint(draw,x,bottom)); 498 if (snes->ops->view) PetscCall((*snes->ops->view)(snes,viewer)); 499 #if defined(PETSC_HAVE_SAWS) 500 } else if (issaws) { 501 PetscMPIInt rank; 502 const char *name; 503 504 PetscCall(PetscObjectGetName((PetscObject)snes,&name)); 505 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank)); 506 if (!((PetscObject)snes)->amsmem && rank == 0) { 507 char dir[1024]; 508 509 PetscCall(PetscObjectViewSAWs((PetscObject)snes,viewer)); 510 PetscCall(PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/its",name)); 511 PetscStackCallSAWs(SAWs_Register,(dir,&snes->iter,1,SAWs_READ,SAWs_INT)); 512 if (!snes->conv_hist) { 513 PetscCall(SNESSetConvergenceHistory(snes,NULL,NULL,PETSC_DECIDE,PETSC_TRUE)); 514 } 515 PetscCall(PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/conv_hist",name)); 516 PetscStackCallSAWs(SAWs_Register,(dir,snes->conv_hist,10,SAWs_READ,SAWs_DOUBLE)); 517 } 518 #endif 519 } 520 if (snes->linesearch) { 521 PetscCall(SNESGetLineSearch(snes, &linesearch)); 522 PetscCall(PetscViewerASCIIPushTab(viewer)); 523 PetscCall(SNESLineSearchView(linesearch, viewer)); 524 PetscCall(PetscViewerASCIIPopTab(viewer)); 525 } 526 if (snes->npc && snes->usesnpc) { 527 PetscCall(PetscViewerASCIIPushTab(viewer)); 528 PetscCall(SNESView(snes->npc, viewer)); 529 PetscCall(PetscViewerASCIIPopTab(viewer)); 530 } 531 PetscCall(PetscViewerASCIIPushTab(viewer)); 532 PetscCall(DMGetDMSNES(snes->dm,&dmsnes)); 533 PetscCall(DMSNESView(dmsnes, viewer)); 534 PetscCall(PetscViewerASCIIPopTab(viewer)); 535 if (snes->usesksp) { 536 PetscCall(SNESGetKSP(snes,&ksp)); 537 PetscCall(PetscViewerASCIIPushTab(viewer)); 538 PetscCall(KSPView(ksp,viewer)); 539 PetscCall(PetscViewerASCIIPopTab(viewer)); 540 } 541 if (isdraw) { 542 PetscDraw draw; 543 PetscCall(PetscViewerDrawGetDraw(viewer,0,&draw)); 544 PetscCall(PetscDrawPopCurrentPoint(draw)); 545 } 546 PetscFunctionReturn(0); 547 } 548 549 /* 550 We retain a list of functions that also take SNES command 551 line options. These are called at the end SNESSetFromOptions() 552 */ 553 #define MAXSETFROMOPTIONS 5 554 static PetscInt numberofsetfromoptions; 555 static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 556 557 /*@C 558 SNESAddOptionsChecker - Adds an additional function to check for SNES options. 559 560 Not Collective 561 562 Input Parameter: 563 . snescheck - function that checks for options 564 565 Level: developer 566 567 .seealso: `SNESSetFromOptions()` 568 @*/ 569 PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 570 { 571 PetscFunctionBegin; 572 PetscCheck(numberofsetfromoptions < MAXSETFROMOPTIONS,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %d allowed", MAXSETFROMOPTIONS); 573 othersetfromoptions[numberofsetfromoptions++] = snescheck; 574 PetscFunctionReturn(0); 575 } 576 577 PETSC_INTERN PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 578 579 static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 580 { 581 Mat J; 582 MatNullSpace nullsp; 583 584 PetscFunctionBegin; 585 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 586 587 if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 588 Mat A = snes->jacobian, B = snes->jacobian_pre; 589 PetscCall(MatCreateVecs(A ? A : B, NULL,&snes->vec_func)); 590 } 591 592 if (version == 1) { 593 PetscCall(MatCreateSNESMF(snes,&J)); 594 PetscCall(MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix)); 595 PetscCall(MatSetFromOptions(J)); 596 /* TODO: the version 2 code should be merged into the MatCreateSNESMF() and MatCreateMFFD() infrastructure and then removed */ 597 } else if (version == 2) { 598 PetscCheck(snes->vec_func,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 599 #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL___FP16) 600 PetscCall(SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J)); 601 #else 602 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator routines (version 2)"); 603 #endif 604 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator routines, only version 1 and 2"); 605 606 /* attach any user provided null space that was on Amat to the newly created matrix free matrix */ 607 if (snes->jacobian) { 608 PetscCall(MatGetNullSpace(snes->jacobian,&nullsp)); 609 if (nullsp) PetscCall(MatSetNullSpace(J,nullsp)); 610 } 611 612 PetscCall(PetscInfo(snes,"Setting default matrix-free operator routines (version %" PetscInt_FMT ")\n", version)); 613 if (hasOperator) { 614 615 /* This version replaces the user provided Jacobian matrix with a 616 matrix-free version but still employs the user-provided preconditioner matrix. */ 617 PetscCall(SNESSetJacobian(snes,J,NULL,NULL,NULL)); 618 } else { 619 /* This version replaces both the user-provided Jacobian and the user- 620 provided preconditioner Jacobian with the default matrix free version. */ 621 if (snes->npcside == PC_LEFT && snes->npc) { 622 if (!snes->jacobian) PetscCall(SNESSetJacobian(snes,J,NULL,NULL,NULL)); 623 } else { 624 KSP ksp; 625 PC pc; 626 PetscBool match; 627 628 PetscCall(SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,NULL)); 629 /* Force no preconditioner */ 630 PetscCall(SNESGetKSP(snes,&ksp)); 631 PetscCall(KSPGetPC(ksp,&pc)); 632 PetscCall(PetscObjectTypeCompareAny((PetscObject)pc,&match,PCSHELL,PCH2OPUS,"")); 633 if (!match) { 634 PetscCall(PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n")); 635 PetscCall(PCSetType(pc,PCNONE)); 636 } 637 } 638 } 639 PetscCall(MatDestroy(&J)); 640 PetscFunctionReturn(0); 641 } 642 643 static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx) 644 { 645 SNES snes = (SNES)ctx; 646 Vec Xfine,Xfine_named = NULL,Xcoarse; 647 648 PetscFunctionBegin; 649 if (PetscLogPrintInfo) { 650 PetscInt finelevel,coarselevel,fineclevel,coarseclevel; 651 PetscCall(DMGetRefineLevel(dmfine,&finelevel)); 652 PetscCall(DMGetCoarsenLevel(dmfine,&fineclevel)); 653 PetscCall(DMGetRefineLevel(dmcoarse,&coarselevel)); 654 PetscCall(DMGetCoarsenLevel(dmcoarse,&coarseclevel)); 655 PetscCall(PetscInfo(dmfine,"Restricting SNES solution vector from level %" PetscInt_FMT "-%" PetscInt_FMT " to level %" PetscInt_FMT "-%" PetscInt_FMT "\n",finelevel,fineclevel,coarselevel,coarseclevel)); 656 } 657 if (dmfine == snes->dm) Xfine = snes->vec_sol; 658 else { 659 PetscCall(DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named)); 660 Xfine = Xfine_named; 661 } 662 PetscCall(DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse)); 663 if (Inject) { 664 PetscCall(MatRestrict(Inject,Xfine,Xcoarse)); 665 } else { 666 PetscCall(MatRestrict(Restrict,Xfine,Xcoarse)); 667 PetscCall(VecPointwiseMult(Xcoarse,Xcoarse,Rscale)); 668 } 669 PetscCall(DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse)); 670 if (Xfine_named) PetscCall(DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named)); 671 PetscFunctionReturn(0); 672 } 673 674 static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm,DM dmc,void *ctx) 675 { 676 PetscFunctionBegin; 677 PetscCall(DMCoarsenHookAdd(dmc,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,ctx)); 678 PetscFunctionReturn(0); 679 } 680 681 /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can 682 * safely call SNESGetDM() in their residual evaluation routine. */ 683 static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,void *ctx) 684 { 685 SNES snes = (SNES)ctx; 686 Vec X,Xnamed = NULL; 687 DM dmsave; 688 void *ctxsave; 689 PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*) = NULL; 690 691 PetscFunctionBegin; 692 dmsave = snes->dm; 693 PetscCall(KSPGetDM(ksp,&snes->dm)); 694 if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */ 695 else { /* We are on a coarser level, this vec was initialized using a DM restrict hook */ 696 PetscCall(DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed)); 697 X = Xnamed; 698 PetscCall(SNESGetJacobian(snes,NULL,NULL,&jac,&ctxsave)); 699 /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */ 700 if (jac == SNESComputeJacobianDefaultColor) { 701 PetscCall(SNESSetJacobian(snes,NULL,NULL,SNESComputeJacobianDefaultColor,NULL)); 702 } 703 } 704 /* Make sure KSP DM has the Jacobian computation routine */ 705 { 706 DMSNES sdm; 707 708 PetscCall(DMGetDMSNES(snes->dm, &sdm)); 709 if (!sdm->ops->computejacobian) { 710 PetscCall(DMCopyDMSNES(dmsave, snes->dm)); 711 } 712 } 713 /* Compute the operators */ 714 PetscCall(SNESComputeJacobian(snes,X,A,B)); 715 /* Put the previous context back */ 716 if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) { 717 PetscCall(SNESSetJacobian(snes,NULL,NULL,jac,ctxsave)); 718 } 719 720 if (Xnamed) PetscCall(DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed)); 721 snes->dm = dmsave; 722 PetscFunctionReturn(0); 723 } 724 725 /*@ 726 SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX() 727 728 Collective 729 730 Input Parameter: 731 . snes - snes to configure 732 733 Level: developer 734 735 .seealso: `SNESSetUp()` 736 @*/ 737 PetscErrorCode SNESSetUpMatrices(SNES snes) 738 { 739 DM dm; 740 DMSNES sdm; 741 742 PetscFunctionBegin; 743 PetscCall(SNESGetDM(snes,&dm)); 744 PetscCall(DMGetDMSNES(dm,&sdm)); 745 if (!snes->jacobian && snes->mf) { 746 Mat J; 747 void *functx; 748 PetscCall(MatCreateSNESMF(snes,&J)); 749 PetscCall(MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix)); 750 PetscCall(MatSetFromOptions(J)); 751 PetscCall(SNESGetFunction(snes,NULL,NULL,&functx)); 752 PetscCall(SNESSetJacobian(snes,J,J,NULL,NULL)); 753 PetscCall(MatDestroy(&J)); 754 } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 755 Mat J,B; 756 PetscCall(MatCreateSNESMF(snes,&J)); 757 PetscCall(MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix)); 758 PetscCall(MatSetFromOptions(J)); 759 PetscCall(DMCreateMatrix(snes->dm,&B)); 760 /* sdm->computejacobian was already set to reach here */ 761 PetscCall(SNESSetJacobian(snes,J,B,NULL,NULL)); 762 PetscCall(MatDestroy(&J)); 763 PetscCall(MatDestroy(&B)); 764 } else if (!snes->jacobian_pre) { 765 PetscDS prob; 766 Mat J, B; 767 PetscBool hasPrec = PETSC_FALSE; 768 769 J = snes->jacobian; 770 PetscCall(DMGetDS(dm, &prob)); 771 if (prob) PetscCall(PetscDSHasJacobianPreconditioner(prob, &hasPrec)); 772 if (J) PetscCall(PetscObjectReference((PetscObject) J)); 773 else if (hasPrec) PetscCall(DMCreateMatrix(snes->dm, &J)); 774 PetscCall(DMCreateMatrix(snes->dm, &B)); 775 PetscCall(SNESSetJacobian(snes, J ? J : B, B, NULL, NULL)); 776 PetscCall(MatDestroy(&J)); 777 PetscCall(MatDestroy(&B)); 778 } 779 { 780 KSP ksp; 781 PetscCall(SNESGetKSP(snes,&ksp)); 782 PetscCall(KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes)); 783 PetscCall(DMCoarsenHookAdd(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes)); 784 } 785 PetscFunctionReturn(0); 786 } 787 788 static PetscErrorCode SNESMonitorPauseFinal_Internal(SNES snes) 789 { 790 PetscInt i; 791 792 PetscFunctionBegin; 793 if (!snes->pauseFinal) PetscFunctionReturn(0); 794 for (i = 0; i < snes->numbermonitors; ++i) { 795 PetscViewerAndFormat *vf = (PetscViewerAndFormat *) snes->monitorcontext[i]; 796 PetscDraw draw; 797 PetscReal lpause; 798 799 if (!vf) continue; 800 if (vf->lg) { 801 if (!PetscCheckPointer(vf->lg, PETSC_OBJECT)) continue; 802 if (((PetscObject) vf->lg)->classid != PETSC_DRAWLG_CLASSID) continue; 803 PetscCall(PetscDrawLGGetDraw(vf->lg, &draw)); 804 PetscCall(PetscDrawGetPause(draw, &lpause)); 805 PetscCall(PetscDrawSetPause(draw, -1.0)); 806 PetscCall(PetscDrawPause(draw)); 807 PetscCall(PetscDrawSetPause(draw, lpause)); 808 } else { 809 PetscBool isdraw; 810 811 if (!PetscCheckPointer(vf->viewer, PETSC_OBJECT)) continue; 812 if (((PetscObject) vf->viewer)->classid != PETSC_VIEWER_CLASSID) continue; 813 PetscCall(PetscObjectTypeCompare((PetscObject) vf->viewer, PETSCVIEWERDRAW, &isdraw)); 814 if (!isdraw) continue; 815 PetscCall(PetscViewerDrawGetDraw(vf->viewer, 0, &draw)); 816 PetscCall(PetscDrawGetPause(draw, &lpause)); 817 PetscCall(PetscDrawSetPause(draw, -1.0)); 818 PetscCall(PetscDrawPause(draw)); 819 PetscCall(PetscDrawSetPause(draw, lpause)); 820 } 821 } 822 PetscFunctionReturn(0); 823 } 824 825 /*@C 826 SNESMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 827 828 Collective on SNES 829 830 Input Parameters: 831 + snes - SNES object you wish to monitor 832 . name - the monitor type one is seeking 833 . help - message indicating what monitoring is done 834 . manual - manual page for the monitor 835 . monitor - the monitor function 836 - monitorsetup - a function that is called once ONLY if the user selected this monitor that may set additional features of the SNES or PetscViewer objects 837 838 Level: developer 839 840 .seealso: `PetscOptionsGetViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, 841 `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()` 842 `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`, 843 `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, 844 `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`, 845 `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`, 846 `PetscOptionsFList()`, `PetscOptionsEList()` 847 @*/ 848 PetscErrorCode SNESMonitorSetFromOptions(SNES snes,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNES,PetscViewerAndFormat*)) 849 { 850 PetscViewer viewer; 851 PetscViewerFormat format; 852 PetscBool flg; 853 854 PetscFunctionBegin; 855 PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,name,&viewer,&format,&flg)); 856 if (flg) { 857 PetscViewerAndFormat *vf; 858 PetscCall(PetscViewerAndFormatCreate(viewer,format,&vf)); 859 PetscCall(PetscObjectDereference((PetscObject)viewer)); 860 if (monitorsetup) PetscCall((*monitorsetup)(snes,vf)); 861 PetscCall(SNESMonitorSet(snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy)); 862 } 863 PetscFunctionReturn(0); 864 } 865 866 PetscErrorCode SNESEWSetFromOptions_Private(SNESKSPEW* kctx, MPI_Comm comm, const char* prefix) 867 { 868 PetscFunctionBegin; 869 PetscOptionsBegin(comm,prefix,"Eisenstat and Walker type forcing options","KSP"); 870 PetscCall(PetscOptionsInt("-ksp_ew_version","Version 1, 2 or 3",NULL,kctx->version,&kctx->version,NULL)); 871 PetscCall(PetscOptionsReal("-ksp_ew_rtol0","0 <= rtol0 < 1",NULL,kctx->rtol_0,&kctx->rtol_0,NULL)); 872 PetscCall(PetscOptionsReal("-ksp_ew_rtolmax","0 <= rtolmax < 1",NULL,kctx->rtol_max,&kctx->rtol_max,NULL)); 873 PetscCall(PetscOptionsReal("-ksp_ew_gamma","0 <= gamma <= 1",NULL,kctx->gamma,&kctx->gamma,NULL)); 874 PetscCall(PetscOptionsReal("-ksp_ew_alpha","1 < alpha <= 2",NULL,kctx->alpha,&kctx->alpha,NULL)); 875 PetscCall(PetscOptionsReal("-ksp_ew_alpha2","alpha2",NULL,kctx->alpha2,&kctx->alpha2,NULL)); 876 PetscCall(PetscOptionsReal("-ksp_ew_threshold","0 < threshold < 1",NULL,kctx->threshold,&kctx->threshold,NULL)); 877 PetscCall(PetscOptionsReal("-ksp_ew_v4_p1","p1",NULL,kctx->v4_p1,&kctx->v4_p1,NULL)); 878 PetscCall(PetscOptionsReal("-ksp_ew_v4_p2","p2",NULL,kctx->v4_p2,&kctx->v4_p2,NULL)); 879 PetscCall(PetscOptionsReal("-ksp_ew_v4_p3","p3",NULL,kctx->v4_p3,&kctx->v4_p3,NULL)); 880 PetscCall(PetscOptionsReal("-ksp_ew_v4_m1","Scaling when rk-1 in [p2,p3)",NULL,kctx->v4_m1,&kctx->v4_m1,NULL)); 881 PetscCall(PetscOptionsReal("-ksp_ew_v4_m2","Scaling when rk-1 in [p3,+infty)",NULL,kctx->v4_m2,&kctx->v4_m2,NULL)); 882 PetscCall(PetscOptionsReal("-ksp_ew_v4_m3","Threshold for successive rtol (0.1 in Eq.7)",NULL,kctx->v4_m3,&kctx->v4_m3,NULL)); 883 PetscCall(PetscOptionsReal("-ksp_ew_v4_m4","Adaptation scaling (0.5 in Eq.7)",NULL,kctx->v4_m4,&kctx->v4_m4,NULL)); 884 PetscOptionsEnd(); 885 PetscFunctionReturn(0); 886 } 887 888 /*@ 889 SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 890 891 Collective on SNES 892 893 Input Parameter: 894 . snes - the SNES context 895 896 Options Database Keys: 897 + -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, SNESType for complete list 898 . -snes_stol - convergence tolerance in terms of the norm 899 of the change in the solution between steps 900 . -snes_atol <abstol> - absolute tolerance of residual norm 901 . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 902 . -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence 903 . -snes_force_iteration <force> - force SNESSolve() to take at least one iteration 904 . -snes_max_it <max_it> - maximum number of iterations 905 . -snes_max_funcs <max_funcs> - maximum number of function evaluations 906 . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 907 . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 908 . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 909 . -snes_lag_preconditioner_persists <true,false> - retains the -snes_lag_preconditioner information across multiple SNESSolve() 910 . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 911 . -snes_lag_jacobian_persists <true,false> - retains the -snes_lag_jacobian information across multiple SNESSolve() 912 . -snes_trtol <trtol> - trust region tolerance 913 . -snes_convergence_test - <default,skip,correct_pressure> convergence test in nonlinear solver. 914 default SNESConvergedDefault(). skip SNESConvergedSkip() means continue iterating until max_it or some other criterion is reached, saving expense 915 of convergence test. correct_pressure SNESConvergedCorrectPressure() has special handling of a pressure null space. 916 . -snes_monitor [ascii][:filename][:viewer format] - prints residual norm at each iteration. if no filename given prints to stdout 917 . -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration 918 . -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration 919 . -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration 920 . -snes_monitor_lg_residualnorm - plots residual norm at each iteration 921 . -snes_monitor_lg_range - plots residual norm at each iteration 922 . -snes_monitor_pause_final - Pauses all monitor drawing after the solver ends 923 . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 924 . -snes_fd_color - use finite differences with coloring to compute Jacobian 925 . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 926 . -snes_converged_reason - print the reason for convergence/divergence after each solve 927 . -npc_snes_type <type> - the SNES type to use as a nonlinear preconditioner 928 . -snes_test_jacobian <optional threshold> - compare the user provided Jacobian with one computed via finite differences to check for errors. If a threshold is given, display only those entries whose difference is greater than the threshold. 929 - -snes_test_jacobian_view - display the user provided Jacobian, the finite difference Jacobian and the difference between them to help users detect the location of errors in the user provided Jacobian. 930 931 Options Database for Eisenstat-Walker method: 932 + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 933 . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 934 . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 935 . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 936 . -snes_ksp_ew_gamma <gamma> - Sets gamma 937 . -snes_ksp_ew_alpha <alpha> - Sets alpha 938 . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 939 - -snes_ksp_ew_threshold <threshold> - Sets threshold 940 941 Notes: 942 To see all options, run your program with the -help option or consult the users manual 943 944 Notes: 945 SNES supports three approaches for computing (approximate) Jacobians: user provided via SNESSetJacobian(), matrix free, and computing explicitly with 946 finite differences and coloring using MatFDColoring. It is also possible to use automatic differentiation and the MatFDColoring object. 947 948 Level: beginner 949 950 .seealso: `SNESSetOptionsPrefix()`, `SNESResetFromOptions()`, `SNES`, `SNESCreate()` 951 @*/ 952 PetscErrorCode SNESSetFromOptions(SNES snes) 953 { 954 PetscBool flg,pcset,persist,set; 955 PetscInt i,indx,lag,grids; 956 const char *deft = SNESNEWTONLS; 957 const char *convtests[] = {"default","skip","correct_pressure"}; 958 SNESKSPEW *kctx = NULL; 959 char type[256], monfilename[PETSC_MAX_PATH_LEN], ewprefix[256]; 960 PCSide pcside; 961 const char *optionsprefix; 962 963 PetscFunctionBegin; 964 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 965 PetscCall(SNESRegisterAll()); 966 PetscObjectOptionsBegin((PetscObject)snes); 967 if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name; 968 PetscCall(PetscOptionsFList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg)); 969 if (flg) { 970 PetscCall(SNESSetType(snes,type)); 971 } else if (!((PetscObject)snes)->type_name) { 972 PetscCall(SNESSetType(snes,deft)); 973 } 974 PetscCall(PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,NULL)); 975 PetscCall(PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,NULL)); 976 977 PetscCall(PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,NULL)); 978 PetscCall(PetscOptionsReal("-snes_divergence_tolerance","Stop if residual norm increases by this factor","SNESSetDivergenceTolerance",snes->divtol,&snes->divtol,NULL)); 979 PetscCall(PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,NULL)); 980 PetscCall(PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,NULL)); 981 PetscCall(PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,NULL)); 982 PetscCall(PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,NULL)); 983 PetscCall(PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,NULL)); 984 PetscCall(PetscOptionsBool("-snes_force_iteration","Force SNESSolve() to take at least one iteration","SNESSetForceIteration",snes->forceiteration,&snes->forceiteration,NULL)); 985 PetscCall(PetscOptionsBool("-snes_check_jacobian_domain_error","Check Jacobian domain error after Jacobian evaluation","SNESCheckJacobianDomainError",snes->checkjacdomainerror,&snes->checkjacdomainerror,NULL)); 986 987 PetscCall(PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg)); 988 if (flg) { 989 PetscCheck(lag != -1,PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Cannot set the lag to -1 from the command line since the preconditioner must be built as least once, perhaps you mean -2"); 990 PetscCall(SNESSetLagPreconditioner(snes,lag)); 991 } 992 PetscCall(PetscOptionsBool("-snes_lag_preconditioner_persists","Preconditioner lagging through multiple SNES solves","SNESSetLagPreconditionerPersists",snes->lagjac_persist,&persist,&flg)); 993 if (flg) PetscCall(SNESSetLagPreconditionerPersists(snes,persist)); 994 PetscCall(PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg)); 995 if (flg) { 996 PetscCheck(lag != -1,PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Cannot set the lag to -1 from the command line since the Jacobian must be built as least once, perhaps you mean -2"); 997 PetscCall(SNESSetLagJacobian(snes,lag)); 998 } 999 PetscCall(PetscOptionsBool("-snes_lag_jacobian_persists","Jacobian lagging through multiple SNES solves","SNESSetLagJacobianPersists",snes->lagjac_persist,&persist,&flg)); 1000 if (flg) PetscCall(SNESSetLagJacobianPersists(snes,persist)); 1001 1002 PetscCall(PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg)); 1003 if (flg) PetscCall(SNESSetGridSequence(snes,grids)); 1004 1005 PetscCall(PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,sizeof(convtests)/sizeof(char*),"default",&indx,&flg)); 1006 if (flg) { 1007 switch (indx) { 1008 case 0: PetscCall(SNESSetConvergenceTest(snes,SNESConvergedDefault,NULL,NULL)); break; 1009 case 1: PetscCall(SNESSetConvergenceTest(snes,SNESConvergedSkip,NULL,NULL)); break; 1010 case 2: PetscCall(SNESSetConvergenceTest(snes,SNESConvergedCorrectPressure,NULL,NULL)); break; 1011 } 1012 } 1013 1014 PetscCall(PetscOptionsEList("-snes_norm_schedule","SNES Norm schedule","SNESSetNormSchedule",SNESNormSchedules,5,"function",&indx,&flg)); 1015 if (flg) PetscCall(SNESSetNormSchedule(snes,(SNESNormSchedule)indx)); 1016 1017 PetscCall(PetscOptionsEList("-snes_function_type","SNES Norm schedule","SNESSetFunctionType",SNESFunctionTypes,2,"unpreconditioned",&indx,&flg)); 1018 if (flg) PetscCall(SNESSetFunctionType(snes,(SNESFunctionType)indx)); 1019 1020 kctx = (SNESKSPEW*)snes->kspconvctx; 1021 1022 PetscCall(PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,NULL)); 1023 1024 PetscCall(SNESGetOptionsPrefix(snes,&optionsprefix)); 1025 PetscCall(PetscSNPrintf(ewprefix,sizeof(ewprefix),"%s%s",optionsprefix ? optionsprefix : "","snes_")); 1026 PetscCall(SNESEWSetFromOptions_Private(kctx,PetscObjectComm((PetscObject)snes),ewprefix)); 1027 1028 PetscCall(PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,NULL)); 1029 PetscCall(PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,NULL)); 1030 PetscCall(PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,NULL)); 1031 PetscCall(PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,NULL)); 1032 PetscCall(PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,NULL)); 1033 PetscCall(PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,NULL)); 1034 PetscCall(PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,NULL)); 1035 1036 flg = PETSC_FALSE; 1037 PetscCall(PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,&set)); 1038 if (set && flg) PetscCall(SNESMonitorCancel(snes)); 1039 1040 PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor","Monitor norm of function","SNESMonitorDefault",SNESMonitorDefault,SNESMonitorDefaultSetUp)); 1041 PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_short","Monitor norm of function with fewer digits","SNESMonitorDefaultShort",SNESMonitorDefaultShort,NULL)); 1042 PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_range","Monitor range of elements of function","SNESMonitorRange",SNESMonitorRange,NULL)); 1043 1044 PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_ratio","Monitor ratios of the norm of function for consecutive steps","SNESMonitorRatio",SNESMonitorRatio,SNESMonitorRatioSetUp)); 1045 PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_field","Monitor norm of function (split into fields)","SNESMonitorDefaultField",SNESMonitorDefaultField,NULL)); 1046 PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_solution","View solution at each iteration","SNESMonitorSolution",SNESMonitorSolution,NULL)); 1047 PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_solution_update","View correction at each iteration","SNESMonitorSolutionUpdate",SNESMonitorSolutionUpdate,NULL)); 1048 PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_residual","View residual at each iteration","SNESMonitorResidual",SNESMonitorResidual,NULL)); 1049 PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_jacupdate_spectrum","Print the change in the spectrum of the Jacobian","SNESMonitorJacUpdateSpectrum",SNESMonitorJacUpdateSpectrum,NULL)); 1050 PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_fields","Monitor norm of function per field","SNESMonitorSet",SNESMonitorFields,NULL)); 1051 PetscCall(PetscOptionsBool("-snes_monitor_pause_final", "Pauses all draw monitors at the final iterate", "SNESMonitorPauseFinal_Internal", PETSC_FALSE, &snes->pauseFinal, NULL)); 1052 1053 PetscCall(PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",NULL,monfilename,sizeof(monfilename),&flg)); 1054 if (flg) PetscCall(PetscPythonMonitorSet((PetscObject)snes,monfilename)); 1055 1056 flg = PETSC_FALSE; 1057 PetscCall(PetscOptionsBool("-snes_monitor_lg_range","Plot function range at each iteration","SNESMonitorLGRange",flg,&flg,NULL)); 1058 if (flg) { 1059 PetscViewer ctx; 1060 1061 PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx)); 1062 PetscCall(SNESMonitorSet(snes,SNESMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy)); 1063 } 1064 1065 flg = PETSC_FALSE; 1066 PetscCall(PetscOptionsBool("-snes_converged_reason_view_cancel","Remove all converged reason viewers","SNESConvergedReasonViewCancel",flg,&flg,&set)); 1067 if (set && flg) PetscCall(SNESConvergedReasonViewCancel(snes)); 1068 1069 flg = PETSC_FALSE; 1070 PetscCall(PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESComputeJacobianDefault",flg,&flg,NULL)); 1071 if (flg) { 1072 void *functx; 1073 DM dm; 1074 DMSNES sdm; 1075 PetscCall(SNESGetDM(snes,&dm)); 1076 PetscCall(DMGetDMSNES(dm,&sdm)); 1077 sdm->jacobianctx = NULL; 1078 PetscCall(SNESGetFunction(snes,NULL,NULL,&functx)); 1079 PetscCall(SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefault,functx)); 1080 PetscCall(PetscInfo(snes,"Setting default finite difference Jacobian matrix\n")); 1081 } 1082 1083 flg = PETSC_FALSE; 1084 PetscCall(PetscOptionsBool("-snes_fd_function","Use finite differences (slow) to compute function from user objective","SNESObjectiveComputeFunctionDefaultFD",flg,&flg,NULL)); 1085 if (flg) PetscCall(SNESSetFunction(snes,NULL,SNESObjectiveComputeFunctionDefaultFD,NULL)); 1086 1087 flg = PETSC_FALSE; 1088 PetscCall(PetscOptionsBool("-snes_fd_color","Use finite differences with coloring to compute Jacobian","SNESComputeJacobianDefaultColor",flg,&flg,NULL)); 1089 if (flg) { 1090 DM dm; 1091 DMSNES sdm; 1092 PetscCall(SNESGetDM(snes,&dm)); 1093 PetscCall(DMGetDMSNES(dm,&sdm)); 1094 sdm->jacobianctx = NULL; 1095 PetscCall(SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefaultColor,NULL)); 1096 PetscCall(PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n")); 1097 } 1098 1099 flg = PETSC_FALSE; 1100 PetscCall(PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","SNESSetUseMatrixFree",PETSC_FALSE,&snes->mf_operator,&flg)); 1101 if (flg && snes->mf_operator) { 1102 snes->mf_operator = PETSC_TRUE; 1103 snes->mf = PETSC_TRUE; 1104 } 1105 flg = PETSC_FALSE; 1106 PetscCall(PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","SNESSetUseMatrixFree",PETSC_FALSE,&snes->mf,&flg)); 1107 if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE; 1108 PetscCall(PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",snes->mf_version,&snes->mf_version,NULL)); 1109 1110 flg = PETSC_FALSE; 1111 PetscCall(SNESGetNPCSide(snes,&pcside)); 1112 PetscCall(PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetNPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg)); 1113 if (flg) PetscCall(SNESSetNPCSide(snes,pcside)); 1114 1115 #if defined(PETSC_HAVE_SAWS) 1116 /* 1117 Publish convergence information using SAWs 1118 */ 1119 flg = PETSC_FALSE; 1120 PetscCall(PetscOptionsBool("-snes_monitor_saws","Publish SNES progress using SAWs","SNESMonitorSet",flg,&flg,NULL)); 1121 if (flg) { 1122 void *ctx; 1123 PetscCall(SNESMonitorSAWsCreate(snes,&ctx)); 1124 PetscCall(SNESMonitorSet(snes,SNESMonitorSAWs,ctx,SNESMonitorSAWsDestroy)); 1125 } 1126 #endif 1127 #if defined(PETSC_HAVE_SAWS) 1128 { 1129 PetscBool set; 1130 flg = PETSC_FALSE; 1131 PetscCall(PetscOptionsBool("-snes_saws_block","Block for SAWs at end of SNESSolve","PetscObjectSAWsBlock",((PetscObject)snes)->amspublishblock,&flg,&set)); 1132 if (set) PetscCall(PetscObjectSAWsSetBlock((PetscObject)snes,flg)); 1133 } 1134 #endif 1135 1136 for (i = 0; i < numberofsetfromoptions; i++) { 1137 PetscCall((*othersetfromoptions[i])(snes)); 1138 } 1139 1140 if (snes->ops->setfromoptions) PetscCall((*snes->ops->setfromoptions)(PetscOptionsObject,snes)); 1141 1142 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 1143 PetscCall(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)snes)); 1144 PetscOptionsEnd(); 1145 1146 if (snes->linesearch) { 1147 PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 1148 PetscCall(SNESLineSearchSetFromOptions(snes->linesearch)); 1149 } 1150 1151 if (snes->usesksp) { 1152 if (!snes->ksp) PetscCall(SNESGetKSP(snes,&snes->ksp)); 1153 PetscCall(KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre)); 1154 PetscCall(KSPSetFromOptions(snes->ksp)); 1155 } 1156 1157 /* if user has set the SNES NPC type via options database, create it. */ 1158 PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 1159 PetscCall(PetscOptionsHasName(((PetscObject)snes)->options,optionsprefix, "-npc_snes_type", &pcset)); 1160 if (pcset && (!snes->npc)) { 1161 PetscCall(SNESGetNPC(snes, &snes->npc)); 1162 } 1163 if (snes->npc) PetscCall(SNESSetFromOptions(snes->npc)); 1164 snes->setfromoptionscalled++; 1165 PetscFunctionReturn(0); 1166 } 1167 1168 /*@ 1169 SNESResetFromOptions - Sets various SNES and KSP parameters from user options ONLY if the SNES was previously set from options 1170 1171 Collective on SNES 1172 1173 Input Parameter: 1174 . snes - the SNES context 1175 1176 Level: beginner 1177 1178 .seealso: `SNESSetFromOptions()`, `SNESSetOptionsPrefix()` 1179 @*/ 1180 PetscErrorCode SNESResetFromOptions(SNES snes) 1181 { 1182 PetscFunctionBegin; 1183 if (snes->setfromoptionscalled) PetscCall(SNESSetFromOptions(snes)); 1184 PetscFunctionReturn(0); 1185 } 1186 1187 /*@C 1188 SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 1189 the nonlinear solvers. 1190 1191 Logically Collective on SNES 1192 1193 Input Parameters: 1194 + snes - the SNES context 1195 . compute - function to compute the context 1196 - destroy - function to destroy the context 1197 1198 Level: intermediate 1199 1200 Notes: 1201 This function is currently not available from Fortran. 1202 1203 .seealso: `SNESGetApplicationContext()`, `SNESSetComputeApplicationContext()`, `SNESGetApplicationContext()` 1204 @*/ 1205 PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 1206 { 1207 PetscFunctionBegin; 1208 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1209 snes->ops->usercompute = compute; 1210 snes->ops->userdestroy = destroy; 1211 PetscFunctionReturn(0); 1212 } 1213 1214 /*@ 1215 SNESSetApplicationContext - Sets the optional user-defined context for 1216 the nonlinear solvers. 1217 1218 Logically Collective on SNES 1219 1220 Input Parameters: 1221 + snes - the SNES context 1222 - usrP - optional user context 1223 1224 Level: intermediate 1225 1226 Fortran Notes: 1227 To use this from Fortran you must write a Fortran interface definition for this 1228 function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1229 1230 .seealso: `SNESGetApplicationContext()` 1231 @*/ 1232 PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 1233 { 1234 KSP ksp; 1235 1236 PetscFunctionBegin; 1237 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1238 PetscCall(SNESGetKSP(snes,&ksp)); 1239 PetscCall(KSPSetApplicationContext(ksp,usrP)); 1240 snes->user = usrP; 1241 PetscFunctionReturn(0); 1242 } 1243 1244 /*@ 1245 SNESGetApplicationContext - Gets the user-defined context for the 1246 nonlinear solvers. 1247 1248 Not Collective 1249 1250 Input Parameter: 1251 . snes - SNES context 1252 1253 Output Parameter: 1254 . usrP - user context 1255 1256 Fortran Notes: 1257 To use this from Fortran you must write a Fortran interface definition for this 1258 function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1259 1260 Level: intermediate 1261 1262 .seealso: `SNESSetApplicationContext()` 1263 @*/ 1264 PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 1265 { 1266 PetscFunctionBegin; 1267 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1268 *(void**)usrP = snes->user; 1269 PetscFunctionReturn(0); 1270 } 1271 1272 /*@ 1273 SNESSetUseMatrixFree - indicates that SNES should use matrix free finite difference matrix vector products internally to apply the Jacobian. 1274 1275 Collective on SNES 1276 1277 Input Parameters: 1278 + snes - SNES context 1279 . mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used 1280 - mf - use matrix-free for both the Amat and Pmat used by SNESSetJacobian(), both the Amat and Pmat set in SNESSetJacobian() will be ignored 1281 1282 Options Database: 1283 + -snes_mf - use matrix free for both the mat and pmat operator 1284 . -snes_mf_operator - use matrix free only for the mat operator 1285 . -snes_fd_color - compute the Jacobian via coloring and finite differences. 1286 - -snes_fd - compute the Jacobian via finite differences (slow) 1287 1288 Level: intermediate 1289 1290 Notes: 1291 SNES supports three approaches for computing (approximate) Jacobians: user provided via SNESSetJacobian(), matrix free, and computing explicitly with 1292 finite differences and coloring using MatFDColoring. It is also possible to use automatic differentiation and the MatFDColoring object. 1293 1294 .seealso: `SNESGetUseMatrixFree()`, `MatCreateSNESMF()`, `SNESComputeJacobianDefaultColor()` 1295 @*/ 1296 PetscErrorCode SNESSetUseMatrixFree(SNES snes,PetscBool mf_operator,PetscBool mf) 1297 { 1298 PetscFunctionBegin; 1299 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1300 PetscValidLogicalCollectiveBool(snes,mf_operator,2); 1301 PetscValidLogicalCollectiveBool(snes,mf,3); 1302 snes->mf = mf_operator ? PETSC_TRUE : mf; 1303 snes->mf_operator = mf_operator; 1304 PetscFunctionReturn(0); 1305 } 1306 1307 /*@ 1308 SNESGetUseMatrixFree - indicates if the SNES uses matrix free finite difference matrix vector products to apply the Jacobian. 1309 1310 Collective on SNES 1311 1312 Input Parameter: 1313 . snes - SNES context 1314 1315 Output Parameters: 1316 + mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used 1317 - mf - use matrix-free for both the Amat and Pmat used by SNESSetJacobian(), both the Amat and Pmat set in SNESSetJacobian() will be ignored 1318 1319 Options Database: 1320 + -snes_mf - use matrix free for both the mat and pmat operator 1321 - -snes_mf_operator - use matrix free only for the mat operator 1322 1323 Level: intermediate 1324 1325 .seealso: `SNESSetUseMatrixFree()`, `MatCreateSNESMF()` 1326 @*/ 1327 PetscErrorCode SNESGetUseMatrixFree(SNES snes,PetscBool *mf_operator,PetscBool *mf) 1328 { 1329 PetscFunctionBegin; 1330 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1331 if (mf) *mf = snes->mf; 1332 if (mf_operator) *mf_operator = snes->mf_operator; 1333 PetscFunctionReturn(0); 1334 } 1335 1336 /*@ 1337 SNESGetIterationNumber - Gets the number of nonlinear iterations completed 1338 at this time. 1339 1340 Not Collective 1341 1342 Input Parameter: 1343 . snes - SNES context 1344 1345 Output Parameter: 1346 . iter - iteration number 1347 1348 Notes: 1349 For example, during the computation of iteration 2 this would return 1. 1350 1351 This is useful for using lagged Jacobians (where one does not recompute the 1352 Jacobian at each SNES iteration). For example, the code 1353 .vb 1354 ierr = SNESGetIterationNumber(snes,&it); 1355 if (!(it % 2)) { 1356 [compute Jacobian here] 1357 } 1358 .ve 1359 can be used in your ComputeJacobian() function to cause the Jacobian to be 1360 recomputed every second SNES iteration. 1361 1362 After the SNES solve is complete this will return the number of nonlinear iterations used. 1363 1364 Level: intermediate 1365 1366 .seealso: `SNESGetLinearSolveIterations()` 1367 @*/ 1368 PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt *iter) 1369 { 1370 PetscFunctionBegin; 1371 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1372 PetscValidIntPointer(iter,2); 1373 *iter = snes->iter; 1374 PetscFunctionReturn(0); 1375 } 1376 1377 /*@ 1378 SNESSetIterationNumber - Sets the current iteration number. 1379 1380 Not Collective 1381 1382 Input Parameters: 1383 + snes - SNES context 1384 - iter - iteration number 1385 1386 Level: developer 1387 1388 .seealso: `SNESGetLinearSolveIterations()` 1389 @*/ 1390 PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 1391 { 1392 PetscFunctionBegin; 1393 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1394 PetscCall(PetscObjectSAWsTakeAccess((PetscObject)snes)); 1395 snes->iter = iter; 1396 PetscCall(PetscObjectSAWsGrantAccess((PetscObject)snes)); 1397 PetscFunctionReturn(0); 1398 } 1399 1400 /*@ 1401 SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 1402 attempted by the nonlinear solver. 1403 1404 Not Collective 1405 1406 Input Parameter: 1407 . snes - SNES context 1408 1409 Output Parameter: 1410 . nfails - number of unsuccessful steps attempted 1411 1412 Notes: 1413 This counter is reset to zero for each successive call to SNESSolve(). 1414 1415 Level: intermediate 1416 1417 .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1418 `SNESSetMaxNonlinearStepFailures()`, `SNESGetMaxNonlinearStepFailures()` 1419 @*/ 1420 PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt *nfails) 1421 { 1422 PetscFunctionBegin; 1423 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1424 PetscValidIntPointer(nfails,2); 1425 *nfails = snes->numFailures; 1426 PetscFunctionReturn(0); 1427 } 1428 1429 /*@ 1430 SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 1431 attempted by the nonlinear solver before it gives up. 1432 1433 Not Collective 1434 1435 Input Parameters: 1436 + snes - SNES context 1437 - maxFails - maximum of unsuccessful steps 1438 1439 Level: intermediate 1440 1441 .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1442 `SNESGetMaxNonlinearStepFailures()`, `SNESGetNonlinearStepFailures()` 1443 @*/ 1444 PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 1445 { 1446 PetscFunctionBegin; 1447 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1448 snes->maxFailures = maxFails; 1449 PetscFunctionReturn(0); 1450 } 1451 1452 /*@ 1453 SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 1454 attempted by the nonlinear solver before it gives up. 1455 1456 Not Collective 1457 1458 Input Parameter: 1459 . snes - SNES context 1460 1461 Output Parameter: 1462 . maxFails - maximum of unsuccessful steps 1463 1464 Level: intermediate 1465 1466 .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1467 `SNESSetMaxNonlinearStepFailures()`, `SNESGetNonlinearStepFailures()` 1468 1469 @*/ 1470 PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 1471 { 1472 PetscFunctionBegin; 1473 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1474 PetscValidIntPointer(maxFails,2); 1475 *maxFails = snes->maxFailures; 1476 PetscFunctionReturn(0); 1477 } 1478 1479 /*@ 1480 SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 1481 done by SNES. 1482 1483 Not Collective 1484 1485 Input Parameter: 1486 . snes - SNES context 1487 1488 Output Parameter: 1489 . nfuncs - number of evaluations 1490 1491 Level: intermediate 1492 1493 Notes: 1494 Reset every time SNESSolve is called unless SNESSetCountersReset() is used. 1495 1496 .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, `SNESSetCountersReset()` 1497 @*/ 1498 PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 1499 { 1500 PetscFunctionBegin; 1501 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1502 PetscValidIntPointer(nfuncs,2); 1503 *nfuncs = snes->nfuncs; 1504 PetscFunctionReturn(0); 1505 } 1506 1507 /*@ 1508 SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 1509 linear solvers. 1510 1511 Not Collective 1512 1513 Input Parameter: 1514 . snes - SNES context 1515 1516 Output Parameter: 1517 . nfails - number of failed solves 1518 1519 Level: intermediate 1520 1521 Options Database Keys: 1522 . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 1523 1524 Notes: 1525 This counter is reset to zero for each successive call to SNESSolve(). 1526 1527 .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()` 1528 @*/ 1529 PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt *nfails) 1530 { 1531 PetscFunctionBegin; 1532 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1533 PetscValidIntPointer(nfails,2); 1534 *nfails = snes->numLinearSolveFailures; 1535 PetscFunctionReturn(0); 1536 } 1537 1538 /*@ 1539 SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 1540 allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 1541 1542 Logically Collective on SNES 1543 1544 Input Parameters: 1545 + snes - SNES context 1546 - maxFails - maximum allowed linear solve failures 1547 1548 Level: intermediate 1549 1550 Options Database Keys: 1551 . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 1552 1553 Notes: 1554 By default this is 0; that is SNES returns on the first failed linear solve 1555 1556 .seealso: `SNESGetLinearSolveFailures()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()` 1557 @*/ 1558 PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 1559 { 1560 PetscFunctionBegin; 1561 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1562 PetscValidLogicalCollectiveInt(snes,maxFails,2); 1563 snes->maxLinearSolveFailures = maxFails; 1564 PetscFunctionReturn(0); 1565 } 1566 1567 /*@ 1568 SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 1569 are allowed before SNES terminates 1570 1571 Not Collective 1572 1573 Input Parameter: 1574 . snes - SNES context 1575 1576 Output Parameter: 1577 . maxFails - maximum of unsuccessful solves allowed 1578 1579 Level: intermediate 1580 1581 Notes: 1582 By default this is 1; that is SNES returns on the first failed linear solve 1583 1584 .seealso: `SNESGetLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, 1585 @*/ 1586 PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 1587 { 1588 PetscFunctionBegin; 1589 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1590 PetscValidIntPointer(maxFails,2); 1591 *maxFails = snes->maxLinearSolveFailures; 1592 PetscFunctionReturn(0); 1593 } 1594 1595 /*@ 1596 SNESGetLinearSolveIterations - Gets the total number of linear iterations 1597 used by the nonlinear solver. 1598 1599 Not Collective 1600 1601 Input Parameter: 1602 . snes - SNES context 1603 1604 Output Parameter: 1605 . lits - number of linear iterations 1606 1607 Notes: 1608 This counter is reset to zero for each successive call to SNESSolve() unless SNESSetCountersReset() is used. 1609 1610 If the linear solver fails inside the SNESSolve() the iterations for that call to the linear solver are not included. If you wish to count them 1611 then call KSPGetIterationNumber() after the failed solve. 1612 1613 Level: intermediate 1614 1615 .seealso: `SNESGetIterationNumber()`, `SNESGetLinearSolveFailures()`, `SNESGetMaxLinearSolveFailures()`, `SNESSetCountersReset()` 1616 @*/ 1617 PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt *lits) 1618 { 1619 PetscFunctionBegin; 1620 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1621 PetscValidIntPointer(lits,2); 1622 *lits = snes->linear_its; 1623 PetscFunctionReturn(0); 1624 } 1625 1626 /*@ 1627 SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations 1628 are reset every time SNESSolve() is called. 1629 1630 Logically Collective on SNES 1631 1632 Input Parameters: 1633 + snes - SNES context 1634 - reset - whether to reset the counters or not 1635 1636 Notes: 1637 This defaults to PETSC_TRUE 1638 1639 Level: developer 1640 1641 .seealso: `SNESGetNumberFunctionEvals()`, `SNESGetLinearSolveIterations()`, `SNESGetNPC()` 1642 @*/ 1643 PetscErrorCode SNESSetCountersReset(SNES snes,PetscBool reset) 1644 { 1645 PetscFunctionBegin; 1646 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1647 PetscValidLogicalCollectiveBool(snes,reset,2); 1648 snes->counters_reset = reset; 1649 PetscFunctionReturn(0); 1650 } 1651 1652 /*@ 1653 SNESSetKSP - Sets a KSP context for the SNES object to use 1654 1655 Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 1656 1657 Input Parameters: 1658 + snes - the SNES context 1659 - ksp - the KSP context 1660 1661 Notes: 1662 The SNES object already has its KSP object, you can obtain with SNESGetKSP() 1663 so this routine is rarely needed. 1664 1665 The KSP object that is already in the SNES object has its reference count 1666 decreased by one. 1667 1668 Level: developer 1669 1670 .seealso: `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()` 1671 @*/ 1672 PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 1673 { 1674 PetscFunctionBegin; 1675 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1676 PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 1677 PetscCheckSameComm(snes,1,ksp,2); 1678 PetscCall(PetscObjectReference((PetscObject)ksp)); 1679 if (snes->ksp) PetscCall(PetscObjectDereference((PetscObject)snes->ksp)); 1680 snes->ksp = ksp; 1681 PetscFunctionReturn(0); 1682 } 1683 1684 /* -----------------------------------------------------------*/ 1685 /*@ 1686 SNESCreate - Creates a nonlinear solver context. 1687 1688 Collective 1689 1690 Input Parameters: 1691 . comm - MPI communicator 1692 1693 Output Parameter: 1694 . outsnes - the new SNES context 1695 1696 Options Database Keys: 1697 + -snes_mf - Activates default matrix-free Jacobian-vector products, 1698 and no preconditioning matrix 1699 . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1700 products, and a user-provided preconditioning matrix 1701 as set by SNESSetJacobian() 1702 - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1703 1704 Level: beginner 1705 1706 Developer Notes: 1707 SNES always creates a KSP object even though many SNES methods do not use it. This is 1708 unfortunate and should be fixed at some point. The flag snes->usesksp indicates if the 1709 particular method does use KSP and regulates if the information about the KSP is printed 1710 in SNESView(). TSSetFromOptions() does call SNESSetFromOptions() which can lead to users being confused 1711 by help messages about meaningless SNES options. 1712 1713 SNES always creates the snes->kspconvctx even though it is used by only one type. This should 1714 be fixed. 1715 1716 .seealso: `SNESSolve()`, `SNESDestroy()`, `SNES`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()` 1717 1718 @*/ 1719 PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 1720 { 1721 SNES snes; 1722 SNESKSPEW *kctx; 1723 1724 PetscFunctionBegin; 1725 PetscValidPointer(outsnes,2); 1726 *outsnes = NULL; 1727 PetscCall(SNESInitializePackage()); 1728 1729 PetscCall(PetscHeaderCreate(snes,SNES_CLASSID,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView)); 1730 1731 snes->ops->converged = SNESConvergedDefault; 1732 snes->usesksp = PETSC_TRUE; 1733 snes->tolerancesset = PETSC_FALSE; 1734 snes->max_its = 50; 1735 snes->max_funcs = 10000; 1736 snes->norm = 0.0; 1737 snes->xnorm = 0.0; 1738 snes->ynorm = 0.0; 1739 snes->normschedule = SNES_NORM_ALWAYS; 1740 snes->functype = SNES_FUNCTION_DEFAULT; 1741 #if defined(PETSC_USE_REAL_SINGLE) 1742 snes->rtol = 1.e-5; 1743 #else 1744 snes->rtol = 1.e-8; 1745 #endif 1746 snes->ttol = 0.0; 1747 #if defined(PETSC_USE_REAL_SINGLE) 1748 snes->abstol = 1.e-25; 1749 #else 1750 snes->abstol = 1.e-50; 1751 #endif 1752 #if defined(PETSC_USE_REAL_SINGLE) 1753 snes->stol = 1.e-5; 1754 #else 1755 snes->stol = 1.e-8; 1756 #endif 1757 #if defined(PETSC_USE_REAL_SINGLE) 1758 snes->deltatol = 1.e-6; 1759 #else 1760 snes->deltatol = 1.e-12; 1761 #endif 1762 snes->divtol = 1.e4; 1763 snes->rnorm0 = 0; 1764 snes->nfuncs = 0; 1765 snes->numFailures = 0; 1766 snes->maxFailures = 1; 1767 snes->linear_its = 0; 1768 snes->lagjacobian = 1; 1769 snes->jac_iter = 0; 1770 snes->lagjac_persist = PETSC_FALSE; 1771 snes->lagpreconditioner = 1; 1772 snes->pre_iter = 0; 1773 snes->lagpre_persist = PETSC_FALSE; 1774 snes->numbermonitors = 0; 1775 snes->numberreasonviews = 0; 1776 snes->data = NULL; 1777 snes->setupcalled = PETSC_FALSE; 1778 snes->ksp_ewconv = PETSC_FALSE; 1779 snes->nwork = 0; 1780 snes->work = NULL; 1781 snes->nvwork = 0; 1782 snes->vwork = NULL; 1783 snes->conv_hist_len = 0; 1784 snes->conv_hist_max = 0; 1785 snes->conv_hist = NULL; 1786 snes->conv_hist_its = NULL; 1787 snes->conv_hist_reset = PETSC_TRUE; 1788 snes->counters_reset = PETSC_TRUE; 1789 snes->vec_func_init_set = PETSC_FALSE; 1790 snes->reason = SNES_CONVERGED_ITERATING; 1791 snes->npcside = PC_RIGHT; 1792 snes->setfromoptionscalled = 0; 1793 1794 snes->mf = PETSC_FALSE; 1795 snes->mf_operator = PETSC_FALSE; 1796 snes->mf_version = 1; 1797 1798 snes->numLinearSolveFailures = 0; 1799 snes->maxLinearSolveFailures = 1; 1800 1801 snes->vizerotolerance = 1.e-8; 1802 snes->checkjacdomainerror = PetscDefined(USE_DEBUG) ? PETSC_TRUE : PETSC_FALSE; 1803 1804 /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */ 1805 snes->alwayscomputesfinalresidual = PETSC_FALSE; 1806 1807 /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 1808 PetscCall(PetscNewLog(snes,&kctx)); 1809 1810 snes->kspconvctx = (void*)kctx; 1811 kctx->version = 2; 1812 kctx->rtol_0 = 0.3; /* Eisenstat and Walker suggest rtol_0=.5, but 1813 this was too large for some test cases */ 1814 kctx->rtol_last = 0.0; 1815 kctx->rtol_max = 0.9; 1816 kctx->gamma = 1.0; 1817 kctx->alpha = 0.5*(1.0 + PetscSqrtReal(5.0)); 1818 kctx->alpha2 = kctx->alpha; 1819 kctx->threshold = 0.1; 1820 kctx->lresid_last = 0.0; 1821 kctx->norm_last = 0.0; 1822 1823 kctx->rk_last = 0.0; 1824 kctx->rk_last_2 = 0.0; 1825 kctx->rtol_last_2 = 0.0; 1826 kctx->v4_p1 = 0.1; 1827 kctx->v4_p2 = 0.4; 1828 kctx->v4_p3 = 0.7; 1829 kctx->v4_m1 = 0.8; 1830 kctx->v4_m2 = 0.5; 1831 kctx->v4_m3 = 0.1; 1832 kctx->v4_m4 = 0.5; 1833 1834 *outsnes = snes; 1835 PetscFunctionReturn(0); 1836 } 1837 1838 /*MC 1839 SNESFunction - Functional form used to convey the nonlinear function to be solved by SNES 1840 1841 Synopsis: 1842 #include "petscsnes.h" 1843 PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx); 1844 1845 Collective on snes 1846 1847 Input Parameters: 1848 + snes - the SNES context 1849 . x - state at which to evaluate residual 1850 - ctx - optional user-defined function context, passed in with SNESSetFunction() 1851 1852 Output Parameter: 1853 . f - vector to put residual (function value) 1854 1855 Level: intermediate 1856 1857 .seealso: `SNESSetFunction()`, `SNESGetFunction()` 1858 M*/ 1859 1860 /*@C 1861 SNESSetFunction - Sets the function evaluation routine and function 1862 vector for use by the SNES routines in solving systems of nonlinear 1863 equations. 1864 1865 Logically Collective on SNES 1866 1867 Input Parameters: 1868 + snes - the SNES context 1869 . r - vector to store function values, may be NULL 1870 . f - function evaluation routine; see SNESFunction for calling sequence details 1871 - ctx - [optional] user-defined context for private data for the 1872 function evaluation routine (may be NULL) 1873 1874 Notes: 1875 The Newton-like methods typically solve linear systems of the form 1876 $ f'(x) x = -f(x), 1877 where f'(x) denotes the Jacobian matrix and f(x) is the function. 1878 1879 Level: beginner 1880 1881 .seealso: `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetPicard()`, `SNESFunction` 1882 @*/ 1883 PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx) 1884 { 1885 DM dm; 1886 1887 PetscFunctionBegin; 1888 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1889 if (r) { 1890 PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1891 PetscCheckSameComm(snes,1,r,2); 1892 PetscCall(PetscObjectReference((PetscObject)r)); 1893 PetscCall(VecDestroy(&snes->vec_func)); 1894 snes->vec_func = r; 1895 } 1896 PetscCall(SNESGetDM(snes,&dm)); 1897 PetscCall(DMSNESSetFunction(dm,f,ctx)); 1898 if (f == SNESPicardComputeFunction) { 1899 PetscCall(DMSNESSetMFFunction(dm,SNESPicardComputeMFFunction,ctx)); 1900 } 1901 PetscFunctionReturn(0); 1902 } 1903 1904 /*@C 1905 SNESSetInitialFunction - Sets the function vector to be used as the 1906 function norm at the initialization of the method. In some 1907 instances, the user has precomputed the function before calling 1908 SNESSolve. This function allows one to avoid a redundant call 1909 to SNESComputeFunction in that case. 1910 1911 Logically Collective on SNES 1912 1913 Input Parameters: 1914 + snes - the SNES context 1915 - f - vector to store function value 1916 1917 Notes: 1918 This should not be modified during the solution procedure. 1919 1920 This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1921 1922 Level: developer 1923 1924 .seealso: `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetInitialFunctionNorm()` 1925 @*/ 1926 PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1927 { 1928 Vec vec_func; 1929 1930 PetscFunctionBegin; 1931 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1932 PetscValidHeaderSpecific(f,VEC_CLASSID,2); 1933 PetscCheckSameComm(snes,1,f,2); 1934 if (snes->npcside == PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) { 1935 snes->vec_func_init_set = PETSC_FALSE; 1936 PetscFunctionReturn(0); 1937 } 1938 PetscCall(SNESGetFunction(snes,&vec_func,NULL,NULL)); 1939 PetscCall(VecCopy(f,vec_func)); 1940 1941 snes->vec_func_init_set = PETSC_TRUE; 1942 PetscFunctionReturn(0); 1943 } 1944 1945 /*@ 1946 SNESSetNormSchedule - Sets the SNESNormSchedule used in convergence and monitoring 1947 of the SNES method. 1948 1949 Logically Collective on SNES 1950 1951 Input Parameters: 1952 + snes - the SNES context 1953 - normschedule - the frequency of norm computation 1954 1955 Options Database Key: 1956 . -snes_norm_schedule <none, always, initialonly, finalonly, initialfinalonly> - set the schedule 1957 1958 Notes: 1959 Only certain SNES methods support certain SNESNormSchedules. Most require evaluation 1960 of the nonlinear function and the taking of its norm at every iteration to 1961 even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1962 (SNESNGS) and the like do not require the norm of the function to be computed, and therefore 1963 may either be monitored for convergence or not. As these are often used as nonlinear 1964 preconditioners, monitoring the norm of their error is not a useful enterprise within 1965 their solution. 1966 1967 Level: developer 1968 1969 .seealso: `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1970 @*/ 1971 PetscErrorCode SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule) 1972 { 1973 PetscFunctionBegin; 1974 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1975 snes->normschedule = normschedule; 1976 PetscFunctionReturn(0); 1977 } 1978 1979 /*@ 1980 SNESGetNormSchedule - Gets the SNESNormSchedule used in convergence and monitoring 1981 of the SNES method. 1982 1983 Logically Collective on SNES 1984 1985 Input Parameters: 1986 + snes - the SNES context 1987 - normschedule - the type of the norm used 1988 1989 Level: advanced 1990 1991 .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1992 @*/ 1993 PetscErrorCode SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule) 1994 { 1995 PetscFunctionBegin; 1996 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1997 *normschedule = snes->normschedule; 1998 PetscFunctionReturn(0); 1999 } 2000 2001 /*@ 2002 SNESSetFunctionNorm - Sets the last computed residual norm. 2003 2004 Logically Collective on SNES 2005 2006 Input Parameters: 2007 + snes - the SNES context 2008 2009 - normschedule - the frequency of norm computation 2010 2011 Level: developer 2012 2013 .seealso: `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 2014 @*/ 2015 PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm) 2016 { 2017 PetscFunctionBegin; 2018 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2019 snes->norm = norm; 2020 PetscFunctionReturn(0); 2021 } 2022 2023 /*@ 2024 SNESGetFunctionNorm - Gets the last computed norm of the residual 2025 2026 Not Collective 2027 2028 Input Parameter: 2029 . snes - the SNES context 2030 2031 Output Parameter: 2032 . norm - the last computed residual norm 2033 2034 Level: developer 2035 2036 .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 2037 @*/ 2038 PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm) 2039 { 2040 PetscFunctionBegin; 2041 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2042 PetscValidRealPointer(norm, 2); 2043 *norm = snes->norm; 2044 PetscFunctionReturn(0); 2045 } 2046 2047 /*@ 2048 SNESGetUpdateNorm - Gets the last computed norm of the Newton update 2049 2050 Not Collective 2051 2052 Input Parameter: 2053 . snes - the SNES context 2054 2055 Output Parameter: 2056 . ynorm - the last computed update norm 2057 2058 Level: developer 2059 2060 .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()` 2061 @*/ 2062 PetscErrorCode SNESGetUpdateNorm(SNES snes, PetscReal *ynorm) 2063 { 2064 PetscFunctionBegin; 2065 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2066 PetscValidRealPointer(ynorm, 2); 2067 *ynorm = snes->ynorm; 2068 PetscFunctionReturn(0); 2069 } 2070 2071 /*@ 2072 SNESGetSolutionNorm - Gets the last computed norm of the solution 2073 2074 Not Collective 2075 2076 Input Parameter: 2077 . snes - the SNES context 2078 2079 Output Parameter: 2080 . xnorm - the last computed solution norm 2081 2082 Level: developer 2083 2084 .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()`, `SNESGetUpdateNorm()` 2085 @*/ 2086 PetscErrorCode SNESGetSolutionNorm(SNES snes, PetscReal *xnorm) 2087 { 2088 PetscFunctionBegin; 2089 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2090 PetscValidRealPointer(xnorm, 2); 2091 *xnorm = snes->xnorm; 2092 PetscFunctionReturn(0); 2093 } 2094 2095 /*@C 2096 SNESSetFunctionType - Sets the SNESNormSchedule used in convergence and monitoring 2097 of the SNES method. 2098 2099 Logically Collective on SNES 2100 2101 Input Parameters: 2102 + snes - the SNES context 2103 - normschedule - the frequency of norm computation 2104 2105 Notes: 2106 Only certain SNES methods support certain SNESNormSchedules. Most require evaluation 2107 of the nonlinear function and the taking of its norm at every iteration to 2108 even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 2109 (SNESNGS) and the like do not require the norm of the function to be computed, and therefore 2110 may either be monitored for convergence or not. As these are often used as nonlinear 2111 preconditioners, monitoring the norm of their error is not a useful enterprise within 2112 their solution. 2113 2114 Level: developer 2115 2116 .seealso: `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 2117 @*/ 2118 PetscErrorCode SNESSetFunctionType(SNES snes, SNESFunctionType type) 2119 { 2120 PetscFunctionBegin; 2121 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2122 snes->functype = type; 2123 PetscFunctionReturn(0); 2124 } 2125 2126 /*@C 2127 SNESGetFunctionType - Gets the SNESNormSchedule used in convergence and monitoring 2128 of the SNES method. 2129 2130 Logically Collective on SNES 2131 2132 Input Parameters: 2133 + snes - the SNES context 2134 - normschedule - the type of the norm used 2135 2136 Level: advanced 2137 2138 .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 2139 @*/ 2140 PetscErrorCode SNESGetFunctionType(SNES snes, SNESFunctionType *type) 2141 { 2142 PetscFunctionBegin; 2143 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2144 *type = snes->functype; 2145 PetscFunctionReturn(0); 2146 } 2147 2148 /*MC 2149 SNESNGSFunction - function used to convey a Gauss-Seidel sweep on the nonlinear function 2150 2151 Synopsis: 2152 #include <petscsnes.h> 2153 $ SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx); 2154 2155 Collective on snes 2156 2157 Input Parameters: 2158 + X - solution vector 2159 . B - RHS vector 2160 - ctx - optional user-defined Gauss-Seidel context 2161 2162 Output Parameter: 2163 . X - solution vector 2164 2165 Level: intermediate 2166 2167 .seealso: `SNESSetNGS()`, `SNESGetNGS()` 2168 M*/ 2169 2170 /*@C 2171 SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for 2172 use with composed nonlinear solvers. 2173 2174 Input Parameters: 2175 + snes - the SNES context 2176 . f - function evaluation routine to apply Gauss-Seidel see SNESNGSFunction 2177 - ctx - [optional] user-defined context for private data for the 2178 smoother evaluation routine (may be NULL) 2179 2180 Notes: 2181 The NGS routines are used by the composed nonlinear solver to generate 2182 a problem appropriate update to the solution, particularly FAS. 2183 2184 Level: intermediate 2185 2186 .seealso: `SNESGetFunction()`, `SNESComputeNGS()` 2187 @*/ 2188 PetscErrorCode SNESSetNGS(SNES snes,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx) 2189 { 2190 DM dm; 2191 2192 PetscFunctionBegin; 2193 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2194 PetscCall(SNESGetDM(snes,&dm)); 2195 PetscCall(DMSNESSetNGS(dm,f,ctx)); 2196 PetscFunctionReturn(0); 2197 } 2198 2199 /* 2200 This is used for -snes_mf_operator; it uses a duplicate of snes->jacobian_pre because snes->jacobian_pre cannot be 2201 changed during the KSPSolve() 2202 */ 2203 PetscErrorCode SNESPicardComputeMFFunction(SNES snes,Vec x,Vec f,void *ctx) 2204 { 2205 DM dm; 2206 DMSNES sdm; 2207 2208 PetscFunctionBegin; 2209 PetscCall(SNESGetDM(snes,&dm)); 2210 PetscCall(DMGetDMSNES(dm,&sdm)); 2211 PetscCheck(sdm->ops->computepjacobian,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard Jacobian."); 2212 /* A(x)*x - b(x) */ 2213 if (sdm->ops->computepfunction) { 2214 PetscStackPush("SNES Picard user function"); 2215 PetscCall((*sdm->ops->computepfunction)(snes,x,f,sdm->pctx)); 2216 PetscStackPop; 2217 PetscCall(VecScale(f,-1.0)); 2218 if (!snes->picard) { 2219 /* Cannot share nonzero pattern because of the possible use of SNESComputeJacobianDefault() */ 2220 PetscCall(MatDuplicate(snes->jacobian_pre,MAT_DO_NOT_COPY_VALUES,&snes->picard)); 2221 } 2222 PetscStackPush("SNES Picard user Jacobian"); 2223 PetscCall((*sdm->ops->computepjacobian)(snes,x,snes->picard,snes->picard,sdm->pctx)); 2224 PetscStackPop; 2225 PetscCall(MatMultAdd(snes->picard,x,f,f)); 2226 } else { 2227 PetscStackPush("SNES Picard user Jacobian"); 2228 PetscCall((*sdm->ops->computepjacobian)(snes,x,snes->picard,snes->picard,sdm->pctx)); 2229 PetscStackPop; 2230 PetscCall(MatMult(snes->picard,x,f)); 2231 } 2232 PetscFunctionReturn(0); 2233 } 2234 2235 PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 2236 { 2237 DM dm; 2238 DMSNES sdm; 2239 2240 PetscFunctionBegin; 2241 PetscCall(SNESGetDM(snes,&dm)); 2242 PetscCall(DMGetDMSNES(dm,&sdm)); 2243 PetscCheck(sdm->ops->computepjacobian,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard Jacobian."); 2244 /* A(x)*x - b(x) */ 2245 if (sdm->ops->computepfunction) { 2246 PetscStackPush("SNES Picard user function"); 2247 PetscCall((*sdm->ops->computepfunction)(snes,x,f,sdm->pctx)); 2248 PetscStackPop; 2249 PetscCall(VecScale(f,-1.0)); 2250 PetscStackPush("SNES Picard user Jacobian"); 2251 PetscCall((*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx)); 2252 PetscStackPop; 2253 PetscCall(MatMultAdd(snes->jacobian_pre,x,f,f)); 2254 } else { 2255 PetscStackPush("SNES Picard user Jacobian"); 2256 PetscCall((*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx)); 2257 PetscStackPop; 2258 PetscCall(MatMult(snes->jacobian_pre,x,f)); 2259 } 2260 PetscFunctionReturn(0); 2261 } 2262 2263 PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat J,Mat B,void *ctx) 2264 { 2265 PetscFunctionBegin; 2266 /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */ 2267 /* must assembly if matrix-free to get the last SNES solution */ 2268 PetscCall(MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY)); 2269 PetscCall(MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY)); 2270 PetscFunctionReturn(0); 2271 } 2272 2273 /*@C 2274 SNESSetPicard - Use SNES to solve the system A(x) x = bp(x) + b via a Picard type iteration (Picard linearization) 2275 2276 Logically Collective on SNES 2277 2278 Input Parameters: 2279 + snes - the SNES context 2280 . r - vector to store function values, may be NULL 2281 . bp - function evaluation routine, may be NULL 2282 . Amat - matrix with which A(x) x - bp(x) - b is to be computed 2283 . Pmat - matrix from which preconditioner is computed (usually the same as Amat) 2284 . J - function to compute matrix values, see SNESJacobianFunction() for details on its calling sequence 2285 - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL) 2286 2287 Notes: 2288 It is often better to provide the nonlinear function F() and some approximation to its Jacobian directly and use 2289 an approximate Newton solver. This interface is provided to allow porting/testing a previous Picard based code in PETSc before converting it to approximate Newton. 2290 2291 One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 2292 2293 $ Solves the equation A(x) x = bp(x) - b via the defect correction algorithm A(x^{n}) (x^{n+1} - x^{n}) = bp(x^{n}) + b - A(x^{n})x^{n} 2294 $ Note that when an exact solver is used this corresponds to the "classic" Picard A(x^{n}) x^{n+1} = bp(x^{n}) + b iteration. 2295 2296 Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 2297 2298 We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 2299 the direct Picard iteration A(x^n) x^{n+1} = bp(x^n) + b 2300 2301 There is some controversity over the definition of a Picard iteration for nonlinear systems but almost everyone agrees that it involves a linear solve and some 2302 believe it is the iteration A(x^{n}) x^{n+1} = b(x^{n}) hence we use the name Picard. If anyone has an authoritative reference that defines the Picard iteration 2303 different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 2304 2305 When used with -snes_mf_operator this will run matrix-free Newton's method where the matrix-vector product is of the true Jacobian of A(x)x - bp(x) -b. 2306 2307 When used with -snes_fd this will compute the true Jacobian (very slowly one column at at time) and thus represent Newton's method. 2308 2309 When used with -snes_fd_coloring this will compute the Jacobian via coloring and thus represent a faster implementation of Newton's method. But the 2310 the nonzero structure of the Jacobian is, in general larger than that of the Picard matrix A so you must provide in A the needed nonzero structure for the correct 2311 coloring. When using DMDA this may mean creating the matrix A with DMCreateMatrix() using a wider stencil than strictly needed for A or with a DMDA_STENCIL_BOX. 2312 See the commment in src/snes/tutorials/ex15.c. 2313 2314 Level: intermediate 2315 2316 .seealso: `SNESGetFunction()`, `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESGetPicard()`, `SNESLineSearchPreCheckPicard()`, `SNESJacobianFunction` 2317 @*/ 2318 PetscErrorCode SNESSetPicard(SNES snes,Vec r,PetscErrorCode (*bp)(SNES,Vec,Vec,void*),Mat Amat, Mat Pmat, PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx) 2319 { 2320 DM dm; 2321 2322 PetscFunctionBegin; 2323 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2324 PetscCall(SNESGetDM(snes, &dm)); 2325 PetscCall(DMSNESSetPicard(dm,bp,J,ctx)); 2326 PetscCall(DMSNESSetMFFunction(dm,SNESPicardComputeMFFunction,ctx)); 2327 PetscCall(SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx)); 2328 PetscCall(SNESSetJacobian(snes,Amat,Pmat,SNESPicardComputeJacobian,ctx)); 2329 PetscFunctionReturn(0); 2330 } 2331 2332 /*@C 2333 SNESGetPicard - Returns the context for the Picard iteration 2334 2335 Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 2336 2337 Input Parameter: 2338 . snes - the SNES context 2339 2340 Output Parameters: 2341 + r - the function (or NULL) 2342 . f - the function (or NULL); see SNESFunction for calling sequence details 2343 . Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL) 2344 . Pmat - the matrix from which the preconditioner will be constructed (or NULL) 2345 . J - the function for matrix evaluation (or NULL); see SNESJacobianFunction for calling sequence details 2346 - ctx - the function context (or NULL) 2347 2348 Level: advanced 2349 2350 .seealso: `SNESSetPicard()`, `SNESGetFunction()`, `SNESGetJacobian()`, `SNESGetDM()`, `SNESFunction`, `SNESJacobianFunction` 2351 @*/ 2352 PetscErrorCode SNESGetPicard(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),Mat *Amat, Mat *Pmat, PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx) 2353 { 2354 DM dm; 2355 2356 PetscFunctionBegin; 2357 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2358 PetscCall(SNESGetFunction(snes,r,NULL,NULL)); 2359 PetscCall(SNESGetJacobian(snes,Amat,Pmat,NULL,NULL)); 2360 PetscCall(SNESGetDM(snes,&dm)); 2361 PetscCall(DMSNESGetPicard(dm,f,J,ctx)); 2362 PetscFunctionReturn(0); 2363 } 2364 2365 /*@C 2366 SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 2367 2368 Logically Collective on SNES 2369 2370 Input Parameters: 2371 + snes - the SNES context 2372 . func - function evaluation routine 2373 - ctx - [optional] user-defined context for private data for the 2374 function evaluation routine (may be NULL) 2375 2376 Calling sequence of func: 2377 $ func (SNES snes,Vec x,void *ctx); 2378 2379 . f - function vector 2380 - ctx - optional user-defined function context 2381 2382 Level: intermediate 2383 2384 .seealso: `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()` 2385 @*/ 2386 PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 2387 { 2388 PetscFunctionBegin; 2389 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2390 if (func) snes->ops->computeinitialguess = func; 2391 if (ctx) snes->initialguessP = ctx; 2392 PetscFunctionReturn(0); 2393 } 2394 2395 /* --------------------------------------------------------------- */ 2396 /*@C 2397 SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 2398 it assumes a zero right hand side. 2399 2400 Logically Collective on SNES 2401 2402 Input Parameter: 2403 . snes - the SNES context 2404 2405 Output Parameter: 2406 . rhs - the right hand side vector or NULL if the right hand side vector is null 2407 2408 Level: intermediate 2409 2410 .seealso: `SNESGetSolution()`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetFunction()` 2411 @*/ 2412 PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 2413 { 2414 PetscFunctionBegin; 2415 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2416 PetscValidPointer(rhs,2); 2417 *rhs = snes->vec_rhs; 2418 PetscFunctionReturn(0); 2419 } 2420 2421 /*@ 2422 SNESComputeFunction - Calls the function that has been set with SNESSetFunction(). 2423 2424 Collective on SNES 2425 2426 Input Parameters: 2427 + snes - the SNES context 2428 - x - input vector 2429 2430 Output Parameter: 2431 . y - function vector, as set by SNESSetFunction() 2432 2433 Notes: 2434 SNESComputeFunction() is typically used within nonlinear solvers 2435 implementations, so users would not generally call this routine themselves. 2436 2437 Level: developer 2438 2439 .seealso: `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeMFFunction()` 2440 @*/ 2441 PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 2442 { 2443 DM dm; 2444 DMSNES sdm; 2445 2446 PetscFunctionBegin; 2447 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2448 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2449 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2450 PetscCheckSameComm(snes,1,x,2); 2451 PetscCheckSameComm(snes,1,y,3); 2452 PetscCall(VecValidValues(x,2,PETSC_TRUE)); 2453 2454 PetscCall(SNESGetDM(snes,&dm)); 2455 PetscCall(DMGetDMSNES(dm,&sdm)); 2456 if (sdm->ops->computefunction) { 2457 if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) { 2458 PetscCall(PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0)); 2459 } 2460 PetscCall(VecLockReadPush(x)); 2461 PetscStackPush("SNES user function"); 2462 /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */ 2463 snes->domainerror = PETSC_FALSE; 2464 PetscCall((*sdm->ops->computefunction)(snes,x,y,sdm->functionctx)); 2465 PetscStackPop; 2466 PetscCall(VecLockReadPop(x)); 2467 if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) { 2468 PetscCall(PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0)); 2469 } 2470 } else if (snes->vec_rhs) { 2471 PetscCall(MatMult(snes->jacobian, x, y)); 2472 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 2473 if (snes->vec_rhs) PetscCall(VecAXPY(y,-1.0,snes->vec_rhs)); 2474 snes->nfuncs++; 2475 /* 2476 domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2477 propagate the value to all processes 2478 */ 2479 if (snes->domainerror) PetscCall(VecSetInf(y)); 2480 PetscFunctionReturn(0); 2481 } 2482 2483 /*@ 2484 SNESComputeMFFunction - Calls the function that has been set with SNESSetMFFunction(). 2485 2486 Collective on SNES 2487 2488 Input Parameters: 2489 + snes - the SNES context 2490 - x - input vector 2491 2492 Output Parameter: 2493 . y - function vector, as set by SNESSetMFFunction() 2494 2495 Notes: 2496 SNESComputeMFFunction() is used within the matrix vector products called by the matrix created with MatCreateSNESMF() 2497 so users would not generally call this routine themselves. 2498 2499 Since this function is intended for use with finite differencing it does not subtract the right hand side vector provided with SNESSolve() 2500 while SNESComputeFunction() does. As such, this routine cannot be used with MatMFFDSetBase() with a provided F function value even if it applies the 2501 same function as SNESComputeFunction() if a SNESSolve() right hand side vector is use because the two functions difference would include this right hand side function. 2502 2503 Level: developer 2504 2505 .seealso: `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeFunction()`, `MatCreateSNESMF` 2506 @*/ 2507 PetscErrorCode SNESComputeMFFunction(SNES snes,Vec x,Vec y) 2508 { 2509 DM dm; 2510 DMSNES sdm; 2511 2512 PetscFunctionBegin; 2513 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2514 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2515 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2516 PetscCheckSameComm(snes,1,x,2); 2517 PetscCheckSameComm(snes,1,y,3); 2518 PetscCall(VecValidValues(x,2,PETSC_TRUE)); 2519 2520 PetscCall(SNESGetDM(snes,&dm)); 2521 PetscCall(DMGetDMSNES(dm,&sdm)); 2522 PetscCall(PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0)); 2523 PetscCall(VecLockReadPush(x)); 2524 PetscStackPush("SNES user function"); 2525 /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */ 2526 snes->domainerror = PETSC_FALSE; 2527 PetscCall((*sdm->ops->computemffunction)(snes,x,y,sdm->mffunctionctx)); 2528 PetscStackPop; 2529 PetscCall(VecLockReadPop(x)); 2530 PetscCall(PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0)); 2531 snes->nfuncs++; 2532 /* 2533 domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2534 propagate the value to all processes 2535 */ 2536 if (snes->domainerror) PetscCall(VecSetInf(y)); 2537 PetscFunctionReturn(0); 2538 } 2539 2540 /*@ 2541 SNESComputeNGS - Calls the Gauss-Seidel function that has been set with SNESSetNGS(). 2542 2543 Collective on SNES 2544 2545 Input Parameters: 2546 + snes - the SNES context 2547 . x - input vector 2548 - b - rhs vector 2549 2550 Output Parameter: 2551 . x - new solution vector 2552 2553 Notes: 2554 SNESComputeNGS() is typically used within composed nonlinear solver 2555 implementations, so most users would not generally call this routine 2556 themselves. 2557 2558 Level: developer 2559 2560 .seealso: `SNESSetNGS()`, `SNESComputeFunction()` 2561 @*/ 2562 PetscErrorCode SNESComputeNGS(SNES snes,Vec b,Vec x) 2563 { 2564 DM dm; 2565 DMSNES sdm; 2566 2567 PetscFunctionBegin; 2568 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2569 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 2570 if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 2571 PetscCheckSameComm(snes,1,x,3); 2572 if (b) PetscCheckSameComm(snes,1,b,2); 2573 if (b) PetscCall(VecValidValues(b,2,PETSC_TRUE)); 2574 PetscCall(PetscLogEventBegin(SNES_NGSEval,snes,x,b,0)); 2575 PetscCall(SNESGetDM(snes,&dm)); 2576 PetscCall(DMGetDMSNES(dm,&sdm)); 2577 if (sdm->ops->computegs) { 2578 if (b) PetscCall(VecLockReadPush(b)); 2579 PetscStackPush("SNES user NGS"); 2580 PetscCall((*sdm->ops->computegs)(snes,x,b,sdm->gsctx)); 2581 PetscStackPop; 2582 if (b) PetscCall(VecLockReadPop(b)); 2583 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve()."); 2584 PetscCall(PetscLogEventEnd(SNES_NGSEval,snes,x,b,0)); 2585 PetscFunctionReturn(0); 2586 } 2587 2588 PetscErrorCode SNESTestJacobian(SNES snes) 2589 { 2590 Mat A,B,C,D,jacobian; 2591 Vec x = snes->vec_sol,f = snes->vec_func; 2592 PetscReal nrm,gnorm; 2593 PetscReal threshold = 1.e-5; 2594 MatType mattype; 2595 PetscInt m,n,M,N; 2596 void *functx; 2597 PetscBool complete_print = PETSC_FALSE,threshold_print = PETSC_FALSE,test = PETSC_FALSE,flg,istranspose; 2598 PetscViewer viewer,mviewer; 2599 MPI_Comm comm; 2600 PetscInt tabs; 2601 static PetscBool directionsprinted = PETSC_FALSE; 2602 PetscViewerFormat format; 2603 2604 PetscFunctionBegin; 2605 PetscObjectOptionsBegin((PetscObject)snes); 2606 PetscCall(PetscOptionsName("-snes_test_jacobian","Compare hand-coded and finite difference Jacobians","None",&test)); 2607 PetscCall(PetscOptionsReal("-snes_test_jacobian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold,NULL)); 2608 PetscCall(PetscOptionsViewer("-snes_test_jacobian_view","View difference between hand-coded and finite difference Jacobians element entries","None",&mviewer,&format,&complete_print)); 2609 if (!complete_print) { 2610 PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display","-snes_test_jacobian_view","3.13",NULL)); 2611 PetscCall(PetscOptionsViewer("-snes_test_jacobian_display","Display difference between hand-coded and finite difference Jacobians","None",&mviewer,&format,&complete_print)); 2612 } 2613 /* for compatibility with PETSc 3.9 and older. */ 2614 PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display_threshold","-snes_test_jacobian","3.13","-snes_test_jacobian accepts an optional threshold (since v3.10)")); 2615 PetscCall(PetscOptionsReal("-snes_test_jacobian_display_threshold", "Display difference between hand-coded and finite difference Jacobians which exceed input threshold", "None", threshold, &threshold, &threshold_print)); 2616 PetscOptionsEnd(); 2617 if (!test) PetscFunctionReturn(0); 2618 2619 PetscCall(PetscObjectGetComm((PetscObject)snes,&comm)); 2620 PetscCall(PetscViewerASCIIGetStdout(comm,&viewer)); 2621 PetscCall(PetscViewerASCIIGetTab(viewer, &tabs)); 2622 PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel)); 2623 PetscCall(PetscViewerASCIIPrintf(viewer," ---------- Testing Jacobian -------------\n")); 2624 if (!complete_print && !directionsprinted) { 2625 PetscCall(PetscViewerASCIIPrintf(viewer," Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference\n")); 2626 PetscCall(PetscViewerASCIIPrintf(viewer," of hand-coded and finite difference Jacobian entries greater than <threshold>.\n")); 2627 } 2628 if (!directionsprinted) { 2629 PetscCall(PetscViewerASCIIPrintf(viewer," Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n")); 2630 PetscCall(PetscViewerASCIIPrintf(viewer," O(1.e-8), the hand-coded Jacobian is probably correct.\n")); 2631 directionsprinted = PETSC_TRUE; 2632 } 2633 if (complete_print) PetscCall(PetscViewerPushFormat(mviewer,format)); 2634 2635 PetscCall(PetscObjectTypeCompare((PetscObject)snes->jacobian,MATMFFD,&flg)); 2636 if (!flg) jacobian = snes->jacobian; 2637 else jacobian = snes->jacobian_pre; 2638 2639 if (!x) { 2640 PetscCall(MatCreateVecs(jacobian, &x, NULL)); 2641 } else { 2642 PetscCall(PetscObjectReference((PetscObject) x)); 2643 } 2644 if (!f) { 2645 PetscCall(VecDuplicate(x, &f)); 2646 } else { 2647 PetscCall(PetscObjectReference((PetscObject) f)); 2648 } 2649 /* evaluate the function at this point because SNESComputeJacobianDefault() assumes that the function has been evaluated and put into snes->vec_func */ 2650 PetscCall(SNESComputeFunction(snes,x,f)); 2651 PetscCall(VecDestroy(&f)); 2652 PetscCall(PetscObjectTypeCompare((PetscObject)snes,SNESKSPTRANSPOSEONLY,&istranspose)); 2653 while (jacobian) { 2654 Mat JT = NULL, Jsave = NULL; 2655 2656 if (istranspose) { 2657 PetscCall(MatCreateTranspose(jacobian,&JT)); 2658 Jsave = jacobian; 2659 jacobian = JT; 2660 } 2661 PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)jacobian,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPISBAIJ,"")); 2662 if (flg) { 2663 A = jacobian; 2664 PetscCall(PetscObjectReference((PetscObject)A)); 2665 } else { 2666 PetscCall(MatComputeOperator(jacobian,MATAIJ,&A)); 2667 } 2668 2669 PetscCall(MatGetType(A,&mattype)); 2670 PetscCall(MatGetSize(A,&M,&N)); 2671 PetscCall(MatGetLocalSize(A,&m,&n)); 2672 PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&B)); 2673 PetscCall(MatSetType(B,mattype)); 2674 PetscCall(MatSetSizes(B,m,n,M,N)); 2675 PetscCall(MatSetBlockSizesFromMats(B,A,A)); 2676 PetscCall(MatSetUp(B)); 2677 PetscCall(MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE)); 2678 2679 PetscCall(SNESGetFunction(snes,NULL,NULL,&functx)); 2680 PetscCall(SNESComputeJacobianDefault(snes,x,B,B,functx)); 2681 2682 PetscCall(MatDuplicate(B,MAT_COPY_VALUES,&D)); 2683 PetscCall(MatAYPX(D,-1.0,A,DIFFERENT_NONZERO_PATTERN)); 2684 PetscCall(MatNorm(D,NORM_FROBENIUS,&nrm)); 2685 PetscCall(MatNorm(A,NORM_FROBENIUS,&gnorm)); 2686 PetscCall(MatDestroy(&D)); 2687 if (!gnorm) gnorm = 1; /* just in case */ 2688 PetscCall(PetscViewerASCIIPrintf(viewer," ||J - Jfd||_F/||J||_F = %g, ||J - Jfd||_F = %g\n",(double)(nrm/gnorm),(double)nrm)); 2689 2690 if (complete_print) { 2691 PetscCall(PetscViewerASCIIPrintf(viewer," Hand-coded Jacobian ----------\n")); 2692 PetscCall(MatView(A,mviewer)); 2693 PetscCall(PetscViewerASCIIPrintf(viewer," Finite difference Jacobian ----------\n")); 2694 PetscCall(MatView(B,mviewer)); 2695 } 2696 2697 if (threshold_print || complete_print) { 2698 PetscInt Istart, Iend, *ccols, bncols, cncols, j, row; 2699 PetscScalar *cvals; 2700 const PetscInt *bcols; 2701 const PetscScalar *bvals; 2702 2703 PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&C)); 2704 PetscCall(MatSetType(C,mattype)); 2705 PetscCall(MatSetSizes(C,m,n,M,N)); 2706 PetscCall(MatSetBlockSizesFromMats(C,A,A)); 2707 PetscCall(MatSetUp(C)); 2708 PetscCall(MatSetOption(C,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE)); 2709 2710 PetscCall(MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN)); 2711 PetscCall(MatGetOwnershipRange(B,&Istart,&Iend)); 2712 2713 for (row = Istart; row < Iend; row++) { 2714 PetscCall(MatGetRow(B,row,&bncols,&bcols,&bvals)); 2715 PetscCall(PetscMalloc2(bncols,&ccols,bncols,&cvals)); 2716 for (j = 0, cncols = 0; j < bncols; j++) { 2717 if (PetscAbsScalar(bvals[j]) > threshold) { 2718 ccols[cncols] = bcols[j]; 2719 cvals[cncols] = bvals[j]; 2720 cncols += 1; 2721 } 2722 } 2723 if (cncols) { 2724 PetscCall(MatSetValues(C,1,&row,cncols,ccols,cvals,INSERT_VALUES)); 2725 } 2726 PetscCall(MatRestoreRow(B,row,&bncols,&bcols,&bvals)); 2727 PetscCall(PetscFree2(ccols,cvals)); 2728 } 2729 PetscCall(MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY)); 2730 PetscCall(MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY)); 2731 PetscCall(PetscViewerASCIIPrintf(viewer," Hand-coded minus finite-difference Jacobian with tolerance %g ----------\n",(double)threshold)); 2732 PetscCall(MatView(C,complete_print ? mviewer : viewer)); 2733 PetscCall(MatDestroy(&C)); 2734 } 2735 PetscCall(MatDestroy(&A)); 2736 PetscCall(MatDestroy(&B)); 2737 PetscCall(MatDestroy(&JT)); 2738 if (Jsave) jacobian = Jsave; 2739 if (jacobian != snes->jacobian_pre) { 2740 jacobian = snes->jacobian_pre; 2741 PetscCall(PetscViewerASCIIPrintf(viewer," ---------- Testing Jacobian for preconditioner -------------\n")); 2742 } 2743 else jacobian = NULL; 2744 } 2745 PetscCall(VecDestroy(&x)); 2746 if (complete_print) PetscCall(PetscViewerPopFormat(mviewer)); 2747 if (mviewer) PetscCall(PetscViewerDestroy(&mviewer)); 2748 PetscCall(PetscViewerASCIISetTab(viewer,tabs)); 2749 PetscFunctionReturn(0); 2750 } 2751 2752 /*@ 2753 SNESComputeJacobian - Computes the Jacobian matrix that has been set with SNESSetJacobian(). 2754 2755 Collective on SNES 2756 2757 Input Parameters: 2758 + snes - the SNES context 2759 - x - input vector 2760 2761 Output Parameters: 2762 + A - Jacobian matrix 2763 - B - optional preconditioning matrix 2764 2765 Options Database Keys: 2766 + -snes_lag_preconditioner <lag> - how often to rebuild preconditioner 2767 . -snes_lag_jacobian <lag> - how often to rebuild Jacobian 2768 . -snes_test_jacobian <optional threshold> - compare the user provided Jacobian with one compute via finite differences to check for errors. If a threshold is given, display only those entries whose difference is greater than the threshold. 2769 . -snes_test_jacobian_view - display the user provided Jacobian, the finite difference Jacobian and the difference between them to help users detect the location of errors in the user provided Jacobian 2770 . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 2771 . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 2772 . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 2773 . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 2774 . -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference 2775 . -snes_compare_coloring_display - Compute the finite difference Jacobian using coloring and display verbose differences 2776 . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 2777 . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2778 . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2779 . -snes_compare_coloring_draw - Compute the finite difference Jacobian using coloring and draw differences 2780 - -snes_compare_coloring_draw_contour - Compute the finite difference Jacobian using coloring and show contours of matrices and differences 2781 2782 Notes: 2783 Most users should not need to explicitly call this routine, as it 2784 is used internally within the nonlinear solvers. 2785 2786 Developer Notes: 2787 This has duplicative ways of checking the accuracy of the user provided Jacobian (see the options above). This is for historical reasons, the routine SNESTestJacobian() use to used 2788 for with the SNESType of test that has been removed. 2789 2790 Level: developer 2791 2792 .seealso: `SNESSetJacobian()`, `KSPSetOperators()`, `MatStructure`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()` 2793 @*/ 2794 PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat A,Mat B) 2795 { 2796 PetscBool flag; 2797 DM dm; 2798 DMSNES sdm; 2799 KSP ksp; 2800 2801 PetscFunctionBegin; 2802 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2803 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 2804 PetscCheckSameComm(snes,1,X,2); 2805 PetscCall(VecValidValues(X,2,PETSC_TRUE)); 2806 PetscCall(SNESGetDM(snes,&dm)); 2807 PetscCall(DMGetDMSNES(dm,&sdm)); 2808 2809 PetscCheck(sdm->ops->computejacobian,PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 2810 2811 /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 2812 2813 if (snes->lagjacobian == -2) { 2814 snes->lagjacobian = -1; 2815 2816 PetscCall(PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n")); 2817 } else if (snes->lagjacobian == -1) { 2818 PetscCall(PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n")); 2819 PetscCall(PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag)); 2820 if (flag) { 2821 PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); 2822 PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); 2823 } 2824 PetscFunctionReturn(0); 2825 } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) { 2826 PetscCall(PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n",snes->lagjacobian,snes->iter)); 2827 PetscCall(PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag)); 2828 if (flag) { 2829 PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); 2830 PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); 2831 } 2832 PetscFunctionReturn(0); 2833 } 2834 if (snes->npc && snes->npcside == PC_LEFT) { 2835 PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); 2836 PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); 2837 PetscFunctionReturn(0); 2838 } 2839 2840 PetscCall(PetscLogEventBegin(SNES_JacobianEval,snes,X,A,B)); 2841 PetscCall(VecLockReadPush(X)); 2842 PetscStackPush("SNES user Jacobian function"); 2843 PetscCall((*sdm->ops->computejacobian)(snes,X,A,B,sdm->jacobianctx)); 2844 PetscStackPop; 2845 PetscCall(VecLockReadPop(X)); 2846 PetscCall(PetscLogEventEnd(SNES_JacobianEval,snes,X,A,B)); 2847 2848 /* attach latest linearization point to the preconditioning matrix */ 2849 PetscCall(PetscObjectCompose((PetscObject)B,"__SNES_latest_X",(PetscObject)X)); 2850 2851 /* the next line ensures that snes->ksp exists */ 2852 PetscCall(SNESGetKSP(snes,&ksp)); 2853 if (snes->lagpreconditioner == -2) { 2854 PetscCall(PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n")); 2855 PetscCall(KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE)); 2856 snes->lagpreconditioner = -1; 2857 } else if (snes->lagpreconditioner == -1) { 2858 PetscCall(PetscInfo(snes,"Reusing preconditioner because lag is -1\n")); 2859 PetscCall(KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE)); 2860 } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) { 2861 PetscCall(PetscInfo(snes,"Reusing preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n",snes->lagpreconditioner,snes->iter)); 2862 PetscCall(KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE)); 2863 } else { 2864 PetscCall(PetscInfo(snes,"Rebuilding preconditioner\n")); 2865 PetscCall(KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE)); 2866 } 2867 2868 PetscCall(SNESTestJacobian(snes)); 2869 /* make sure user returned a correct Jacobian and preconditioner */ 2870 /* PetscValidHeaderSpecific(A,MAT_CLASSID,3); 2871 PetscValidHeaderSpecific(B,MAT_CLASSID,4); */ 2872 { 2873 PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 2874 PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit",NULL,NULL,&flag)); 2875 PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",NULL,NULL,&flag_draw)); 2876 PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",NULL,NULL,&flag_contour)); 2877 PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_operator",NULL,NULL,&flag_operator)); 2878 if (flag || flag_draw || flag_contour) { 2879 Mat Bexp_mine = NULL,Bexp,FDexp; 2880 PetscViewer vdraw,vstdout; 2881 PetscBool flg; 2882 if (flag_operator) { 2883 PetscCall(MatComputeOperator(A,MATAIJ,&Bexp_mine)); 2884 Bexp = Bexp_mine; 2885 } else { 2886 /* See if the preconditioning matrix can be viewed and added directly */ 2887 PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"")); 2888 if (flg) Bexp = B; 2889 else { 2890 /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 2891 PetscCall(MatComputeOperator(B,MATAIJ,&Bexp_mine)); 2892 Bexp = Bexp_mine; 2893 } 2894 } 2895 PetscCall(MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp)); 2896 PetscCall(SNESComputeJacobianDefault(snes,X,FDexp,FDexp,NULL)); 2897 PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout)); 2898 if (flag_draw || flag_contour) { 2899 PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw)); 2900 if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR)); 2901 } else vdraw = NULL; 2902 PetscCall(PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator ? "Jacobian" : "preconditioning Jacobian")); 2903 if (flag) PetscCall(MatView(Bexp,vstdout)); 2904 if (vdraw) PetscCall(MatView(Bexp,vdraw)); 2905 PetscCall(PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n")); 2906 if (flag) PetscCall(MatView(FDexp,vstdout)); 2907 if (vdraw) PetscCall(MatView(FDexp,vdraw)); 2908 PetscCall(MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN)); 2909 PetscCall(PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n")); 2910 if (flag) PetscCall(MatView(FDexp,vstdout)); 2911 if (vdraw) { /* Always use contour for the difference */ 2912 PetscCall(PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR)); 2913 PetscCall(MatView(FDexp,vdraw)); 2914 PetscCall(PetscViewerPopFormat(vdraw)); 2915 } 2916 if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw)); 2917 PetscCall(PetscViewerDestroy(&vdraw)); 2918 PetscCall(MatDestroy(&Bexp_mine)); 2919 PetscCall(MatDestroy(&FDexp)); 2920 } 2921 } 2922 { 2923 PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 2924 PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 2925 PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring",NULL,NULL,&flag)); 2926 PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_display",NULL,NULL,&flag_display)); 2927 PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",NULL,NULL,&flag_draw)); 2928 PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",NULL,NULL,&flag_contour)); 2929 PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",NULL,NULL,&flag_threshold)); 2930 if (flag_threshold) { 2931 PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,NULL)); 2932 PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,NULL)); 2933 } 2934 if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 2935 Mat Bfd; 2936 PetscViewer vdraw,vstdout; 2937 MatColoring coloring; 2938 ISColoring iscoloring; 2939 MatFDColoring matfdcoloring; 2940 PetscErrorCode (*func)(SNES,Vec,Vec,void*); 2941 void *funcctx; 2942 PetscReal norm1,norm2,normmax; 2943 2944 PetscCall(MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&Bfd)); 2945 PetscCall(MatColoringCreate(Bfd,&coloring)); 2946 PetscCall(MatColoringSetType(coloring,MATCOLORINGSL)); 2947 PetscCall(MatColoringSetFromOptions(coloring)); 2948 PetscCall(MatColoringApply(coloring,&iscoloring)); 2949 PetscCall(MatColoringDestroy(&coloring)); 2950 PetscCall(MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring)); 2951 PetscCall(MatFDColoringSetFromOptions(matfdcoloring)); 2952 PetscCall(MatFDColoringSetUp(Bfd,iscoloring,matfdcoloring)); 2953 PetscCall(ISColoringDestroy(&iscoloring)); 2954 2955 /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 2956 PetscCall(SNESGetFunction(snes,NULL,&func,&funcctx)); 2957 PetscCall(MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))func,funcctx)); 2958 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix)); 2959 PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_")); 2960 PetscCall(MatFDColoringSetFromOptions(matfdcoloring)); 2961 PetscCall(MatFDColoringApply(Bfd,matfdcoloring,X,snes)); 2962 PetscCall(MatFDColoringDestroy(&matfdcoloring)); 2963 2964 PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout)); 2965 if (flag_draw || flag_contour) { 2966 PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw)); 2967 if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR)); 2968 } else vdraw = NULL; 2969 PetscCall(PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n")); 2970 if (flag_display) PetscCall(MatView(B,vstdout)); 2971 if (vdraw) PetscCall(MatView(B,vdraw)); 2972 PetscCall(PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n")); 2973 if (flag_display) PetscCall(MatView(Bfd,vstdout)); 2974 if (vdraw) PetscCall(MatView(Bfd,vdraw)); 2975 PetscCall(MatAYPX(Bfd,-1.0,B,SAME_NONZERO_PATTERN)); 2976 PetscCall(MatNorm(Bfd,NORM_1,&norm1)); 2977 PetscCall(MatNorm(Bfd,NORM_FROBENIUS,&norm2)); 2978 PetscCall(MatNorm(Bfd,NORM_MAX,&normmax)); 2979 PetscCall(PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%g normFrob=%g normmax=%g\n",(double)norm1,(double)norm2,(double)normmax)); 2980 if (flag_display) PetscCall(MatView(Bfd,vstdout)); 2981 if (vdraw) { /* Always use contour for the difference */ 2982 PetscCall(PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR)); 2983 PetscCall(MatView(Bfd,vdraw)); 2984 PetscCall(PetscViewerPopFormat(vdraw)); 2985 } 2986 if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw)); 2987 2988 if (flag_threshold) { 2989 PetscInt bs,rstart,rend,i; 2990 PetscCall(MatGetBlockSize(B,&bs)); 2991 PetscCall(MatGetOwnershipRange(B,&rstart,&rend)); 2992 for (i=rstart; i<rend; i++) { 2993 const PetscScalar *ba,*ca; 2994 const PetscInt *bj,*cj; 2995 PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 2996 PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 2997 PetscCall(MatGetRow(B,i,&bn,&bj,&ba)); 2998 PetscCall(MatGetRow(Bfd,i,&cn,&cj,&ca)); 2999 PetscCheck(bn == cn,((PetscObject)A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 3000 for (j=0; j<bn; j++) { 3001 PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 3002 if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 3003 maxentrycol = bj[j]; 3004 maxentry = PetscRealPart(ba[j]); 3005 } 3006 if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 3007 maxdiffcol = bj[j]; 3008 maxdiff = PetscRealPart(ca[j]); 3009 } 3010 if (rdiff > maxrdiff) { 3011 maxrdiffcol = bj[j]; 3012 maxrdiff = rdiff; 3013 } 3014 } 3015 if (maxrdiff > 1) { 3016 PetscCall(PetscViewerASCIIPrintf(vstdout,"row %" PetscInt_FMT " (maxentry=%g at %" PetscInt_FMT ", maxdiff=%g at %" PetscInt_FMT ", maxrdiff=%g at %" PetscInt_FMT "):",i,(double)maxentry,maxentrycol,(double)maxdiff,maxdiffcol,(double)maxrdiff,maxrdiffcol)); 3017 for (j=0; j<bn; j++) { 3018 PetscReal rdiff; 3019 rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 3020 if (rdiff > 1) { 3021 PetscCall(PetscViewerASCIIPrintf(vstdout," (%" PetscInt_FMT ",%g:%g)",bj[j],(double)PetscRealPart(ba[j]),(double)PetscRealPart(ca[j]))); 3022 } 3023 } 3024 PetscCall(PetscViewerASCIIPrintf(vstdout,"\n")); 3025 } 3026 PetscCall(MatRestoreRow(B,i,&bn,&bj,&ba)); 3027 PetscCall(MatRestoreRow(Bfd,i,&cn,&cj,&ca)); 3028 } 3029 } 3030 PetscCall(PetscViewerDestroy(&vdraw)); 3031 PetscCall(MatDestroy(&Bfd)); 3032 } 3033 } 3034 PetscFunctionReturn(0); 3035 } 3036 3037 /*MC 3038 SNESJacobianFunction - Function used to convey the nonlinear Jacobian of the function to be solved by SNES 3039 3040 Synopsis: 3041 #include "petscsnes.h" 3042 PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx); 3043 3044 Collective on snes 3045 3046 Input Parameters: 3047 + x - input vector, the Jacobian is to be computed at this value 3048 - ctx - [optional] user-defined Jacobian context 3049 3050 Output Parameters: 3051 + Amat - the matrix that defines the (approximate) Jacobian 3052 - Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 3053 3054 Level: intermediate 3055 3056 .seealso: `SNESSetFunction()`, `SNESGetFunction()`, `SNESSetJacobian()`, `SNESGetJacobian()` 3057 M*/ 3058 3059 /*@C 3060 SNESSetJacobian - Sets the function to compute Jacobian as well as the 3061 location to store the matrix. 3062 3063 Logically Collective on SNES 3064 3065 Input Parameters: 3066 + snes - the SNES context 3067 . Amat - the matrix that defines the (approximate) Jacobian 3068 . Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 3069 . J - Jacobian evaluation routine (if NULL then SNES retains any previously set value), see SNESJacobianFunction for details 3070 - ctx - [optional] user-defined context for private data for the 3071 Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value) 3072 3073 Notes: 3074 If the Amat matrix and Pmat matrix are different you must call MatAssemblyBegin/End() on 3075 each matrix. 3076 3077 If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null 3078 space to Amat and the KSP solvers will automatically use that null space as needed during the solution process. 3079 3080 If using SNESComputeJacobianDefaultColor() to assemble a Jacobian, the ctx argument 3081 must be a MatFDColoring. 3082 3083 Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 3084 example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 3085 3086 Level: beginner 3087 3088 .seealso: `KSPSetOperators()`, `SNESSetFunction()`, `MatMFFDComputeJacobian()`, `SNESComputeJacobianDefaultColor()`, `MatStructure`, `J`, 3089 `SNESSetPicard()`, `SNESJacobianFunction` 3090 @*/ 3091 PetscErrorCode SNESSetJacobian(SNES snes,Mat Amat,Mat Pmat,PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx) 3092 { 3093 DM dm; 3094 3095 PetscFunctionBegin; 3096 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3097 if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 3098 if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 3099 if (Amat) PetscCheckSameComm(snes,1,Amat,2); 3100 if (Pmat) PetscCheckSameComm(snes,1,Pmat,3); 3101 PetscCall(SNESGetDM(snes,&dm)); 3102 PetscCall(DMSNESSetJacobian(dm,J,ctx)); 3103 if (Amat) { 3104 PetscCall(PetscObjectReference((PetscObject)Amat)); 3105 PetscCall(MatDestroy(&snes->jacobian)); 3106 3107 snes->jacobian = Amat; 3108 } 3109 if (Pmat) { 3110 PetscCall(PetscObjectReference((PetscObject)Pmat)); 3111 PetscCall(MatDestroy(&snes->jacobian_pre)); 3112 3113 snes->jacobian_pre = Pmat; 3114 } 3115 PetscFunctionReturn(0); 3116 } 3117 3118 /*@C 3119 SNESGetJacobian - Returns the Jacobian matrix and optionally the user 3120 provided context for evaluating the Jacobian. 3121 3122 Not Collective, but Mat object will be parallel if SNES object is 3123 3124 Input Parameter: 3125 . snes - the nonlinear solver context 3126 3127 Output Parameters: 3128 + Amat - location to stash (approximate) Jacobian matrix (or NULL) 3129 . Pmat - location to stash matrix used to compute the preconditioner (or NULL) 3130 . J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence 3131 - ctx - location to stash Jacobian ctx (or NULL) 3132 3133 Level: advanced 3134 3135 .seealso: `SNESSetJacobian()`, `SNESComputeJacobian()`, `SNESJacobianFunction`, `SNESGetFunction()` 3136 @*/ 3137 PetscErrorCode SNESGetJacobian(SNES snes,Mat *Amat,Mat *Pmat,PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx) 3138 { 3139 DM dm; 3140 DMSNES sdm; 3141 3142 PetscFunctionBegin; 3143 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3144 if (Amat) *Amat = snes->jacobian; 3145 if (Pmat) *Pmat = snes->jacobian_pre; 3146 PetscCall(SNESGetDM(snes,&dm)); 3147 PetscCall(DMGetDMSNES(dm,&sdm)); 3148 if (J) *J = sdm->ops->computejacobian; 3149 if (ctx) *ctx = sdm->jacobianctx; 3150 PetscFunctionReturn(0); 3151 } 3152 3153 static PetscErrorCode SNESSetDefaultComputeJacobian(SNES snes) 3154 { 3155 DM dm; 3156 DMSNES sdm; 3157 3158 PetscFunctionBegin; 3159 PetscCall(SNESGetDM(snes,&dm)); 3160 PetscCall(DMGetDMSNES(dm,&sdm)); 3161 if (!sdm->ops->computejacobian && snes->jacobian_pre) { 3162 DM dm; 3163 PetscBool isdense,ismf; 3164 3165 PetscCall(SNESGetDM(snes,&dm)); 3166 PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre,&isdense,MATSEQDENSE,MATMPIDENSE,MATDENSE,NULL)); 3167 PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre,&ismf,MATMFFD,MATSHELL,NULL)); 3168 if (isdense) { 3169 PetscCall(DMSNESSetJacobian(dm,SNESComputeJacobianDefault,NULL)); 3170 } else if (!ismf) { 3171 PetscCall(DMSNESSetJacobian(dm,SNESComputeJacobianDefaultColor,NULL)); 3172 } 3173 } 3174 PetscFunctionReturn(0); 3175 } 3176 3177 /*@ 3178 SNESSetUp - Sets up the internal data structures for the later use 3179 of a nonlinear solver. 3180 3181 Collective on SNES 3182 3183 Input Parameters: 3184 . snes - the SNES context 3185 3186 Notes: 3187 For basic use of the SNES solvers the user need not explicitly call 3188 SNESSetUp(), since these actions will automatically occur during 3189 the call to SNESSolve(). However, if one wishes to control this 3190 phase separately, SNESSetUp() should be called after SNESCreate() 3191 and optional routines of the form SNESSetXXX(), but before SNESSolve(). 3192 3193 Level: advanced 3194 3195 .seealso: `SNESCreate()`, `SNESSolve()`, `SNESDestroy()` 3196 @*/ 3197 PetscErrorCode SNESSetUp(SNES snes) 3198 { 3199 DM dm; 3200 DMSNES sdm; 3201 SNESLineSearch linesearch, pclinesearch; 3202 void *lsprectx,*lspostctx; 3203 PetscErrorCode (*precheck)(SNESLineSearch,Vec,Vec,PetscBool*,void*); 3204 PetscErrorCode (*postcheck)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*); 3205 PetscErrorCode (*func)(SNES,Vec,Vec,void*); 3206 Vec f,fpc; 3207 void *funcctx; 3208 PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*); 3209 void *jacctx,*appctx; 3210 Mat j,jpre; 3211 3212 PetscFunctionBegin; 3213 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3214 if (snes->setupcalled) PetscFunctionReturn(0); 3215 PetscCall(PetscLogEventBegin(SNES_Setup,snes,0,0,0)); 3216 3217 if (!((PetscObject)snes)->type_name) { 3218 PetscCall(SNESSetType(snes,SNESNEWTONLS)); 3219 } 3220 3221 PetscCall(SNESGetFunction(snes,&snes->vec_func,NULL,NULL)); 3222 3223 PetscCall(SNESGetDM(snes,&dm)); 3224 PetscCall(DMGetDMSNES(dm,&sdm)); 3225 PetscCheck(sdm->ops->computefunction,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Function never provided to SNES object"); 3226 PetscCall(SNESSetDefaultComputeJacobian(snes)); 3227 3228 if (!snes->vec_func) { 3229 PetscCall(DMCreateGlobalVector(dm,&snes->vec_func)); 3230 } 3231 3232 if (!snes->ksp) { 3233 PetscCall(SNESGetKSP(snes, &snes->ksp)); 3234 } 3235 3236 if (snes->linesearch) { 3237 PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 3238 PetscCall(SNESLineSearchSetFunction(snes->linesearch,SNESComputeFunction)); 3239 } 3240 3241 if (snes->npc && snes->npcside == PC_LEFT) { 3242 snes->mf = PETSC_TRUE; 3243 snes->mf_operator = PETSC_FALSE; 3244 } 3245 3246 if (snes->npc) { 3247 /* copy the DM over */ 3248 PetscCall(SNESGetDM(snes,&dm)); 3249 PetscCall(SNESSetDM(snes->npc,dm)); 3250 3251 PetscCall(SNESGetFunction(snes,&f,&func,&funcctx)); 3252 PetscCall(VecDuplicate(f,&fpc)); 3253 PetscCall(SNESSetFunction(snes->npc,fpc,func,funcctx)); 3254 PetscCall(SNESGetJacobian(snes,&j,&jpre,&jac,&jacctx)); 3255 PetscCall(SNESSetJacobian(snes->npc,j,jpre,jac,jacctx)); 3256 PetscCall(SNESGetApplicationContext(snes,&appctx)); 3257 PetscCall(SNESSetApplicationContext(snes->npc,appctx)); 3258 PetscCall(VecDestroy(&fpc)); 3259 3260 /* copy the function pointers over */ 3261 PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->npc)); 3262 3263 /* default to 1 iteration */ 3264 PetscCall(SNESSetTolerances(snes->npc,0.0,0.0,0.0,1,snes->npc->max_funcs)); 3265 if (snes->npcside == PC_RIGHT) { 3266 PetscCall(SNESSetNormSchedule(snes->npc,SNES_NORM_FINAL_ONLY)); 3267 } else { 3268 PetscCall(SNESSetNormSchedule(snes->npc,SNES_NORM_NONE)); 3269 } 3270 PetscCall(SNESSetFromOptions(snes->npc)); 3271 3272 /* copy the line search context over */ 3273 if (snes->linesearch && snes->npc->linesearch) { 3274 PetscCall(SNESGetLineSearch(snes,&linesearch)); 3275 PetscCall(SNESGetLineSearch(snes->npc,&pclinesearch)); 3276 PetscCall(SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx)); 3277 PetscCall(SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx)); 3278 PetscCall(SNESLineSearchSetPreCheck(pclinesearch,precheck,lsprectx)); 3279 PetscCall(SNESLineSearchSetPostCheck(pclinesearch,postcheck,lspostctx)); 3280 PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch)); 3281 } 3282 } 3283 if (snes->mf) PetscCall(SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version)); 3284 if (snes->ops->usercompute && !snes->user) { 3285 PetscCall((*snes->ops->usercompute)(snes,(void**)&snes->user)); 3286 } 3287 3288 snes->jac_iter = 0; 3289 snes->pre_iter = 0; 3290 3291 if (snes->ops->setup) PetscCall((*snes->ops->setup)(snes)); 3292 3293 PetscCall(SNESSetDefaultComputeJacobian(snes)); 3294 3295 if (snes->npc && snes->npcside == PC_LEFT) { 3296 if (snes->functype == SNES_FUNCTION_PRECONDITIONED) { 3297 if (snes->linesearch) { 3298 PetscCall(SNESGetLineSearch(snes,&linesearch)); 3299 PetscCall(SNESLineSearchSetFunction(linesearch,SNESComputeFunctionDefaultNPC)); 3300 } 3301 } 3302 } 3303 PetscCall(PetscLogEventEnd(SNES_Setup,snes,0,0,0)); 3304 snes->setupcalled = PETSC_TRUE; 3305 PetscFunctionReturn(0); 3306 } 3307 3308 /*@ 3309 SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 3310 3311 Collective on SNES 3312 3313 Input Parameter: 3314 . snes - iterative context obtained from SNESCreate() 3315 3316 Level: intermediate 3317 3318 Notes: 3319 Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 3320 3321 .seealso: `SNESCreate()`, `SNESSetUp()`, `SNESSolve()` 3322 @*/ 3323 PetscErrorCode SNESReset(SNES snes) 3324 { 3325 PetscFunctionBegin; 3326 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3327 if (snes->ops->userdestroy && snes->user) { 3328 PetscCall((*snes->ops->userdestroy)((void**)&snes->user)); 3329 snes->user = NULL; 3330 } 3331 if (snes->npc) PetscCall(SNESReset(snes->npc)); 3332 3333 if (snes->ops->reset) PetscCall((*snes->ops->reset)(snes)); 3334 if (snes->ksp) PetscCall(KSPReset(snes->ksp)); 3335 3336 if (snes->linesearch) PetscCall(SNESLineSearchReset(snes->linesearch)); 3337 3338 PetscCall(VecDestroy(&snes->vec_rhs)); 3339 PetscCall(VecDestroy(&snes->vec_sol)); 3340 PetscCall(VecDestroy(&snes->vec_sol_update)); 3341 PetscCall(VecDestroy(&snes->vec_func)); 3342 PetscCall(MatDestroy(&snes->jacobian)); 3343 PetscCall(MatDestroy(&snes->jacobian_pre)); 3344 PetscCall(MatDestroy(&snes->picard)); 3345 PetscCall(VecDestroyVecs(snes->nwork,&snes->work)); 3346 PetscCall(VecDestroyVecs(snes->nvwork,&snes->vwork)); 3347 3348 snes->alwayscomputesfinalresidual = PETSC_FALSE; 3349 3350 snes->nwork = snes->nvwork = 0; 3351 snes->setupcalled = PETSC_FALSE; 3352 PetscFunctionReturn(0); 3353 } 3354 3355 /*@ 3356 SNESConvergedReasonViewCancel - Clears all the reasonview functions for a SNES object. 3357 3358 Collective on SNES 3359 3360 Input Parameter: 3361 . snes - iterative context obtained from SNESCreate() 3362 3363 Level: intermediate 3364 3365 .seealso: `SNESCreate()`, `SNESDestroy()`, `SNESReset()` 3366 @*/ 3367 PetscErrorCode SNESConvergedReasonViewCancel(SNES snes) 3368 { 3369 PetscInt i; 3370 3371 PetscFunctionBegin; 3372 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3373 for (i=0; i<snes->numberreasonviews; i++) { 3374 if (snes->reasonviewdestroy[i]) { 3375 PetscCall((*snes->reasonviewdestroy[i])(&snes->reasonviewcontext[i])); 3376 } 3377 } 3378 snes->numberreasonviews = 0; 3379 PetscFunctionReturn(0); 3380 } 3381 3382 /*@C 3383 SNESDestroy - Destroys the nonlinear solver context that was created 3384 with SNESCreate(). 3385 3386 Collective on SNES 3387 3388 Input Parameter: 3389 . snes - the SNES context 3390 3391 Level: beginner 3392 3393 .seealso: `SNESCreate()`, `SNESSolve()` 3394 @*/ 3395 PetscErrorCode SNESDestroy(SNES *snes) 3396 { 3397 PetscFunctionBegin; 3398 if (!*snes) PetscFunctionReturn(0); 3399 PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 3400 if (--((PetscObject)(*snes))->refct > 0) {*snes = NULL; PetscFunctionReturn(0);} 3401 3402 PetscCall(SNESReset((*snes))); 3403 PetscCall(SNESDestroy(&(*snes)->npc)); 3404 3405 /* if memory was published with SAWs then destroy it */ 3406 PetscCall(PetscObjectSAWsViewOff((PetscObject)*snes)); 3407 if ((*snes)->ops->destroy) PetscCall((*((*snes))->ops->destroy)((*snes))); 3408 3409 if ((*snes)->dm) PetscCall(DMCoarsenHookRemove((*snes)->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,*snes)); 3410 PetscCall(DMDestroy(&(*snes)->dm)); 3411 PetscCall(KSPDestroy(&(*snes)->ksp)); 3412 PetscCall(SNESLineSearchDestroy(&(*snes)->linesearch)); 3413 3414 PetscCall(PetscFree((*snes)->kspconvctx)); 3415 if ((*snes)->ops->convergeddestroy) { 3416 PetscCall((*(*snes)->ops->convergeddestroy)((*snes)->cnvP)); 3417 } 3418 if ((*snes)->conv_hist_alloc) { 3419 PetscCall(PetscFree2((*snes)->conv_hist,(*snes)->conv_hist_its)); 3420 } 3421 PetscCall(SNESMonitorCancel((*snes))); 3422 PetscCall(SNESConvergedReasonViewCancel((*snes))); 3423 PetscCall(PetscHeaderDestroy(snes)); 3424 PetscFunctionReturn(0); 3425 } 3426 3427 /* ----------- Routines to set solver parameters ---------- */ 3428 3429 /*@ 3430 SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 3431 3432 Logically Collective on SNES 3433 3434 Input Parameters: 3435 + snes - the SNES context 3436 - lag - 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 3437 the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3438 3439 Options Database Keys: 3440 + -snes_lag_jacobian_persists <true,false> - sets the persistence 3441 . -snes_lag_jacobian <-2,1,2,...> - sets the lag 3442 . -snes_lag_preconditioner_persists <true,false> - sets the persistence 3443 - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3444 3445 Notes: 3446 The default is 1 3447 The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or SNESSetLagPreconditionerPersists() was called 3448 3449 SNESSetLagPreconditionerPersists() allows using the same uniform lagging (for example every second solve) across multiple solves. 3450 3451 Level: intermediate 3452 3453 .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetLagPreconditionerPersists()`, 3454 `SNESSetLagJacobianPersists()` 3455 3456 @*/ 3457 PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 3458 { 3459 PetscFunctionBegin; 3460 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3461 PetscCheck(lag >= -2,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 3462 PetscCheck(lag,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 3463 PetscValidLogicalCollectiveInt(snes,lag,2); 3464 snes->lagpreconditioner = lag; 3465 PetscFunctionReturn(0); 3466 } 3467 3468 /*@ 3469 SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 3470 3471 Logically Collective on SNES 3472 3473 Input Parameters: 3474 + snes - the SNES context 3475 - steps - the number of refinements to do, defaults to 0 3476 3477 Options Database Keys: 3478 . -snes_grid_sequence <steps> - Use grid sequencing to generate initial guess 3479 3480 Level: intermediate 3481 3482 Notes: 3483 Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 3484 3485 .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetGridSequence()` 3486 3487 @*/ 3488 PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 3489 { 3490 PetscFunctionBegin; 3491 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3492 PetscValidLogicalCollectiveInt(snes,steps,2); 3493 snes->gridsequence = steps; 3494 PetscFunctionReturn(0); 3495 } 3496 3497 /*@ 3498 SNESGetGridSequence - gets the number of steps of grid sequencing that SNES does 3499 3500 Logically Collective on SNES 3501 3502 Input Parameter: 3503 . snes - the SNES context 3504 3505 Output Parameter: 3506 . steps - the number of refinements to do, defaults to 0 3507 3508 Options Database Keys: 3509 . -snes_grid_sequence <steps> - set number of refinements 3510 3511 Level: intermediate 3512 3513 Notes: 3514 Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 3515 3516 .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetGridSequence()` 3517 3518 @*/ 3519 PetscErrorCode SNESGetGridSequence(SNES snes,PetscInt *steps) 3520 { 3521 PetscFunctionBegin; 3522 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3523 *steps = snes->gridsequence; 3524 PetscFunctionReturn(0); 3525 } 3526 3527 /*@ 3528 SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 3529 3530 Not Collective 3531 3532 Input Parameter: 3533 . snes - the SNES context 3534 3535 Output Parameter: 3536 . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 3537 the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3538 3539 Options Database Keys: 3540 + -snes_lag_jacobian_persists <true,false> - sets the persistence 3541 . -snes_lag_jacobian <-2,1,2,...> - sets the lag 3542 . -snes_lag_preconditioner_persists <true,false> - sets the persistence 3543 - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3544 3545 Notes: 3546 The default is 1 3547 The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3548 3549 Level: intermediate 3550 3551 .seealso: `SNESSetTrustRegionTolerance()`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3552 3553 @*/ 3554 PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 3555 { 3556 PetscFunctionBegin; 3557 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3558 *lag = snes->lagpreconditioner; 3559 PetscFunctionReturn(0); 3560 } 3561 3562 /*@ 3563 SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 3564 often the preconditioner is rebuilt. 3565 3566 Logically Collective on SNES 3567 3568 Input Parameters: 3569 + snes - the SNES context 3570 - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 3571 the Jacobian is built etc. -2 means rebuild at next chance but then never again 3572 3573 Options Database Keys: 3574 + -snes_lag_jacobian_persists <true,false> - sets the persistence 3575 . -snes_lag_jacobian <-2,1,2,...> - sets the lag 3576 . -snes_lag_preconditioner_persists <true,false> - sets the persistence 3577 - -snes_lag_preconditioner <-2,1,2,...> - sets the lag. 3578 3579 Notes: 3580 The default is 1 3581 The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3582 If -1 is used before the very first nonlinear solve the CODE WILL FAIL! because no Jacobian is used, use -2 to indicate you want it recomputed 3583 at the next Newton step but never again (unless it is reset to another value) 3584 3585 Level: intermediate 3586 3587 .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagPreconditioner()`, `SNESGetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3588 3589 @*/ 3590 PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 3591 { 3592 PetscFunctionBegin; 3593 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3594 PetscCheck(lag >= -2,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 3595 PetscCheck(lag,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 3596 PetscValidLogicalCollectiveInt(snes,lag,2); 3597 snes->lagjacobian = lag; 3598 PetscFunctionReturn(0); 3599 } 3600 3601 /*@ 3602 SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 3603 3604 Not Collective 3605 3606 Input Parameter: 3607 . snes - the SNES context 3608 3609 Output Parameter: 3610 . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 3611 the Jacobian is built etc. 3612 3613 Notes: 3614 The default is 1 3615 The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or SNESSetLagJacobianPersists() was called. 3616 3617 Level: intermediate 3618 3619 .seealso: `SNESSetTrustRegionTolerance()`, `SNESSetLagJacobian()`, `SNESSetLagPreconditioner()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3620 3621 @*/ 3622 PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 3623 { 3624 PetscFunctionBegin; 3625 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3626 *lag = snes->lagjacobian; 3627 PetscFunctionReturn(0); 3628 } 3629 3630 /*@ 3631 SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple solves 3632 3633 Logically collective on SNES 3634 3635 Input Parameters: 3636 + snes - the SNES context 3637 - flg - jacobian lagging persists if true 3638 3639 Options Database Keys: 3640 + -snes_lag_jacobian_persists <true,false> - sets the persistence 3641 . -snes_lag_jacobian <-2,1,2,...> - sets the lag 3642 . -snes_lag_preconditioner_persists <true,false> - sets the persistence 3643 - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3644 3645 Notes: 3646 This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by 3647 several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several 3648 timesteps may present huge efficiency gains. 3649 3650 Level: developer 3651 3652 .seealso: `SNESSetLagPreconditionerPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagJacobianPersists()` 3653 3654 @*/ 3655 PetscErrorCode SNESSetLagJacobianPersists(SNES snes,PetscBool flg) 3656 { 3657 PetscFunctionBegin; 3658 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3659 PetscValidLogicalCollectiveBool(snes,flg,2); 3660 snes->lagjac_persist = flg; 3661 PetscFunctionReturn(0); 3662 } 3663 3664 /*@ 3665 SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple nonlinear solves 3666 3667 Logically Collective on SNES 3668 3669 Input Parameters: 3670 + snes - the SNES context 3671 - flg - preconditioner lagging persists if true 3672 3673 Options Database Keys: 3674 + -snes_lag_jacobian_persists <true,false> - sets the persistence 3675 . -snes_lag_jacobian <-2,1,2,...> - sets the lag 3676 . -snes_lag_preconditioner_persists <true,false> - sets the persistence 3677 - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3678 3679 Notes: 3680 This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale 3681 by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over 3682 several timesteps may present huge efficiency gains. 3683 3684 Level: developer 3685 3686 .seealso: `SNESSetLagJacobianPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagPreconditioner()` 3687 3688 @*/ 3689 PetscErrorCode SNESSetLagPreconditionerPersists(SNES snes,PetscBool flg) 3690 { 3691 PetscFunctionBegin; 3692 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3693 PetscValidLogicalCollectiveBool(snes,flg,2); 3694 snes->lagpre_persist = flg; 3695 PetscFunctionReturn(0); 3696 } 3697 3698 /*@ 3699 SNESSetForceIteration - force SNESSolve() to take at least one iteration regardless of the initial residual norm 3700 3701 Logically Collective on SNES 3702 3703 Input Parameters: 3704 + snes - the SNES context 3705 - force - PETSC_TRUE require at least one iteration 3706 3707 Options Database Keys: 3708 . -snes_force_iteration <force> - Sets forcing an iteration 3709 3710 Notes: 3711 This is used sometimes with TS to prevent TS from detecting a false steady state solution 3712 3713 Level: intermediate 3714 3715 .seealso: `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()` 3716 @*/ 3717 PetscErrorCode SNESSetForceIteration(SNES snes,PetscBool force) 3718 { 3719 PetscFunctionBegin; 3720 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3721 snes->forceiteration = force; 3722 PetscFunctionReturn(0); 3723 } 3724 3725 /*@ 3726 SNESGetForceIteration - Whether or not to force SNESSolve() take at least one iteration regardless of the initial residual norm 3727 3728 Logically Collective on SNES 3729 3730 Input Parameters: 3731 . snes - the SNES context 3732 3733 Output Parameter: 3734 . force - PETSC_TRUE requires at least one iteration. 3735 3736 Level: intermediate 3737 3738 .seealso: `SNESSetForceIteration()`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()` 3739 @*/ 3740 PetscErrorCode SNESGetForceIteration(SNES snes,PetscBool *force) 3741 { 3742 PetscFunctionBegin; 3743 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3744 *force = snes->forceiteration; 3745 PetscFunctionReturn(0); 3746 } 3747 3748 /*@ 3749 SNESSetTolerances - Sets various parameters used in convergence tests. 3750 3751 Logically Collective on SNES 3752 3753 Input Parameters: 3754 + snes - the SNES context 3755 . abstol - absolute convergence tolerance 3756 . rtol - relative convergence tolerance 3757 . stol - convergence tolerance in terms of the norm of the change in the solution between steps, || delta x || < stol*|| x || 3758 . maxit - maximum number of iterations 3759 - maxf - maximum number of function evaluations (-1 indicates no limit) 3760 3761 Options Database Keys: 3762 + -snes_atol <abstol> - Sets abstol 3763 . -snes_rtol <rtol> - Sets rtol 3764 . -snes_stol <stol> - Sets stol 3765 . -snes_max_it <maxit> - Sets maxit 3766 - -snes_max_funcs <maxf> - Sets maxf 3767 3768 Notes: 3769 The default maximum number of iterations is 50. 3770 The default maximum number of function evaluations is 1000. 3771 3772 Level: intermediate 3773 3774 .seealso: `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()`, `SNESSetForceIteration()` 3775 @*/ 3776 PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 3777 { 3778 PetscFunctionBegin; 3779 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3780 PetscValidLogicalCollectiveReal(snes,abstol,2); 3781 PetscValidLogicalCollectiveReal(snes,rtol,3); 3782 PetscValidLogicalCollectiveReal(snes,stol,4); 3783 PetscValidLogicalCollectiveInt(snes,maxit,5); 3784 PetscValidLogicalCollectiveInt(snes,maxf,6); 3785 3786 if (abstol != PETSC_DEFAULT) { 3787 PetscCheck(abstol >= 0.0,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %g must be non-negative",(double)abstol); 3788 snes->abstol = abstol; 3789 } 3790 if (rtol != PETSC_DEFAULT) { 3791 PetscCheck(rtol >= 0.0 && 1.0 > rtol,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Relative tolerance %g must be non-negative and less than 1.0",(double)rtol); 3792 snes->rtol = rtol; 3793 } 3794 if (stol != PETSC_DEFAULT) { 3795 PetscCheck(stol >= 0.0,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %g must be non-negative",(double)stol); 3796 snes->stol = stol; 3797 } 3798 if (maxit != PETSC_DEFAULT) { 3799 PetscCheck(maxit >= 0,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %" PetscInt_FMT " must be non-negative",maxit); 3800 snes->max_its = maxit; 3801 } 3802 if (maxf != PETSC_DEFAULT) { 3803 PetscCheck(maxf >= -1,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %" PetscInt_FMT " must be -1 or nonnegative",maxf); 3804 snes->max_funcs = maxf; 3805 } 3806 snes->tolerancesset = PETSC_TRUE; 3807 PetscFunctionReturn(0); 3808 } 3809 3810 /*@ 3811 SNESSetDivergenceTolerance - Sets the divergence tolerance used for the SNES divergence test. 3812 3813 Logically Collective on SNES 3814 3815 Input Parameters: 3816 + snes - the SNES context 3817 - divtol - the divergence tolerance. Use -1 to deactivate the test. 3818 3819 Options Database Keys: 3820 . -snes_divergence_tolerance <divtol> - Sets divtol 3821 3822 Notes: 3823 The default divergence tolerance is 1e4. 3824 3825 Level: intermediate 3826 3827 .seealso: `SNESSetTolerances()`, `SNESGetDivergenceTolerance` 3828 @*/ 3829 PetscErrorCode SNESSetDivergenceTolerance(SNES snes,PetscReal divtol) 3830 { 3831 PetscFunctionBegin; 3832 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3833 PetscValidLogicalCollectiveReal(snes,divtol,2); 3834 3835 if (divtol != PETSC_DEFAULT) { 3836 snes->divtol = divtol; 3837 } 3838 else { 3839 snes->divtol = 1.0e4; 3840 } 3841 PetscFunctionReturn(0); 3842 } 3843 3844 /*@ 3845 SNESGetTolerances - Gets various parameters used in convergence tests. 3846 3847 Not Collective 3848 3849 Input Parameters: 3850 + snes - the SNES context 3851 . atol - absolute convergence tolerance 3852 . rtol - relative convergence tolerance 3853 . stol - convergence tolerance in terms of the norm 3854 of the change in the solution between steps 3855 . maxit - maximum number of iterations 3856 - maxf - maximum number of function evaluations 3857 3858 Notes: 3859 The user can specify NULL for any parameter that is not needed. 3860 3861 Level: intermediate 3862 3863 .seealso: `SNESSetTolerances()` 3864 @*/ 3865 PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 3866 { 3867 PetscFunctionBegin; 3868 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3869 if (atol) *atol = snes->abstol; 3870 if (rtol) *rtol = snes->rtol; 3871 if (stol) *stol = snes->stol; 3872 if (maxit) *maxit = snes->max_its; 3873 if (maxf) *maxf = snes->max_funcs; 3874 PetscFunctionReturn(0); 3875 } 3876 3877 /*@ 3878 SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test. 3879 3880 Not Collective 3881 3882 Input Parameters: 3883 + snes - the SNES context 3884 - divtol - divergence tolerance 3885 3886 Level: intermediate 3887 3888 .seealso: `SNESSetDivergenceTolerance()` 3889 @*/ 3890 PetscErrorCode SNESGetDivergenceTolerance(SNES snes,PetscReal *divtol) 3891 { 3892 PetscFunctionBegin; 3893 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3894 if (divtol) *divtol = snes->divtol; 3895 PetscFunctionReturn(0); 3896 } 3897 3898 /*@ 3899 SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 3900 3901 Logically Collective on SNES 3902 3903 Input Parameters: 3904 + snes - the SNES context 3905 - tol - tolerance 3906 3907 Options Database Key: 3908 . -snes_trtol <tol> - Sets tol 3909 3910 Level: intermediate 3911 3912 .seealso: `SNESSetTolerances()` 3913 @*/ 3914 PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 3915 { 3916 PetscFunctionBegin; 3917 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3918 PetscValidLogicalCollectiveReal(snes,tol,2); 3919 snes->deltatol = tol; 3920 PetscFunctionReturn(0); 3921 } 3922 3923 PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 3924 3925 PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 3926 { 3927 PetscDrawLG lg; 3928 PetscReal x,y,per; 3929 PetscViewer v = (PetscViewer)monctx; 3930 static PetscReal prev; /* should be in the context */ 3931 PetscDraw draw; 3932 3933 PetscFunctionBegin; 3934 PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,4); 3935 PetscCall(PetscViewerDrawGetDrawLG(v,0,&lg)); 3936 if (!n) PetscCall(PetscDrawLGReset(lg)); 3937 PetscCall(PetscDrawLGGetDraw(lg,&draw)); 3938 PetscCall(PetscDrawSetTitle(draw,"Residual norm")); 3939 x = (PetscReal)n; 3940 if (rnorm > 0.0) y = PetscLog10Real(rnorm); 3941 else y = -15.0; 3942 PetscCall(PetscDrawLGAddPoint(lg,&x,&y)); 3943 if (n < 20 || !(n % 5) || snes->reason) { 3944 PetscCall(PetscDrawLGDraw(lg)); 3945 PetscCall(PetscDrawLGSave(lg)); 3946 } 3947 3948 PetscCall(PetscViewerDrawGetDrawLG(v,1,&lg)); 3949 if (!n) PetscCall(PetscDrawLGReset(lg)); 3950 PetscCall(PetscDrawLGGetDraw(lg,&draw)); 3951 PetscCall(PetscDrawSetTitle(draw,"% elemts > .2*max elemt")); 3952 PetscCall(SNESMonitorRange_Private(snes,n,&per)); 3953 x = (PetscReal)n; 3954 y = 100.0*per; 3955 PetscCall(PetscDrawLGAddPoint(lg,&x,&y)); 3956 if (n < 20 || !(n % 5) || snes->reason) { 3957 PetscCall(PetscDrawLGDraw(lg)); 3958 PetscCall(PetscDrawLGSave(lg)); 3959 } 3960 3961 PetscCall(PetscViewerDrawGetDrawLG(v,2,&lg)); 3962 if (!n) {prev = rnorm;PetscCall(PetscDrawLGReset(lg));} 3963 PetscCall(PetscDrawLGGetDraw(lg,&draw)); 3964 PetscCall(PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm")); 3965 x = (PetscReal)n; 3966 y = (prev - rnorm)/prev; 3967 PetscCall(PetscDrawLGAddPoint(lg,&x,&y)); 3968 if (n < 20 || !(n % 5) || snes->reason) { 3969 PetscCall(PetscDrawLGDraw(lg)); 3970 PetscCall(PetscDrawLGSave(lg)); 3971 } 3972 3973 PetscCall(PetscViewerDrawGetDrawLG(v,3,&lg)); 3974 if (!n) PetscCall(PetscDrawLGReset(lg)); 3975 PetscCall(PetscDrawLGGetDraw(lg,&draw)); 3976 PetscCall(PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)")); 3977 x = (PetscReal)n; 3978 y = (prev - rnorm)/(prev*per); 3979 if (n > 2) { /*skip initial crazy value */ 3980 PetscCall(PetscDrawLGAddPoint(lg,&x,&y)); 3981 } 3982 if (n < 20 || !(n % 5) || snes->reason) { 3983 PetscCall(PetscDrawLGDraw(lg)); 3984 PetscCall(PetscDrawLGSave(lg)); 3985 } 3986 prev = rnorm; 3987 PetscFunctionReturn(0); 3988 } 3989 3990 /*@ 3991 SNESMonitor - runs the user provided monitor routines, if they exist 3992 3993 Collective on SNES 3994 3995 Input Parameters: 3996 + snes - nonlinear solver context obtained from SNESCreate() 3997 . iter - iteration number 3998 - rnorm - relative norm of the residual 3999 4000 Notes: 4001 This routine is called by the SNES implementations. 4002 It does not typically need to be called by the user. 4003 4004 Level: developer 4005 4006 .seealso: `SNESMonitorSet()` 4007 @*/ 4008 PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 4009 { 4010 PetscInt i,n = snes->numbermonitors; 4011 4012 PetscFunctionBegin; 4013 PetscCall(VecLockReadPush(snes->vec_sol)); 4014 for (i=0; i<n; i++) { 4015 PetscCall((*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i])); 4016 } 4017 PetscCall(VecLockReadPop(snes->vec_sol)); 4018 PetscFunctionReturn(0); 4019 } 4020 4021 /* ------------ Routines to set performance monitoring options ----------- */ 4022 4023 /*MC 4024 SNESMonitorFunction - functional form passed to SNESMonitorSet() to monitor convergence of nonlinear solver 4025 4026 Synopsis: 4027 #include <petscsnes.h> 4028 $ PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx) 4029 4030 Collective on snes 4031 4032 Input Parameters: 4033 + snes - the SNES context 4034 . its - iteration number 4035 . norm - 2-norm function value (may be estimated) 4036 - mctx - [optional] monitoring context 4037 4038 Level: advanced 4039 4040 .seealso: `SNESMonitorSet()`, `SNESMonitorGet()` 4041 M*/ 4042 4043 /*@C 4044 SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 4045 iteration of the nonlinear solver to display the iteration's 4046 progress. 4047 4048 Logically Collective on SNES 4049 4050 Input Parameters: 4051 + snes - the SNES context 4052 . f - the monitor function, see SNESMonitorFunction for the calling sequence 4053 . mctx - [optional] user-defined context for private data for the 4054 monitor routine (use NULL if no context is desired) 4055 - monitordestroy - [optional] routine that frees monitor context 4056 (may be NULL) 4057 4058 Options Database Keys: 4059 + -snes_monitor - sets SNESMonitorDefault() 4060 . -snes_monitor draw::draw_lg - sets line graph monitor, 4061 - -snes_monitor_cancel - cancels all monitors that have 4062 been hardwired into a code by 4063 calls to SNESMonitorSet(), but 4064 does not cancel those set via 4065 the options database. 4066 4067 Notes: 4068 Several different monitoring routines may be set by calling 4069 SNESMonitorSet() multiple times; all will be called in the 4070 order in which they were set. 4071 4072 Fortran Notes: 4073 Only a single monitor function can be set for each SNES object 4074 4075 Level: intermediate 4076 4077 .seealso: `SNESMonitorDefault()`, `SNESMonitorCancel()`, `SNESMonitorFunction` 4078 @*/ 4079 PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*f)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 4080 { 4081 PetscInt i; 4082 PetscBool identical; 4083 4084 PetscFunctionBegin; 4085 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4086 for (i=0; i<snes->numbermonitors;i++) { 4087 PetscCall(PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))snes->monitor[i],snes->monitorcontext[i],snes->monitordestroy[i],&identical)); 4088 if (identical) PetscFunctionReturn(0); 4089 } 4090 PetscCheck(snes->numbermonitors < MAXSNESMONITORS,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 4091 snes->monitor[snes->numbermonitors] = f; 4092 snes->monitordestroy[snes->numbermonitors] = monitordestroy; 4093 snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 4094 PetscFunctionReturn(0); 4095 } 4096 4097 /*@ 4098 SNESMonitorCancel - Clears all the monitor functions for a SNES object. 4099 4100 Logically Collective on SNES 4101 4102 Input Parameters: 4103 . snes - the SNES context 4104 4105 Options Database Key: 4106 . -snes_monitor_cancel - cancels all monitors that have been hardwired 4107 into a code by calls to SNESMonitorSet(), but does not cancel those 4108 set via the options database 4109 4110 Notes: 4111 There is no way to clear one specific monitor from a SNES object. 4112 4113 Level: intermediate 4114 4115 .seealso: `SNESMonitorDefault()`, `SNESMonitorSet()` 4116 @*/ 4117 PetscErrorCode SNESMonitorCancel(SNES snes) 4118 { 4119 PetscInt i; 4120 4121 PetscFunctionBegin; 4122 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4123 for (i=0; i<snes->numbermonitors; i++) { 4124 if (snes->monitordestroy[i]) { 4125 PetscCall((*snes->monitordestroy[i])(&snes->monitorcontext[i])); 4126 } 4127 } 4128 snes->numbermonitors = 0; 4129 PetscFunctionReturn(0); 4130 } 4131 4132 /*MC 4133 SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver 4134 4135 Synopsis: 4136 #include <petscsnes.h> 4137 $ PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 4138 4139 Collective on snes 4140 4141 Input Parameters: 4142 + snes - the SNES context 4143 . it - current iteration (0 is the first and is before any Newton step) 4144 . xnorm - 2-norm of current iterate 4145 . gnorm - 2-norm of current step 4146 . f - 2-norm of function 4147 - cctx - [optional] convergence context 4148 4149 Output Parameter: 4150 . reason - reason for convergence/divergence, only needs to be set when convergence or divergence is detected 4151 4152 Level: intermediate 4153 4154 .seealso: `SNESSetConvergenceTest()`, `SNESGetConvergenceTest()` 4155 M*/ 4156 4157 /*@C 4158 SNESSetConvergenceTest - Sets the function that is to be used 4159 to test for convergence of the nonlinear iterative solution. 4160 4161 Logically Collective on SNES 4162 4163 Input Parameters: 4164 + snes - the SNES context 4165 . SNESConvergenceTestFunction - routine to test for convergence 4166 . cctx - [optional] context for private data for the convergence routine (may be NULL) 4167 - destroy - [optional] destructor for the context (may be NULL; PETSC_NULL_FUNCTION in Fortran) 4168 4169 Level: advanced 4170 4171 .seealso: `SNESConvergedDefault()`, `SNESConvergedSkip()`, `SNESConvergenceTestFunction` 4172 @*/ 4173 PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*SNESConvergenceTestFunction)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 4174 { 4175 PetscFunctionBegin; 4176 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4177 if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip; 4178 if (snes->ops->convergeddestroy) PetscCall((*snes->ops->convergeddestroy)(snes->cnvP)); 4179 snes->ops->converged = SNESConvergenceTestFunction; 4180 snes->ops->convergeddestroy = destroy; 4181 snes->cnvP = cctx; 4182 PetscFunctionReturn(0); 4183 } 4184 4185 /*@ 4186 SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 4187 4188 Not Collective 4189 4190 Input Parameter: 4191 . snes - the SNES context 4192 4193 Output Parameter: 4194 . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 4195 manual pages for the individual convergence tests for complete lists 4196 4197 Options Database: 4198 . -snes_converged_reason - prints the reason to standard out 4199 4200 Level: intermediate 4201 4202 Notes: 4203 Should only be called after the call the SNESSolve() is complete, if it is called earlier it returns the value SNES__CONVERGED_ITERATING. 4204 4205 .seealso: `SNESSetConvergenceTest()`, `SNESSetConvergedReason()`, `SNESConvergedReason` 4206 @*/ 4207 PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 4208 { 4209 PetscFunctionBegin; 4210 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4211 PetscValidPointer(reason,2); 4212 *reason = snes->reason; 4213 PetscFunctionReturn(0); 4214 } 4215 4216 /*@C 4217 SNESGetConvergedReasonString - Return a human readable string for snes converged reason 4218 4219 Not Collective 4220 4221 Input Parameter: 4222 . snes - the SNES context 4223 4224 Output Parameter: 4225 . strreason - a human readable string that describes SNES converged reason 4226 4227 Level: beginner 4228 4229 .seealso: `SNESGetConvergedReason()` 4230 @*/ 4231 PetscErrorCode SNESGetConvergedReasonString(SNES snes, const char** strreason) 4232 { 4233 PetscFunctionBegin; 4234 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4235 PetscValidPointer(strreason,2); 4236 *strreason = SNESConvergedReasons[snes->reason]; 4237 PetscFunctionReturn(0); 4238 } 4239 4240 /*@ 4241 SNESSetConvergedReason - Sets the reason the SNES iteration was stopped. 4242 4243 Not Collective 4244 4245 Input Parameters: 4246 + snes - the SNES context 4247 - reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 4248 manual pages for the individual convergence tests for complete lists 4249 4250 Level: intermediate 4251 4252 .seealso: `SNESGetConvergedReason()`, `SNESSetConvergenceTest()`, `SNESConvergedReason` 4253 @*/ 4254 PetscErrorCode SNESSetConvergedReason(SNES snes,SNESConvergedReason reason) 4255 { 4256 PetscFunctionBegin; 4257 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4258 snes->reason = reason; 4259 PetscFunctionReturn(0); 4260 } 4261 4262 /*@ 4263 SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 4264 4265 Logically Collective on SNES 4266 4267 Input Parameters: 4268 + snes - iterative context obtained from SNESCreate() 4269 . a - array to hold history, this array will contain the function norms computed at each step 4270 . its - integer array holds the number of linear iterations for each solve. 4271 . na - size of a and its 4272 - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 4273 else it continues storing new values for new nonlinear solves after the old ones 4274 4275 Notes: 4276 If 'a' and 'its' are NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 4277 default array of length 10000 is allocated. 4278 4279 This routine is useful, e.g., when running a code for purposes 4280 of accurate performance monitoring, when no I/O should be done 4281 during the section of code that is being timed. 4282 4283 Level: intermediate 4284 4285 .seealso: `SNESGetConvergenceHistory()` 4286 4287 @*/ 4288 PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 4289 { 4290 PetscFunctionBegin; 4291 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4292 if (a) PetscValidRealPointer(a,2); 4293 if (its) PetscValidIntPointer(its,3); 4294 if (!a) { 4295 if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 4296 PetscCall(PetscCalloc2(na,&a,na,&its)); 4297 snes->conv_hist_alloc = PETSC_TRUE; 4298 } 4299 snes->conv_hist = a; 4300 snes->conv_hist_its = its; 4301 snes->conv_hist_max = (size_t)na; 4302 snes->conv_hist_len = 0; 4303 snes->conv_hist_reset = reset; 4304 PetscFunctionReturn(0); 4305 } 4306 4307 #if defined(PETSC_HAVE_MATLAB_ENGINE) 4308 #include <engine.h> /* MATLAB include file */ 4309 #include <mex.h> /* MATLAB include file */ 4310 4311 PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 4312 { 4313 mxArray *mat; 4314 PetscInt i; 4315 PetscReal *ar; 4316 4317 PetscFunctionBegin; 4318 mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 4319 ar = (PetscReal*) mxGetData(mat); 4320 for (i=0; i<snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i]; 4321 PetscFunctionReturn(mat); 4322 } 4323 #endif 4324 4325 /*@C 4326 SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 4327 4328 Not Collective 4329 4330 Input Parameter: 4331 . snes - iterative context obtained from SNESCreate() 4332 4333 Output Parameters: 4334 + a - array to hold history 4335 . its - integer array holds the number of linear iterations (or 4336 negative if not converged) for each solve. 4337 - na - size of a and its 4338 4339 Notes: 4340 The calling sequence for this routine in Fortran is 4341 $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 4342 4343 This routine is useful, e.g., when running a code for purposes 4344 of accurate performance monitoring, when no I/O should be done 4345 during the section of code that is being timed. 4346 4347 Level: intermediate 4348 4349 .seealso: `SNESSetConvergenceHistory()` 4350 4351 @*/ 4352 PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 4353 { 4354 PetscFunctionBegin; 4355 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4356 if (a) *a = snes->conv_hist; 4357 if (its) *its = snes->conv_hist_its; 4358 if (na) *na = (PetscInt) snes->conv_hist_len; 4359 PetscFunctionReturn(0); 4360 } 4361 4362 /*@C 4363 SNESSetUpdate - Sets the general-purpose update function called 4364 at the beginning of every iteration of the nonlinear solve. Specifically 4365 it is called just before the Jacobian is "evaluated". 4366 4367 Logically Collective on SNES 4368 4369 Input Parameters: 4370 + snes - The nonlinear solver context 4371 - func - The function 4372 4373 Calling sequence of func: 4374 $ func (SNES snes, PetscInt step); 4375 4376 . step - The current step of the iteration 4377 4378 Level: advanced 4379 4380 Note: 4381 This is NOT what one uses to update the ghost points before a function evaluation, that should be done at the beginning of your FormFunction() 4382 This is not used by most users. 4383 4384 There are a varity of function hooks one many set that are called at different stages of the nonlinear solution process, see the functions listed below. 4385 4386 .seealso `SNESSetJacobian()`, `SNESSolve()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRSetPostCheck()`, 4387 `SNESMonitorSet()`, `SNESSetDivergenceTest()` 4388 @*/ 4389 PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 4390 { 4391 PetscFunctionBegin; 4392 PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 4393 snes->ops->update = func; 4394 PetscFunctionReturn(0); 4395 } 4396 4397 /* 4398 SNESScaleStep_Private - Scales a step so that its length is less than the 4399 positive parameter delta. 4400 4401 Input Parameters: 4402 + snes - the SNES context 4403 . y - approximate solution of linear system 4404 . fnorm - 2-norm of current function 4405 - delta - trust region size 4406 4407 Output Parameters: 4408 + gpnorm - predicted function norm at the new point, assuming local 4409 linearization. The value is zero if the step lies within the trust 4410 region, and exceeds zero otherwise. 4411 - ynorm - 2-norm of the step 4412 4413 Note: 4414 For non-trust region methods such as SNESNEWTONLS, the parameter delta 4415 is set to be the maximum allowable step size. 4416 4417 */ 4418 PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 4419 { 4420 PetscReal nrm; 4421 PetscScalar cnorm; 4422 4423 PetscFunctionBegin; 4424 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4425 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 4426 PetscCheckSameComm(snes,1,y,2); 4427 4428 PetscCall(VecNorm(y,NORM_2,&nrm)); 4429 if (nrm > *delta) { 4430 nrm = *delta/nrm; 4431 *gpnorm = (1.0 - nrm)*(*fnorm); 4432 cnorm = nrm; 4433 PetscCall(VecScale(y,cnorm)); 4434 *ynorm = *delta; 4435 } else { 4436 *gpnorm = 0.0; 4437 *ynorm = nrm; 4438 } 4439 PetscFunctionReturn(0); 4440 } 4441 4442 /*@C 4443 SNESConvergedReasonView - Displays the reason a SNES solve converged or diverged to a viewer 4444 4445 Collective on SNES 4446 4447 Parameter: 4448 + snes - iterative context obtained from SNESCreate() 4449 - viewer - the viewer to display the reason 4450 4451 Options Database Keys: 4452 + -snes_converged_reason - print reason for converged or diverged, also prints number of iterations 4453 - -snes_converged_reason ::failed - only print reason and number of iterations when diverged 4454 4455 Notes: 4456 To change the format of the output call PetscViewerPushFormat(viewer,format) before this call. Use PETSC_VIEWER_DEFAULT for the default, 4457 use PETSC_VIEWER_FAILED to only display a reason if it fails. 4458 4459 Level: beginner 4460 4461 .seealso: `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, `SNESConvergedReasonViewFromOptions()`, 4462 `PetscViewerPushFormat()`, `PetscViewerPopFormat()` 4463 4464 @*/ 4465 PetscErrorCode SNESConvergedReasonView(SNES snes,PetscViewer viewer) 4466 { 4467 PetscViewerFormat format; 4468 PetscBool isAscii; 4469 4470 PetscFunctionBegin; 4471 if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)); 4472 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii)); 4473 if (isAscii) { 4474 PetscCall(PetscViewerGetFormat(viewer, &format)); 4475 PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel)); 4476 if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 4477 DM dm; 4478 Vec u; 4479 PetscDS prob; 4480 PetscInt Nf, f; 4481 PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 4482 void **exactCtx; 4483 PetscReal error; 4484 4485 PetscCall(SNESGetDM(snes, &dm)); 4486 PetscCall(SNESGetSolution(snes, &u)); 4487 PetscCall(DMGetDS(dm, &prob)); 4488 PetscCall(PetscDSGetNumFields(prob, &Nf)); 4489 PetscCall(PetscMalloc2(Nf, &exactSol, Nf, &exactCtx)); 4490 for (f = 0; f < Nf; ++f) PetscCall(PetscDSGetExactSolution(prob, f, &exactSol[f], &exactCtx[f])); 4491 PetscCall(DMComputeL2Diff(dm, 0.0, exactSol, exactCtx, u, &error)); 4492 PetscCall(PetscFree2(exactSol, exactCtx)); 4493 if (error < 1.0e-11) PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n")); 4494 else PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", (double)error)); 4495 } 4496 if (snes->reason > 0 && format != PETSC_VIEWER_FAILED) { 4497 if (((PetscObject) snes)->prefix) { 4498 PetscCall(PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve converged due to %s iterations %" PetscInt_FMT "\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter)); 4499 } else { 4500 PetscCall(PetscViewerASCIIPrintf(viewer,"Nonlinear solve converged due to %s iterations %" PetscInt_FMT "\n",SNESConvergedReasons[snes->reason],snes->iter)); 4501 } 4502 } else if (snes->reason <= 0) { 4503 if (((PetscObject) snes)->prefix) { 4504 PetscCall(PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve did not converge due to %s iterations %" PetscInt_FMT "\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter)); 4505 } else { 4506 PetscCall(PetscViewerASCIIPrintf(viewer,"Nonlinear solve did not converge due to %s iterations %" PetscInt_FMT "\n",SNESConvergedReasons[snes->reason],snes->iter)); 4507 } 4508 } 4509 PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel)); 4510 } 4511 PetscFunctionReturn(0); 4512 } 4513 4514 /*@C 4515 SNESConvergedReasonViewSet - Sets an ADDITIONAL function that is to be used at the 4516 end of the nonlinear solver to display the conver reason of the nonlinear solver. 4517 4518 Logically Collective on SNES 4519 4520 Input Parameters: 4521 + snes - the SNES context 4522 . f - the snes converged reason view function 4523 . vctx - [optional] user-defined context for private data for the 4524 snes converged reason view routine (use NULL if no context is desired) 4525 - reasonviewdestroy - [optional] routine that frees reasonview context 4526 (may be NULL) 4527 4528 Options Database Keys: 4529 + -snes_converged_reason - sets a default SNESConvergedReasonView() 4530 - -snes_converged_reason_view_cancel - cancels all converged reason viewers that have 4531 been hardwired into a code by 4532 calls to SNESConvergedReasonViewSet(), but 4533 does not cancel those set via 4534 the options database. 4535 4536 Notes: 4537 Several different converged reason view routines may be set by calling 4538 SNESConvergedReasonViewSet() multiple times; all will be called in the 4539 order in which they were set. 4540 4541 Level: intermediate 4542 4543 .seealso: `SNESConvergedReasonView()`, `SNESConvergedReasonViewCancel()` 4544 @*/ 4545 PetscErrorCode SNESConvergedReasonViewSet(SNES snes,PetscErrorCode (*f)(SNES,void*),void *vctx,PetscErrorCode (*reasonviewdestroy)(void**)) 4546 { 4547 PetscInt i; 4548 PetscBool identical; 4549 4550 PetscFunctionBegin; 4551 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4552 for (i=0; i<snes->numberreasonviews;i++) { 4553 PetscCall(PetscMonitorCompare((PetscErrorCode (*)(void))f,vctx,reasonviewdestroy,(PetscErrorCode (*)(void))snes->reasonview[i],snes->reasonviewcontext[i],snes->reasonviewdestroy[i],&identical)); 4554 if (identical) PetscFunctionReturn(0); 4555 } 4556 PetscCheck(snes->numberreasonviews < MAXSNESREASONVIEWS,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many SNES reasonview set"); 4557 snes->reasonview[snes->numberreasonviews] = f; 4558 snes->reasonviewdestroy[snes->numberreasonviews] = reasonviewdestroy; 4559 snes->reasonviewcontext[snes->numberreasonviews++] = (void*)vctx; 4560 PetscFunctionReturn(0); 4561 } 4562 4563 /*@ 4564 SNESConvergedReasonViewFromOptions - Processes command line options to determine if/how a SNESReason is to be viewed. 4565 All the user-provided convergedReasonView routines will be involved as well, if they exist. 4566 4567 Collective on SNES 4568 4569 Input Parameters: 4570 . snes - the SNES object 4571 4572 Level: intermediate 4573 4574 .seealso: `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()` 4575 4576 @*/ 4577 PetscErrorCode SNESConvergedReasonViewFromOptions(SNES snes) 4578 { 4579 PetscViewer viewer; 4580 PetscBool flg; 4581 static PetscBool incall = PETSC_FALSE; 4582 PetscViewerFormat format; 4583 PetscInt i; 4584 4585 PetscFunctionBegin; 4586 if (incall) PetscFunctionReturn(0); 4587 incall = PETSC_TRUE; 4588 4589 /* All user-provided viewers are called first, if they exist. */ 4590 for (i=0; i<snes->numberreasonviews; i++) { 4591 PetscCall((*snes->reasonview[i])(snes,snes->reasonviewcontext[i])); 4592 } 4593 4594 /* Call PETSc default routine if users ask for it */ 4595 PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_converged_reason",&viewer,&format,&flg)); 4596 if (flg) { 4597 PetscCall(PetscViewerPushFormat(viewer,format)); 4598 PetscCall(SNESConvergedReasonView(snes,viewer)); 4599 PetscCall(PetscViewerPopFormat(viewer)); 4600 PetscCall(PetscViewerDestroy(&viewer)); 4601 } 4602 incall = PETSC_FALSE; 4603 PetscFunctionReturn(0); 4604 } 4605 4606 /*@ 4607 SNESSolve - Solves a nonlinear system F(x) = b. 4608 Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 4609 4610 Collective on SNES 4611 4612 Input Parameters: 4613 + snes - the SNES context 4614 . b - the constant part of the equation F(x) = b, or NULL to use zero. 4615 - x - the solution vector. 4616 4617 Notes: 4618 The user should initialize the vector,x, with the initial guess 4619 for the nonlinear solve prior to calling SNESSolve(). In particular, 4620 to employ an initial guess of zero, the user should explicitly set 4621 this vector to zero by calling VecSet(). 4622 4623 Level: beginner 4624 4625 .seealso: `SNESCreate()`, `SNESDestroy()`, `SNESSetFunction()`, `SNESSetJacobian()`, `SNESSetGridSequence()`, `SNESGetSolution()`, 4626 `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRGetPreCheck()`, `SNESNewtonTRSetPostCheck()`, `SNESNewtonTRGetPostCheck()`, 4627 `SNESLineSearchSetPostCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchGetPreCheck()` 4628 @*/ 4629 PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 4630 { 4631 PetscBool flg; 4632 PetscInt grid; 4633 Vec xcreated = NULL; 4634 DM dm; 4635 4636 PetscFunctionBegin; 4637 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4638 if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 4639 if (x) PetscCheckSameComm(snes,1,x,3); 4640 if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4641 if (b) PetscCheckSameComm(snes,1,b,2); 4642 4643 /* High level operations using the nonlinear solver */ 4644 { 4645 PetscViewer viewer; 4646 PetscViewerFormat format; 4647 PetscInt num; 4648 PetscBool flg; 4649 static PetscBool incall = PETSC_FALSE; 4650 4651 if (!incall) { 4652 /* Estimate the convergence rate of the discretization */ 4653 PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject) snes),((PetscObject)snes)->options, ((PetscObject) snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg)); 4654 if (flg) { 4655 PetscConvEst conv; 4656 DM dm; 4657 PetscReal *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */ 4658 PetscInt Nf; 4659 4660 incall = PETSC_TRUE; 4661 PetscCall(SNESGetDM(snes, &dm)); 4662 PetscCall(DMGetNumFields(dm, &Nf)); 4663 PetscCall(PetscCalloc1(Nf, &alpha)); 4664 PetscCall(PetscConvEstCreate(PetscObjectComm((PetscObject) snes), &conv)); 4665 PetscCall(PetscConvEstSetSolver(conv, (PetscObject) snes)); 4666 PetscCall(PetscConvEstSetFromOptions(conv)); 4667 PetscCall(PetscConvEstSetUp(conv)); 4668 PetscCall(PetscConvEstGetConvRate(conv, alpha)); 4669 PetscCall(PetscViewerPushFormat(viewer, format)); 4670 PetscCall(PetscConvEstRateView(conv, alpha, viewer)); 4671 PetscCall(PetscViewerPopFormat(viewer)); 4672 PetscCall(PetscViewerDestroy(&viewer)); 4673 PetscCall(PetscConvEstDestroy(&conv)); 4674 PetscCall(PetscFree(alpha)); 4675 incall = PETSC_FALSE; 4676 } 4677 /* Adaptively refine the initial grid */ 4678 num = 1; 4679 PetscCall(PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_initial", &num, &flg)); 4680 if (flg) { 4681 DMAdaptor adaptor; 4682 4683 incall = PETSC_TRUE; 4684 PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor)); 4685 PetscCall(DMAdaptorSetSolver(adaptor, snes)); 4686 PetscCall(DMAdaptorSetSequenceLength(adaptor, num)); 4687 PetscCall(DMAdaptorSetFromOptions(adaptor)); 4688 PetscCall(DMAdaptorSetUp(adaptor)); 4689 PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x)); 4690 PetscCall(DMAdaptorDestroy(&adaptor)); 4691 incall = PETSC_FALSE; 4692 } 4693 /* Use grid sequencing to adapt */ 4694 num = 0; 4695 PetscCall(PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_sequence", &num, NULL)); 4696 if (num) { 4697 DMAdaptor adaptor; 4698 4699 incall = PETSC_TRUE; 4700 PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor)); 4701 PetscCall(DMAdaptorSetSolver(adaptor, snes)); 4702 PetscCall(DMAdaptorSetSequenceLength(adaptor, num)); 4703 PetscCall(DMAdaptorSetFromOptions(adaptor)); 4704 PetscCall(DMAdaptorSetUp(adaptor)); 4705 PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x)); 4706 PetscCall(DMAdaptorDestroy(&adaptor)); 4707 incall = PETSC_FALSE; 4708 } 4709 } 4710 } 4711 if (!x) { x = snes->vec_sol; } 4712 if (!x) { 4713 PetscCall(SNESGetDM(snes,&dm)); 4714 PetscCall(DMCreateGlobalVector(dm,&xcreated)); 4715 x = xcreated; 4716 } 4717 PetscCall(SNESViewFromOptions(snes,NULL,"-snes_view_pre")); 4718 4719 for (grid=0; grid<snes->gridsequence; grid++) PetscCall(PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)))); 4720 for (grid=0; grid<snes->gridsequence+1; grid++) { 4721 4722 /* set solution vector */ 4723 if (!grid) PetscCall(PetscObjectReference((PetscObject)x)); 4724 PetscCall(VecDestroy(&snes->vec_sol)); 4725 snes->vec_sol = x; 4726 PetscCall(SNESGetDM(snes,&dm)); 4727 4728 /* set affine vector if provided */ 4729 if (b) PetscCall(PetscObjectReference((PetscObject)b)); 4730 PetscCall(VecDestroy(&snes->vec_rhs)); 4731 snes->vec_rhs = b; 4732 4733 if (snes->vec_rhs) PetscCheck(snes->vec_func != snes->vec_rhs,PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Right hand side vector cannot be function vector"); 4734 PetscCheck(snes->vec_func != snes->vec_sol,PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 4735 PetscCheck(snes->vec_rhs != snes->vec_sol,PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 4736 if (!snes->vec_sol_update /* && snes->vec_sol */) { 4737 PetscCall(VecDuplicate(snes->vec_sol,&snes->vec_sol_update)); 4738 PetscCall(PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->vec_sol_update)); 4739 } 4740 PetscCall(DMShellSetGlobalVector(dm,snes->vec_sol)); 4741 PetscCall(SNESSetUp(snes)); 4742 4743 if (!grid) { 4744 if (snes->ops->computeinitialguess) PetscCall((*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP)); 4745 } 4746 4747 if (snes->conv_hist_reset) snes->conv_hist_len = 0; 4748 if (snes->counters_reset) {snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;} 4749 4750 PetscCall(PetscLogEventBegin(SNES_Solve,snes,0,0,0)); 4751 PetscCall((*snes->ops->solve)(snes)); 4752 PetscCall(PetscLogEventEnd(SNES_Solve,snes,0,0,0)); 4753 PetscCheck(snes->reason,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 4754 snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */ 4755 4756 if (snes->lagjac_persist) snes->jac_iter += snes->iter; 4757 if (snes->lagpre_persist) snes->pre_iter += snes->iter; 4758 4759 PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_test_local_min",NULL,NULL,&flg)); 4760 if (flg && !PetscPreLoadingOn) PetscCall(SNESTestLocalMin(snes)); 4761 /* Call converged reason views. This may involve user-provided viewers as well */ 4762 PetscCall(SNESConvergedReasonViewFromOptions(snes)); 4763 4764 if (snes->errorifnotconverged) PetscCheck(snes->reason >= 0,PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 4765 if (snes->reason < 0) break; 4766 if (grid < snes->gridsequence) { 4767 DM fine; 4768 Vec xnew; 4769 Mat interp; 4770 4771 PetscCall(DMRefine(snes->dm,PetscObjectComm((PetscObject)snes),&fine)); 4772 PetscCheck(fine,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 4773 PetscCall(DMCreateInterpolation(snes->dm,fine,&interp,NULL)); 4774 PetscCall(DMCreateGlobalVector(fine,&xnew)); 4775 PetscCall(MatInterpolate(interp,x,xnew)); 4776 PetscCall(DMInterpolate(snes->dm,interp,fine)); 4777 PetscCall(MatDestroy(&interp)); 4778 x = xnew; 4779 4780 PetscCall(SNESReset(snes)); 4781 PetscCall(SNESSetDM(snes,fine)); 4782 PetscCall(SNESResetFromOptions(snes)); 4783 PetscCall(DMDestroy(&fine)); 4784 PetscCall(PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)))); 4785 } 4786 } 4787 PetscCall(SNESViewFromOptions(snes,NULL,"-snes_view")); 4788 PetscCall(VecViewFromOptions(snes->vec_sol,(PetscObject)snes,"-snes_view_solution")); 4789 PetscCall(DMMonitor(snes->dm)); 4790 PetscCall(SNESMonitorPauseFinal_Internal(snes)); 4791 4792 PetscCall(VecDestroy(&xcreated)); 4793 PetscCall(PetscObjectSAWsBlock((PetscObject)snes)); 4794 PetscFunctionReturn(0); 4795 } 4796 4797 /* --------- Internal routines for SNES Package --------- */ 4798 4799 /*@C 4800 SNESSetType - Sets the method for the nonlinear solver. 4801 4802 Collective on SNES 4803 4804 Input Parameters: 4805 + snes - the SNES context 4806 - type - a known method 4807 4808 Options Database Key: 4809 . -snes_type <type> - Sets the method; use -help for a list 4810 of available methods (for instance, newtonls or newtontr) 4811 4812 Notes: 4813 See "petsc/include/petscsnes.h" for available methods (for instance) 4814 + SNESNEWTONLS - Newton's method with line search 4815 (systems of nonlinear equations) 4816 - SNESNEWTONTR - Newton's method with trust region 4817 (systems of nonlinear equations) 4818 4819 Normally, it is best to use the SNESSetFromOptions() command and then 4820 set the SNES solver type from the options database rather than by using 4821 this routine. Using the options database provides the user with 4822 maximum flexibility in evaluating the many nonlinear solvers. 4823 The SNESSetType() routine is provided for those situations where it 4824 is necessary to set the nonlinear solver independently of the command 4825 line or options database. This might be the case, for example, when 4826 the choice of solver changes during the execution of the program, 4827 and the user's application is taking responsibility for choosing the 4828 appropriate method. 4829 4830 Developer Notes: 4831 SNESRegister() adds a constructor for a new SNESType to SNESList, SNESSetType() locates 4832 the constructor in that list and calls it to create the spexific object. 4833 4834 Level: intermediate 4835 4836 .seealso: `SNESType`, `SNESCreate()`, `SNESDestroy()`, `SNESGetType()`, `SNESSetFromOptions()` 4837 4838 @*/ 4839 PetscErrorCode SNESSetType(SNES snes,SNESType type) 4840 { 4841 PetscBool match; 4842 PetscErrorCode (*r)(SNES); 4843 4844 PetscFunctionBegin; 4845 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4846 PetscValidCharPointer(type,2); 4847 4848 PetscCall(PetscObjectTypeCompare((PetscObject)snes,type,&match)); 4849 if (match) PetscFunctionReturn(0); 4850 4851 PetscCall(PetscFunctionListFind(SNESList,type,&r)); 4852 PetscCheck(r,PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 4853 /* Destroy the previous private SNES context */ 4854 if (snes->ops->destroy) PetscCall((*snes->ops->destroy)(snes)); 4855 /* Reinitialize function pointers in SNESOps structure */ 4856 snes->ops->setup = NULL; 4857 snes->ops->solve = NULL; 4858 snes->ops->view = NULL; 4859 snes->ops->setfromoptions = NULL; 4860 snes->ops->destroy = NULL; 4861 4862 /* It may happen the user has customized the line search before calling SNESSetType */ 4863 if (((PetscObject)snes)->type_name) PetscCall(SNESLineSearchDestroy(&snes->linesearch)); 4864 4865 /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 4866 snes->setupcalled = PETSC_FALSE; 4867 4868 PetscCall(PetscObjectChangeTypeName((PetscObject)snes,type)); 4869 PetscCall((*r)(snes)); 4870 PetscFunctionReturn(0); 4871 } 4872 4873 /*@C 4874 SNESGetType - Gets the SNES method type and name (as a string). 4875 4876 Not Collective 4877 4878 Input Parameter: 4879 . snes - nonlinear solver context 4880 4881 Output Parameter: 4882 . type - SNES method (a character string) 4883 4884 Level: intermediate 4885 4886 @*/ 4887 PetscErrorCode SNESGetType(SNES snes,SNESType *type) 4888 { 4889 PetscFunctionBegin; 4890 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4891 PetscValidPointer(type,2); 4892 *type = ((PetscObject)snes)->type_name; 4893 PetscFunctionReturn(0); 4894 } 4895 4896 /*@ 4897 SNESSetSolution - Sets the solution vector for use by the SNES routines. 4898 4899 Logically Collective on SNES 4900 4901 Input Parameters: 4902 + snes - the SNES context obtained from SNESCreate() 4903 - u - the solution vector 4904 4905 Level: beginner 4906 4907 @*/ 4908 PetscErrorCode SNESSetSolution(SNES snes, Vec u) 4909 { 4910 DM dm; 4911 4912 PetscFunctionBegin; 4913 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4914 PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 4915 PetscCall(PetscObjectReference((PetscObject) u)); 4916 PetscCall(VecDestroy(&snes->vec_sol)); 4917 4918 snes->vec_sol = u; 4919 4920 PetscCall(SNESGetDM(snes, &dm)); 4921 PetscCall(DMShellSetGlobalVector(dm, u)); 4922 PetscFunctionReturn(0); 4923 } 4924 4925 /*@ 4926 SNESGetSolution - Returns the vector where the approximate solution is 4927 stored. This is the fine grid solution when using SNESSetGridSequence(). 4928 4929 Not Collective, but Vec is parallel if SNES is parallel 4930 4931 Input Parameter: 4932 . snes - the SNES context 4933 4934 Output Parameter: 4935 . x - the solution 4936 4937 Level: intermediate 4938 4939 .seealso: `SNESGetSolutionUpdate()`, `SNESGetFunction()` 4940 @*/ 4941 PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 4942 { 4943 PetscFunctionBegin; 4944 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4945 PetscValidPointer(x,2); 4946 *x = snes->vec_sol; 4947 PetscFunctionReturn(0); 4948 } 4949 4950 /*@ 4951 SNESGetSolutionUpdate - Returns the vector where the solution update is 4952 stored. 4953 4954 Not Collective, but Vec is parallel if SNES is parallel 4955 4956 Input Parameter: 4957 . snes - the SNES context 4958 4959 Output Parameter: 4960 . x - the solution update 4961 4962 Level: advanced 4963 4964 .seealso: `SNESGetSolution()`, `SNESGetFunction()` 4965 @*/ 4966 PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 4967 { 4968 PetscFunctionBegin; 4969 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4970 PetscValidPointer(x,2); 4971 *x = snes->vec_sol_update; 4972 PetscFunctionReturn(0); 4973 } 4974 4975 /*@C 4976 SNESGetFunction - Returns the vector where the function is stored. 4977 4978 Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 4979 4980 Input Parameter: 4981 . snes - the SNES context 4982 4983 Output Parameters: 4984 + r - the vector that is used to store residuals (or NULL if you don't want it) 4985 . f - the function (or NULL if you don't want it); see SNESFunction for calling sequence details 4986 - ctx - the function context (or NULL if you don't want it) 4987 4988 Level: advanced 4989 4990 Notes: The vector r DOES NOT, in general contain the current value of the SNES nonlinear function 4991 4992 .seealso: `SNESSetFunction()`, `SNESGetSolution()`, `SNESFunction` 4993 @*/ 4994 PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx) 4995 { 4996 DM dm; 4997 4998 PetscFunctionBegin; 4999 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5000 if (r) { 5001 if (!snes->vec_func) { 5002 if (snes->vec_rhs) { 5003 PetscCall(VecDuplicate(snes->vec_rhs,&snes->vec_func)); 5004 } else if (snes->vec_sol) { 5005 PetscCall(VecDuplicate(snes->vec_sol,&snes->vec_func)); 5006 } else if (snes->dm) { 5007 PetscCall(DMCreateGlobalVector(snes->dm,&snes->vec_func)); 5008 } 5009 } 5010 *r = snes->vec_func; 5011 } 5012 PetscCall(SNESGetDM(snes,&dm)); 5013 PetscCall(DMSNESGetFunction(dm,f,ctx)); 5014 PetscFunctionReturn(0); 5015 } 5016 5017 /*@C 5018 SNESGetNGS - Returns the NGS function and context. 5019 5020 Input Parameter: 5021 . snes - the SNES context 5022 5023 Output Parameters: 5024 + f - the function (or NULL) see SNESNGSFunction for details 5025 - ctx - the function context (or NULL) 5026 5027 Level: advanced 5028 5029 .seealso: `SNESSetNGS()`, `SNESGetFunction()` 5030 @*/ 5031 5032 PetscErrorCode SNESGetNGS (SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void*), void ** ctx) 5033 { 5034 DM dm; 5035 5036 PetscFunctionBegin; 5037 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5038 PetscCall(SNESGetDM(snes,&dm)); 5039 PetscCall(DMSNESGetNGS(dm,f,ctx)); 5040 PetscFunctionReturn(0); 5041 } 5042 5043 /*@C 5044 SNESSetOptionsPrefix - Sets the prefix used for searching for all 5045 SNES options in the database. 5046 5047 Logically Collective on SNES 5048 5049 Input Parameters: 5050 + snes - the SNES context 5051 - prefix - the prefix to prepend to all option names 5052 5053 Notes: 5054 A hyphen (-) must NOT be given at the beginning of the prefix name. 5055 The first character of all runtime options is AUTOMATICALLY the hyphen. 5056 5057 Level: advanced 5058 5059 .seealso: `SNESSetFromOptions()` 5060 @*/ 5061 PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 5062 { 5063 PetscFunctionBegin; 5064 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5065 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes,prefix)); 5066 if (!snes->ksp) PetscCall(SNESGetKSP(snes,&snes->ksp)); 5067 if (snes->linesearch) { 5068 PetscCall(SNESGetLineSearch(snes,&snes->linesearch)); 5069 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix)); 5070 } 5071 PetscCall(KSPSetOptionsPrefix(snes->ksp,prefix)); 5072 PetscFunctionReturn(0); 5073 } 5074 5075 /*@C 5076 SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 5077 SNES options in the database. 5078 5079 Logically Collective on SNES 5080 5081 Input Parameters: 5082 + snes - the SNES context 5083 - prefix - the prefix to prepend to all option names 5084 5085 Notes: 5086 A hyphen (-) must NOT be given at the beginning of the prefix name. 5087 The first character of all runtime options is AUTOMATICALLY the hyphen. 5088 5089 Level: advanced 5090 5091 .seealso: `SNESGetOptionsPrefix()` 5092 @*/ 5093 PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 5094 { 5095 PetscFunctionBegin; 5096 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5097 PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix)); 5098 if (!snes->ksp) PetscCall(SNESGetKSP(snes,&snes->ksp)); 5099 if (snes->linesearch) { 5100 PetscCall(SNESGetLineSearch(snes,&snes->linesearch)); 5101 PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix)); 5102 } 5103 PetscCall(KSPAppendOptionsPrefix(snes->ksp,prefix)); 5104 PetscFunctionReturn(0); 5105 } 5106 5107 /*@C 5108 SNESGetOptionsPrefix - Sets the prefix used for searching for all 5109 SNES options in the database. 5110 5111 Not Collective 5112 5113 Input Parameter: 5114 . snes - the SNES context 5115 5116 Output Parameter: 5117 . prefix - pointer to the prefix string used 5118 5119 Notes: 5120 On the fortran side, the user should pass in a string 'prefix' of 5121 sufficient length to hold the prefix. 5122 5123 Level: advanced 5124 5125 .seealso: `SNESAppendOptionsPrefix()` 5126 @*/ 5127 PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 5128 { 5129 PetscFunctionBegin; 5130 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5131 PetscCall(PetscObjectGetOptionsPrefix((PetscObject)snes,prefix)); 5132 PetscFunctionReturn(0); 5133 } 5134 5135 /*@C 5136 SNESRegister - Adds a method to the nonlinear solver package. 5137 5138 Not collective 5139 5140 Input Parameters: 5141 + name_solver - name of a new user-defined solver 5142 - routine_create - routine to create method context 5143 5144 Notes: 5145 SNESRegister() may be called multiple times to add several user-defined solvers. 5146 5147 Sample usage: 5148 .vb 5149 SNESRegister("my_solver",MySolverCreate); 5150 .ve 5151 5152 Then, your solver can be chosen with the procedural interface via 5153 $ SNESSetType(snes,"my_solver") 5154 or at runtime via the option 5155 $ -snes_type my_solver 5156 5157 Level: advanced 5158 5159 Note: If your function is not being put into a shared library then use SNESRegister() instead 5160 5161 .seealso: `SNESRegisterAll()`, `SNESRegisterDestroy()` 5162 5163 Level: advanced 5164 @*/ 5165 PetscErrorCode SNESRegister(const char sname[],PetscErrorCode (*function)(SNES)) 5166 { 5167 PetscFunctionBegin; 5168 PetscCall(SNESInitializePackage()); 5169 PetscCall(PetscFunctionListAdd(&SNESList,sname,function)); 5170 PetscFunctionReturn(0); 5171 } 5172 5173 PetscErrorCode SNESTestLocalMin(SNES snes) 5174 { 5175 PetscInt N,i,j; 5176 Vec u,uh,fh; 5177 PetscScalar value; 5178 PetscReal norm; 5179 5180 PetscFunctionBegin; 5181 PetscCall(SNESGetSolution(snes,&u)); 5182 PetscCall(VecDuplicate(u,&uh)); 5183 PetscCall(VecDuplicate(u,&fh)); 5184 5185 /* currently only works for sequential */ 5186 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes),"Testing FormFunction() for local min\n")); 5187 PetscCall(VecGetSize(u,&N)); 5188 for (i=0; i<N; i++) { 5189 PetscCall(VecCopy(u,uh)); 5190 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes),"i = %" PetscInt_FMT "\n",i)); 5191 for (j=-10; j<11; j++) { 5192 value = PetscSign(j)*PetscExpReal(PetscAbs(j)-10.0); 5193 PetscCall(VecSetValue(uh,i,value,ADD_VALUES)); 5194 PetscCall(SNESComputeFunction(snes,uh,fh)); 5195 PetscCall(VecNorm(fh,NORM_2,&norm)); 5196 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes)," j norm %" PetscInt_FMT " %18.16e\n",j,(double)norm)); 5197 value = -value; 5198 PetscCall(VecSetValue(uh,i,value,ADD_VALUES)); 5199 } 5200 } 5201 PetscCall(VecDestroy(&uh)); 5202 PetscCall(VecDestroy(&fh)); 5203 PetscFunctionReturn(0); 5204 } 5205 5206 /*@ 5207 SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 5208 computing relative tolerance for linear solvers within an inexact 5209 Newton method. 5210 5211 Logically Collective on SNES 5212 5213 Input Parameters: 5214 + snes - SNES context 5215 - flag - PETSC_TRUE or PETSC_FALSE 5216 5217 Options Database: 5218 + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 5219 . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 5220 . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 5221 . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 5222 . -snes_ksp_ew_gamma <gamma> - Sets gamma 5223 . -snes_ksp_ew_alpha <alpha> - Sets alpha 5224 . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 5225 - -snes_ksp_ew_threshold <threshold> - Sets threshold 5226 5227 Notes: 5228 Currently, the default is to use a constant relative tolerance for 5229 the inner linear solvers. Alternatively, one can use the 5230 Eisenstat-Walker method, where the relative convergence tolerance 5231 is reset at each Newton iteration according progress of the nonlinear 5232 solver. 5233 5234 Level: advanced 5235 5236 Reference: 5237 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 5238 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 5239 5240 .seealso: `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()` 5241 @*/ 5242 PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 5243 { 5244 PetscFunctionBegin; 5245 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5246 PetscValidLogicalCollectiveBool(snes,flag,2); 5247 snes->ksp_ewconv = flag; 5248 PetscFunctionReturn(0); 5249 } 5250 5251 /*@ 5252 SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 5253 for computing relative tolerance for linear solvers within an 5254 inexact Newton method. 5255 5256 Not Collective 5257 5258 Input Parameter: 5259 . snes - SNES context 5260 5261 Output Parameter: 5262 . flag - PETSC_TRUE or PETSC_FALSE 5263 5264 Notes: 5265 Currently, the default is to use a constant relative tolerance for 5266 the inner linear solvers. Alternatively, one can use the 5267 Eisenstat-Walker method, where the relative convergence tolerance 5268 is reset at each Newton iteration according progress of the nonlinear 5269 solver. 5270 5271 Level: advanced 5272 5273 Reference: 5274 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 5275 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 5276 5277 .seealso: `SNESKSPSetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()` 5278 @*/ 5279 PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 5280 { 5281 PetscFunctionBegin; 5282 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5283 PetscValidBoolPointer(flag,2); 5284 *flag = snes->ksp_ewconv; 5285 PetscFunctionReturn(0); 5286 } 5287 5288 /*@ 5289 SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 5290 convergence criteria for the linear solvers within an inexact 5291 Newton method. 5292 5293 Logically Collective on SNES 5294 5295 Input Parameters: 5296 + snes - SNES context 5297 . version - version 1, 2 (default is 2), 3 or 4 5298 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 5299 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 5300 . gamma - multiplicative factor for version 2 rtol computation 5301 (0 <= gamma2 <= 1) 5302 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 5303 . alpha2 - power for safeguard 5304 - threshold - threshold for imposing safeguard (0 < threshold < 1) 5305 5306 Note: 5307 Version 3 was contributed by Luis Chacon, June 2006. 5308 5309 Use PETSC_DEFAULT to retain the default for any of the parameters. 5310 5311 Level: advanced 5312 5313 Reference: 5314 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 5315 inexact Newton method", Utah State University Math. Stat. Dept. Res. 5316 Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 5317 5318 .seealso: `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()` 5319 @*/ 5320 PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 5321 { 5322 SNESKSPEW *kctx; 5323 5324 PetscFunctionBegin; 5325 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5326 kctx = (SNESKSPEW*)snes->kspconvctx; 5327 PetscCheck(kctx,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 5328 PetscValidLogicalCollectiveInt(snes,version,2); 5329 PetscValidLogicalCollectiveReal(snes,rtol_0,3); 5330 PetscValidLogicalCollectiveReal(snes,rtol_max,4); 5331 PetscValidLogicalCollectiveReal(snes,gamma,5); 5332 PetscValidLogicalCollectiveReal(snes,alpha,6); 5333 PetscValidLogicalCollectiveReal(snes,alpha2,7); 5334 PetscValidLogicalCollectiveReal(snes,threshold,8); 5335 5336 if (version != PETSC_DEFAULT) kctx->version = version; 5337 if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 5338 if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 5339 if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 5340 if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 5341 if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 5342 if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 5343 5344 PetscCheck(kctx->version >= 1 && kctx->version <= 4,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1 to 4 are supported: %" PetscInt_FMT,kctx->version); 5345 PetscCheck(kctx->rtol_0 >= 0.0 && kctx->rtol_0 < 1.0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %g",(double)kctx->rtol_0); 5346 PetscCheck(kctx->rtol_max >= 0.0 && kctx->rtol_max < 1.0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%g) < 1.0",(double)kctx->rtol_max); 5347 PetscCheck(kctx->gamma >= 0.0 && kctx->gamma <= 1.0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%g) <= 1.0",(double)kctx->gamma); 5348 PetscCheck(kctx->alpha > 1.0 && kctx->alpha <= 2.0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%g) <= 2.0",(double)kctx->alpha); 5349 PetscCheck(kctx->threshold > 0.0 && kctx->threshold < 1.0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%g) < 1.0",(double)kctx->threshold); 5350 PetscFunctionReturn(0); 5351 } 5352 5353 /*@ 5354 SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 5355 convergence criteria for the linear solvers within an inexact 5356 Newton method. 5357 5358 Not Collective 5359 5360 Input Parameter: 5361 . snes - SNES context 5362 5363 Output Parameters: 5364 + version - version 1, 2 (default is 2), 3 or 4 5365 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 5366 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 5367 . gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1) 5368 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 5369 . alpha2 - power for safeguard 5370 - threshold - threshold for imposing safeguard (0 < threshold < 1) 5371 5372 Level: advanced 5373 5374 .seealso: `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPSetParametersEW()` 5375 @*/ 5376 PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 5377 { 5378 SNESKSPEW *kctx; 5379 5380 PetscFunctionBegin; 5381 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5382 kctx = (SNESKSPEW*)snes->kspconvctx; 5383 PetscCheck(kctx,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 5384 if (version) *version = kctx->version; 5385 if (rtol_0) *rtol_0 = kctx->rtol_0; 5386 if (rtol_max) *rtol_max = kctx->rtol_max; 5387 if (gamma) *gamma = kctx->gamma; 5388 if (alpha) *alpha = kctx->alpha; 5389 if (alpha2) *alpha2 = kctx->alpha2; 5390 if (threshold) *threshold = kctx->threshold; 5391 PetscFunctionReturn(0); 5392 } 5393 5394 PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 5395 { 5396 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 5397 PetscReal rtol = PETSC_DEFAULT,stol; 5398 5399 PetscFunctionBegin; 5400 if (!snes->ksp_ewconv) PetscFunctionReturn(0); 5401 if (!snes->iter) { 5402 rtol = kctx->rtol_0; /* first time in, so use the original user rtol */ 5403 PetscCall(VecNorm(snes->vec_func,NORM_2,&kctx->norm_first)); 5404 } else { 5405 if (kctx->version == 1) { 5406 rtol = PetscAbsReal(snes->norm - kctx->lresid_last)/kctx->norm_last; 5407 stol = PetscPowReal(kctx->rtol_last,kctx->alpha2); 5408 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 5409 } else if (kctx->version == 2) { 5410 rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 5411 stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha); 5412 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 5413 } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */ 5414 rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 5415 /* safeguard: avoid sharp decrease of rtol */ 5416 stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha); 5417 stol = PetscMax(rtol,stol); 5418 rtol = PetscMin(kctx->rtol_0,stol); 5419 /* safeguard: avoid oversolving */ 5420 stol = kctx->gamma*(kctx->norm_first*snes->rtol)/snes->norm; 5421 stol = PetscMax(rtol,stol); 5422 rtol = PetscMin(kctx->rtol_0,stol); 5423 } else if (kctx->version == 4) { /* H.-B. An et al. Journal of Computational and Applied Mathematics 200 (2007) 47-60 */ 5424 PetscReal ared = PetscAbsReal(kctx->norm_last - snes->norm); 5425 PetscReal pred = PetscAbsReal(kctx->norm_last - kctx->lresid_last); 5426 PetscReal rk = ared / pred; 5427 if (rk < kctx->v4_p1) rtol = 1. - 2.*kctx->v4_p1; 5428 else if (rk < kctx->v4_p2) rtol = kctx->rtol_last; 5429 else if (rk < kctx->v4_p3) rtol = kctx->v4_m1 * kctx->rtol_last; 5430 else rtol = kctx->v4_m2 * kctx->rtol_last; 5431 5432 if (kctx->rtol_last_2 > kctx->v4_m3 && kctx->rtol_last > kctx->v4_m3 && 5433 kctx->rk_last_2 < kctx->v4_p1 && kctx->rk_last < kctx->v4_p1) { 5434 rtol = kctx->v4_m4 * kctx->rtol_last; 5435 //printf("iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g (rk %g ps %g %g %g) (AD)\n",snes->iter,kctx->version,(double)rtol,rk,kctx->v4_p1,kctx->v4_p2,kctx->v4_p3); 5436 } else { 5437 //printf("iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g (rk %g ps %g %g %g)\n",snes->iter,kctx->version,(double)rtol,rk,kctx->v4_p1,kctx->v4_p2,kctx->v4_p3); 5438 } 5439 kctx->rtol_last_2 = kctx->rtol_last; 5440 kctx->rk_last_2 = kctx->rk_last; 5441 kctx->rk_last = rk; 5442 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1-4 are supported: %" PetscInt_FMT,kctx->version); 5443 } 5444 /* safeguard: avoid rtol greater than rtol_max */ 5445 rtol = PetscMin(rtol,kctx->rtol_max); 5446 PetscCall(KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT)); 5447 PetscCall(PetscInfo(snes,"iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g\n",snes->iter,kctx->version,(double)rtol)); 5448 PetscFunctionReturn(0); 5449 } 5450 5451 PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 5452 { 5453 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 5454 PCSide pcside; 5455 Vec lres; 5456 5457 PetscFunctionBegin; 5458 if (!snes->ksp_ewconv) PetscFunctionReturn(0); 5459 PetscCall(KSPGetTolerances(ksp,&kctx->rtol_last,NULL,NULL,NULL)); 5460 kctx->norm_last = snes->norm; 5461 if (kctx->version == 1 || kctx->version == 4) { 5462 PC pc; 5463 PetscBool getRes; 5464 5465 PetscCall(KSPGetPC(ksp,&pc)); 5466 PetscCall(PetscObjectTypeCompare((PetscObject)pc,PCNONE,&getRes)); 5467 if (!getRes) { 5468 KSPNormType normtype; 5469 5470 PetscCall(KSPGetNormType(ksp,&normtype)); 5471 getRes = (PetscBool)(normtype == KSP_NORM_UNPRECONDITIONED); 5472 } 5473 PetscCall(KSPGetPCSide(ksp,&pcside)); 5474 if (pcside == PC_RIGHT || getRes) { /* KSP residual is true linear residual */ 5475 PetscCall(KSPGetResidualNorm(ksp,&kctx->lresid_last)); 5476 } else { 5477 /* KSP residual is preconditioned residual */ 5478 /* compute true linear residual norm */ 5479 Mat J; 5480 PetscCall(KSPGetOperators(ksp,&J,NULL)); 5481 PetscCall(VecDuplicate(b,&lres)); 5482 PetscCall(MatMult(J,x,lres)); 5483 PetscCall(VecAYPX(lres,-1.0,b)); 5484 PetscCall(VecNorm(lres,NORM_2,&kctx->lresid_last)); 5485 PetscCall(VecDestroy(&lres)); 5486 } 5487 } 5488 PetscFunctionReturn(0); 5489 } 5490 5491 /*@ 5492 SNESGetKSP - Returns the KSP context for a SNES solver. 5493 5494 Not Collective, but if SNES object is parallel, then KSP object is parallel 5495 5496 Input Parameter: 5497 . snes - the SNES context 5498 5499 Output Parameter: 5500 . ksp - the KSP context 5501 5502 Notes: 5503 The user can then directly manipulate the KSP context to set various 5504 options, etc. Likewise, the user can then extract and manipulate the 5505 PC contexts as well. 5506 5507 Level: beginner 5508 5509 .seealso: `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()` 5510 @*/ 5511 PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 5512 { 5513 PetscFunctionBegin; 5514 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5515 PetscValidPointer(ksp,2); 5516 5517 if (!snes->ksp) { 5518 PetscCall(KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp)); 5519 PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1)); 5520 PetscCall(PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->ksp)); 5521 5522 PetscCall(KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPreSolve_SNESEW,snes)); 5523 PetscCall(KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPostSolve_SNESEW,snes)); 5524 5525 PetscCall(KSPMonitorSetFromOptions(snes->ksp, "-snes_monitor_ksp", "snes_preconditioned_residual", snes)); 5526 PetscCall(PetscObjectSetOptions((PetscObject)snes->ksp,((PetscObject)snes)->options)); 5527 } 5528 *ksp = snes->ksp; 5529 PetscFunctionReturn(0); 5530 } 5531 5532 #include <petsc/private/dmimpl.h> 5533 /*@ 5534 SNESSetDM - Sets the DM that may be used by some nonlinear solvers or their underlying preconditioners 5535 5536 Logically Collective on SNES 5537 5538 Input Parameters: 5539 + snes - the nonlinear solver context 5540 - dm - the dm, cannot be NULL 5541 5542 Notes: 5543 A DM can only be used for solving one problem at a time because information about the problem is stored on the DM, 5544 even when not using interfaces like DMSNESSetFunction(). Use DMClone() to get a distinct DM when solving different 5545 problems using the same function space. 5546 5547 Level: intermediate 5548 5549 .seealso: `SNESGetDM()`, `KSPSetDM()`, `KSPGetDM()` 5550 @*/ 5551 PetscErrorCode SNESSetDM(SNES snes,DM dm) 5552 { 5553 KSP ksp; 5554 DMSNES sdm; 5555 5556 PetscFunctionBegin; 5557 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5558 PetscValidHeaderSpecific(dm,DM_CLASSID,2); 5559 PetscCall(PetscObjectReference((PetscObject)dm)); 5560 if (snes->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */ 5561 if (snes->dm->dmsnes && !dm->dmsnes) { 5562 PetscCall(DMCopyDMSNES(snes->dm,dm)); 5563 PetscCall(DMGetDMSNES(snes->dm,&sdm)); 5564 if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */ 5565 } 5566 PetscCall(DMCoarsenHookRemove(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes)); 5567 PetscCall(DMDestroy(&snes->dm)); 5568 } 5569 snes->dm = dm; 5570 snes->dmAuto = PETSC_FALSE; 5571 5572 PetscCall(SNESGetKSP(snes,&ksp)); 5573 PetscCall(KSPSetDM(ksp,dm)); 5574 PetscCall(KSPSetDMActive(ksp,PETSC_FALSE)); 5575 if (snes->npc) { 5576 PetscCall(SNESSetDM(snes->npc,snes->dm)); 5577 PetscCall(SNESSetNPCSide(snes,snes->npcside)); 5578 } 5579 PetscFunctionReturn(0); 5580 } 5581 5582 /*@ 5583 SNESGetDM - Gets the DM that may be used by some preconditioners 5584 5585 Not Collective but DM obtained is parallel on SNES 5586 5587 Input Parameter: 5588 . snes - the preconditioner context 5589 5590 Output Parameter: 5591 . dm - the dm 5592 5593 Level: intermediate 5594 5595 .seealso: `SNESSetDM()`, `KSPSetDM()`, `KSPGetDM()` 5596 @*/ 5597 PetscErrorCode SNESGetDM(SNES snes,DM *dm) 5598 { 5599 PetscFunctionBegin; 5600 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5601 if (!snes->dm) { 5602 PetscCall(DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm)); 5603 snes->dmAuto = PETSC_TRUE; 5604 } 5605 *dm = snes->dm; 5606 PetscFunctionReturn(0); 5607 } 5608 5609 /*@ 5610 SNESSetNPC - Sets the nonlinear preconditioner to be used. 5611 5612 Collective on SNES 5613 5614 Input Parameters: 5615 + snes - iterative context obtained from SNESCreate() 5616 - pc - the preconditioner object 5617 5618 Notes: 5619 Use SNESGetNPC() to retrieve the preconditioner context (for example, 5620 to configure it using the API). 5621 5622 Level: developer 5623 5624 .seealso: `SNESGetNPC()`, `SNESHasNPC()` 5625 @*/ 5626 PetscErrorCode SNESSetNPC(SNES snes, SNES pc) 5627 { 5628 PetscFunctionBegin; 5629 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5630 PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 5631 PetscCheckSameComm(snes, 1, pc, 2); 5632 PetscCall(PetscObjectReference((PetscObject) pc)); 5633 PetscCall(SNESDestroy(&snes->npc)); 5634 snes->npc = pc; 5635 PetscCall(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->npc)); 5636 PetscFunctionReturn(0); 5637 } 5638 5639 /*@ 5640 SNESGetNPC - Creates a nonlinear preconditioning solver (SNES) to be used to precondition the nonlinear solver. 5641 5642 Not Collective; but any changes to the obtained SNES object must be applied collectively 5643 5644 Input Parameter: 5645 . snes - iterative context obtained from SNESCreate() 5646 5647 Output Parameter: 5648 . pc - preconditioner context 5649 5650 Options Database: 5651 . -npc_snes_type <type> - set the type of the SNES to use as the nonlinear preconditioner 5652 5653 Notes: 5654 If a SNES was previously set with SNESSetNPC() then that SNES is returned, otherwise a new SNES object is created. 5655 5656 The (preconditioner) SNES returned automatically inherits the same nonlinear function and Jacobian supplied to the original 5657 SNES during SNESSetUp() 5658 5659 Level: developer 5660 5661 .seealso: `SNESSetNPC()`, `SNESHasNPC()`, `SNES`, `SNESCreate()` 5662 @*/ 5663 PetscErrorCode SNESGetNPC(SNES snes, SNES *pc) 5664 { 5665 const char *optionsprefix; 5666 5667 PetscFunctionBegin; 5668 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5669 PetscValidPointer(pc, 2); 5670 if (!snes->npc) { 5671 PetscCall(SNESCreate(PetscObjectComm((PetscObject)snes),&snes->npc)); 5672 PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->npc,(PetscObject)snes,1)); 5673 PetscCall(PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->npc)); 5674 PetscCall(SNESGetOptionsPrefix(snes,&optionsprefix)); 5675 PetscCall(SNESSetOptionsPrefix(snes->npc,optionsprefix)); 5676 PetscCall(SNESAppendOptionsPrefix(snes->npc,"npc_")); 5677 PetscCall(SNESSetCountersReset(snes->npc,PETSC_FALSE)); 5678 } 5679 *pc = snes->npc; 5680 PetscFunctionReturn(0); 5681 } 5682 5683 /*@ 5684 SNESHasNPC - Returns whether a nonlinear preconditioner exists 5685 5686 Not Collective 5687 5688 Input Parameter: 5689 . snes - iterative context obtained from SNESCreate() 5690 5691 Output Parameter: 5692 . has_npc - whether the SNES has an NPC or not 5693 5694 Level: developer 5695 5696 .seealso: `SNESSetNPC()`, `SNESGetNPC()` 5697 @*/ 5698 PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc) 5699 { 5700 PetscFunctionBegin; 5701 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5702 *has_npc = (PetscBool) (snes->npc ? PETSC_TRUE : PETSC_FALSE); 5703 PetscFunctionReturn(0); 5704 } 5705 5706 /*@ 5707 SNESSetNPCSide - Sets the preconditioning side. 5708 5709 Logically Collective on SNES 5710 5711 Input Parameter: 5712 . snes - iterative context obtained from SNESCreate() 5713 5714 Output Parameter: 5715 . side - the preconditioning side, where side is one of 5716 .vb 5717 PC_LEFT - left preconditioning 5718 PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5719 .ve 5720 5721 Options Database Keys: 5722 . -snes_npc_side <right,left> - nonlinear preconditioner side 5723 5724 Notes: 5725 SNESNRICHARDSON and SNESNCG only support left preconditioning. 5726 5727 Level: intermediate 5728 5729 .seealso: `SNESGetNPCSide()`, `KSPSetPCSide()` 5730 @*/ 5731 PetscErrorCode SNESSetNPCSide(SNES snes,PCSide side) 5732 { 5733 PetscFunctionBegin; 5734 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5735 PetscValidLogicalCollectiveEnum(snes,side,2); 5736 if (side == PC_SIDE_DEFAULT) side = PC_RIGHT; 5737 PetscCheck((side == PC_LEFT) || (side == PC_RIGHT),PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONG,"Only PC_LEFT and PC_RIGHT are supported"); 5738 snes->npcside = side; 5739 PetscFunctionReturn(0); 5740 } 5741 5742 /*@ 5743 SNESGetNPCSide - Gets the preconditioning side. 5744 5745 Not Collective 5746 5747 Input Parameter: 5748 . snes - iterative context obtained from SNESCreate() 5749 5750 Output Parameter: 5751 . side - the preconditioning side, where side is one of 5752 .vb 5753 PC_LEFT - left preconditioning 5754 PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5755 .ve 5756 5757 Level: intermediate 5758 5759 .seealso: `SNESSetNPCSide()`, `KSPGetPCSide()` 5760 @*/ 5761 PetscErrorCode SNESGetNPCSide(SNES snes,PCSide *side) 5762 { 5763 PetscFunctionBegin; 5764 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5765 PetscValidPointer(side,2); 5766 *side = snes->npcside; 5767 PetscFunctionReturn(0); 5768 } 5769 5770 /*@ 5771 SNESSetLineSearch - Sets the linesearch on the SNES instance. 5772 5773 Collective on SNES 5774 5775 Input Parameters: 5776 + snes - iterative context obtained from SNESCreate() 5777 - linesearch - the linesearch object 5778 5779 Notes: 5780 Use SNESGetLineSearch() to retrieve the preconditioner context (for example, 5781 to configure it using the API). 5782 5783 Level: developer 5784 5785 .seealso: `SNESGetLineSearch()` 5786 @*/ 5787 PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch) 5788 { 5789 PetscFunctionBegin; 5790 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5791 PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 5792 PetscCheckSameComm(snes, 1, linesearch, 2); 5793 PetscCall(PetscObjectReference((PetscObject) linesearch)); 5794 PetscCall(SNESLineSearchDestroy(&snes->linesearch)); 5795 5796 snes->linesearch = linesearch; 5797 5798 PetscCall(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch)); 5799 PetscFunctionReturn(0); 5800 } 5801 5802 /*@ 5803 SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch() 5804 or creates a default line search instance associated with the SNES and returns it. 5805 5806 Not Collective 5807 5808 Input Parameter: 5809 . snes - iterative context obtained from SNESCreate() 5810 5811 Output Parameter: 5812 . linesearch - linesearch context 5813 5814 Level: beginner 5815 5816 .seealso: `SNESSetLineSearch()`, `SNESLineSearchCreate()` 5817 @*/ 5818 PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch) 5819 { 5820 const char *optionsprefix; 5821 5822 PetscFunctionBegin; 5823 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5824 PetscValidPointer(linesearch, 2); 5825 if (!snes->linesearch) { 5826 PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 5827 PetscCall(SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch)); 5828 PetscCall(SNESLineSearchSetSNES(snes->linesearch, snes)); 5829 PetscCall(SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix)); 5830 PetscCall(PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1)); 5831 PetscCall(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch)); 5832 } 5833 *linesearch = snes->linesearch; 5834 PetscFunctionReturn(0); 5835 } 5836