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