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