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