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