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