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