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 CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary)); 288 PetscCheck(isbinary,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()"); 289 290 CHKERRQ(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 CHKERRQ(PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR)); 293 CHKERRQ(SNESSetType(snes, type)); 294 if (snes->ops->load) { 295 CHKERRQ((*snes->ops->load)(snes,viewer)); 296 } 297 CHKERRQ(SNESGetDM(snes,&dm)); 298 CHKERRQ(DMGetDMSNES(dm,&dmsnes)); 299 CHKERRQ(DMSNESLoad(dmsnes,viewer)); 300 CHKERRQ(SNESGetKSP(snes,&ksp)); 301 CHKERRQ(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 CHKERRQ(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 CHKERRQ(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&viewer)); 381 } 382 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 383 PetscCheckSameComm(snes,1,viewer,2); 384 385 CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 386 CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring)); 387 CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary)); 388 CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw)); 389 #if defined(PETSC_HAVE_SAWS) 390 CHKERRQ(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 CHKERRQ(PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer)); 400 if (!snes->setupcalled) { 401 CHKERRQ(PetscViewerASCIIPrintf(viewer," SNES has not been set up so information may be incomplete\n")); 402 } 403 if (snes->ops->view) { 404 CHKERRQ(PetscViewerASCIIPushTab(viewer)); 405 CHKERRQ((*snes->ops->view)(snes,viewer)); 406 CHKERRQ(PetscViewerASCIIPopTab(viewer)); 407 } 408 CHKERRQ(PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs)); 409 CHKERRQ(PetscViewerASCIIPrintf(viewer," tolerances: relative=%g, absolute=%g, solution=%g\n",(double)snes->rtol,(double)snes->abstol,(double)snes->stol)); 410 if (snes->usesksp) { 411 CHKERRQ(PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its)); 412 } 413 CHKERRQ(PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs)); 414 CHKERRQ(SNESGetNormSchedule(snes, &normschedule)); 415 if (normschedule > 0) CHKERRQ(PetscViewerASCIIPrintf(viewer," norm schedule %s\n",SNESNormSchedules[normschedule])); 416 if (snes->gridsequence) { 417 CHKERRQ(PetscViewerASCIIPrintf(viewer," total number of grid sequence refinements=%D\n",snes->gridsequence)); 418 } 419 if (snes->ksp_ewconv) { 420 kctx = (SNESKSPEW*)snes->kspconvctx; 421 if (kctx) { 422 CHKERRQ(PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version)); 423 CHKERRQ(PetscViewerASCIIPrintf(viewer," rtol_0=%g, rtol_max=%g, threshold=%g\n",(double)kctx->rtol_0,(double)kctx->rtol_max,(double)kctx->threshold)); 424 CHKERRQ(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 CHKERRQ(PetscViewerASCIIPrintf(viewer," Preconditioned is never rebuilt\n")); 429 } else if (snes->lagpreconditioner > 1) { 430 CHKERRQ(PetscViewerASCIIPrintf(viewer," Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner)); 431 } 432 if (snes->lagjacobian == -1) { 433 CHKERRQ(PetscViewerASCIIPrintf(viewer," Jacobian is never rebuilt\n")); 434 } else if (snes->lagjacobian > 1) { 435 CHKERRQ(PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian)); 436 } 437 CHKERRQ(SNESGetDM(snes,&dm)); 438 CHKERRQ(DMSNESGetJacobian(dm,&cJ,&ctx)); 439 if (snes->mf_operator) { 440 CHKERRQ(PetscViewerASCIIPrintf(viewer," Jacobian is applied matrix-free with differencing\n")); 441 pre = "Preconditioning "; 442 } 443 if (cJ == SNESComputeJacobianDefault) { 444 CHKERRQ(PetscViewerASCIIPrintf(viewer," %sJacobian is built using finite differences one column at a time\n",pre)); 445 } else if (cJ == SNESComputeJacobianDefaultColor) { 446 CHKERRQ(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 CHKERRQ(PetscObjectQuery((PetscObject)dm,"DMDASNES_FDCOLORING",(PetscObject*)&fdcoloring)); 451 if (fdcoloring) { 452 CHKERRQ(PetscViewerASCIIPrintf(viewer," %sJacobian is built using colored finite differences on a DMDA\n",pre)); 453 } else { 454 CHKERRQ(PetscViewerASCIIPrintf(viewer," %sJacobian is built using a DMDA local Jacobian\n",pre)); 455 } 456 } else if (snes->mf) { 457 CHKERRQ(PetscViewerASCIIPrintf(viewer," Jacobian is applied matrix-free with differencing, no explicit Jacobian\n")); 458 } 459 } else if (isstring) { 460 const char *type; 461 CHKERRQ(SNESGetType(snes,&type)); 462 CHKERRQ(PetscViewerStringSPrintf(viewer," SNESType: %-7.7s",type)); 463 if (snes->ops->view) CHKERRQ((*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 CHKERRQ(PetscObjectGetComm((PetscObject)snes,&comm)); 471 CHKERRMPI(MPI_Comm_rank(comm,&rank)); 472 if (rank == 0) { 473 CHKERRQ(PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT)); 474 CHKERRQ(PetscStrncpy(type,((PetscObject)snes)->type_name,sizeof(type))); 475 CHKERRQ(PetscViewerBinaryWrite(viewer,type,sizeof(type),PETSC_CHAR)); 476 } 477 if (snes->ops->view) { 478 CHKERRQ((*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 CHKERRQ(PetscViewerDrawGetDraw(viewer,0,&draw)); 486 CHKERRQ(PetscDrawGetCurrentPoint(draw,&x,&y)); 487 CHKERRQ(PetscStrncpy(str,"SNES: ",sizeof(str))); 488 CHKERRQ(PetscStrlcat(str,((PetscObject)snes)->type_name,sizeof(str))); 489 CHKERRQ(PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLUE,PETSC_DRAW_BLACK,str,NULL,&h)); 490 bottom = y - h; 491 CHKERRQ(PetscDrawPushCurrentPoint(draw,x,bottom)); 492 if (snes->ops->view) { 493 CHKERRQ((*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 CHKERRQ(PetscObjectGetName((PetscObject)snes,&name)); 501 CHKERRMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank)); 502 if (!((PetscObject)snes)->amsmem && rank == 0) { 503 char dir[1024]; 504 505 CHKERRQ(PetscObjectViewSAWs((PetscObject)snes,viewer)); 506 CHKERRQ(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 CHKERRQ(SNESSetConvergenceHistory(snes,NULL,NULL,PETSC_DECIDE,PETSC_TRUE)); 510 } 511 CHKERRQ(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 CHKERRQ(SNESGetLineSearch(snes, &linesearch)); 518 CHKERRQ(PetscViewerASCIIPushTab(viewer)); 519 CHKERRQ(SNESLineSearchView(linesearch, viewer)); 520 CHKERRQ(PetscViewerASCIIPopTab(viewer)); 521 } 522 if (snes->npc && snes->usesnpc) { 523 CHKERRQ(PetscViewerASCIIPushTab(viewer)); 524 CHKERRQ(SNESView(snes->npc, viewer)); 525 CHKERRQ(PetscViewerASCIIPopTab(viewer)); 526 } 527 CHKERRQ(PetscViewerASCIIPushTab(viewer)); 528 CHKERRQ(DMGetDMSNES(snes->dm,&dmsnes)); 529 CHKERRQ(DMSNESView(dmsnes, viewer)); 530 CHKERRQ(PetscViewerASCIIPopTab(viewer)); 531 if (snes->usesksp) { 532 CHKERRQ(SNESGetKSP(snes,&ksp)); 533 CHKERRQ(PetscViewerASCIIPushTab(viewer)); 534 CHKERRQ(KSPView(ksp,viewer)); 535 CHKERRQ(PetscViewerASCIIPopTab(viewer)); 536 } 537 if (isdraw) { 538 PetscDraw draw; 539 CHKERRQ(PetscViewerDrawGetDraw(viewer,0,&draw)); 540 CHKERRQ(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 CHKERRQ(MatCreateVecs(A ? A : B, NULL,&snes->vec_func)); 586 } 587 588 if (version == 1) { 589 CHKERRQ(MatCreateSNESMF(snes,&J)); 590 CHKERRQ(MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix)); 591 CHKERRQ(MatSetFromOptions(J)); 592 } else if (version == 2) { 593 PetscCheck(snes->vec_func,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 594 #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL___FP16) 595 CHKERRQ(SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J)); 596 #else 597 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator routines (version 2)"); 598 #endif 599 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator routines, only version 1 and 2"); 600 601 /* attach any user provided null space that was on Amat to the newly created matrix free matrix */ 602 if (snes->jacobian) { 603 CHKERRQ(MatGetNullSpace(snes->jacobian,&nullsp)); 604 if (nullsp) { 605 CHKERRQ(MatSetNullSpace(J,nullsp)); 606 } 607 } 608 609 CHKERRQ(PetscInfo(snes,"Setting default matrix-free operator routines (version %D)\n", version)); 610 if (hasOperator) { 611 612 /* This version replaces the user provided Jacobian matrix with a 613 matrix-free version but still employs the user-provided preconditioner matrix. */ 614 CHKERRQ(SNESSetJacobian(snes,J,NULL,NULL,NULL)); 615 } else { 616 /* This version replaces both the user-provided Jacobian and the user- 617 provided preconditioner Jacobian with the default matrix free version. */ 618 if (snes->npcside == PC_LEFT && snes->npc) { 619 if (!snes->jacobian) CHKERRQ(SNESSetJacobian(snes,J,NULL,NULL,NULL)); 620 } else { 621 KSP ksp; 622 PC pc; 623 PetscBool match; 624 625 CHKERRQ(SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,NULL)); 626 /* Force no preconditioner */ 627 CHKERRQ(SNESGetKSP(snes,&ksp)); 628 CHKERRQ(KSPGetPC(ksp,&pc)); 629 CHKERRQ(PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match)); 630 if (!match) { 631 CHKERRQ(PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n")); 632 CHKERRQ(PCSetType(pc,PCNONE)); 633 } 634 } 635 } 636 CHKERRQ(MatDestroy(&J)); 637 PetscFunctionReturn(0); 638 } 639 640 static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx) 641 { 642 SNES snes = (SNES)ctx; 643 Vec Xfine,Xfine_named = NULL,Xcoarse; 644 645 PetscFunctionBegin; 646 if (PetscLogPrintInfo) { 647 PetscInt finelevel,coarselevel,fineclevel,coarseclevel; 648 CHKERRQ(DMGetRefineLevel(dmfine,&finelevel)); 649 CHKERRQ(DMGetCoarsenLevel(dmfine,&fineclevel)); 650 CHKERRQ(DMGetRefineLevel(dmcoarse,&coarselevel)); 651 CHKERRQ(DMGetCoarsenLevel(dmcoarse,&coarseclevel)); 652 CHKERRQ(PetscInfo(dmfine,"Restricting SNES solution vector from level %D-%D to level %D-%D\n",finelevel,fineclevel,coarselevel,coarseclevel)); 653 } 654 if (dmfine == snes->dm) Xfine = snes->vec_sol; 655 else { 656 CHKERRQ(DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named)); 657 Xfine = Xfine_named; 658 } 659 CHKERRQ(DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse)); 660 if (Inject) { 661 CHKERRQ(MatRestrict(Inject,Xfine,Xcoarse)); 662 } else { 663 CHKERRQ(MatRestrict(Restrict,Xfine,Xcoarse)); 664 CHKERRQ(VecPointwiseMult(Xcoarse,Xcoarse,Rscale)); 665 } 666 CHKERRQ(DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse)); 667 if (Xfine_named) CHKERRQ(DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named)); 668 PetscFunctionReturn(0); 669 } 670 671 static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm,DM dmc,void *ctx) 672 { 673 PetscFunctionBegin; 674 CHKERRQ(DMCoarsenHookAdd(dmc,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,ctx)); 675 PetscFunctionReturn(0); 676 } 677 678 /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can 679 * safely call SNESGetDM() in their residual evaluation routine. */ 680 static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,void *ctx) 681 { 682 SNES snes = (SNES)ctx; 683 Vec X,Xnamed = NULL; 684 DM dmsave; 685 void *ctxsave; 686 PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*) = NULL; 687 688 PetscFunctionBegin; 689 dmsave = snes->dm; 690 CHKERRQ(KSPGetDM(ksp,&snes->dm)); 691 if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */ 692 else { /* We are on a coarser level, this vec was initialized using a DM restrict hook */ 693 CHKERRQ(DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed)); 694 X = Xnamed; 695 CHKERRQ(SNESGetJacobian(snes,NULL,NULL,&jac,&ctxsave)); 696 /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */ 697 if (jac == SNESComputeJacobianDefaultColor) { 698 CHKERRQ(SNESSetJacobian(snes,NULL,NULL,SNESComputeJacobianDefaultColor,NULL)); 699 } 700 } 701 /* Make sure KSP DM has the Jacobian computation routine */ 702 { 703 DMSNES sdm; 704 705 CHKERRQ(DMGetDMSNES(snes->dm, &sdm)); 706 if (!sdm->ops->computejacobian) { 707 CHKERRQ(DMCopyDMSNES(dmsave, snes->dm)); 708 } 709 } 710 /* Compute the operators */ 711 CHKERRQ(SNESComputeJacobian(snes,X,A,B)); 712 /* Put the previous context back */ 713 if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) { 714 CHKERRQ(SNESSetJacobian(snes,NULL,NULL,jac,ctxsave)); 715 } 716 717 if (Xnamed) CHKERRQ(DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed)); 718 snes->dm = dmsave; 719 PetscFunctionReturn(0); 720 } 721 722 /*@ 723 SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX() 724 725 Collective 726 727 Input Parameter: 728 . snes - snes to configure 729 730 Level: developer 731 732 .seealso: SNESSetUp() 733 @*/ 734 PetscErrorCode SNESSetUpMatrices(SNES snes) 735 { 736 DM dm; 737 DMSNES sdm; 738 739 PetscFunctionBegin; 740 CHKERRQ(SNESGetDM(snes,&dm)); 741 CHKERRQ(DMGetDMSNES(dm,&sdm)); 742 if (!snes->jacobian && snes->mf) { 743 Mat J; 744 void *functx; 745 CHKERRQ(MatCreateSNESMF(snes,&J)); 746 CHKERRQ(MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix)); 747 CHKERRQ(MatSetFromOptions(J)); 748 CHKERRQ(SNESGetFunction(snes,NULL,NULL,&functx)); 749 CHKERRQ(SNESSetJacobian(snes,J,J,NULL,NULL)); 750 CHKERRQ(MatDestroy(&J)); 751 } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 752 Mat J,B; 753 CHKERRQ(MatCreateSNESMF(snes,&J)); 754 CHKERRQ(MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix)); 755 CHKERRQ(MatSetFromOptions(J)); 756 CHKERRQ(DMCreateMatrix(snes->dm,&B)); 757 /* sdm->computejacobian was already set to reach here */ 758 CHKERRQ(SNESSetJacobian(snes,J,B,NULL,NULL)); 759 CHKERRQ(MatDestroy(&J)); 760 CHKERRQ(MatDestroy(&B)); 761 } else if (!snes->jacobian_pre) { 762 PetscDS prob; 763 Mat J, B; 764 PetscBool hasPrec = PETSC_FALSE; 765 766 J = snes->jacobian; 767 CHKERRQ(DMGetDS(dm, &prob)); 768 if (prob) CHKERRQ(PetscDSHasJacobianPreconditioner(prob, &hasPrec)); 769 if (J) CHKERRQ(PetscObjectReference((PetscObject) J)); 770 else if (hasPrec) CHKERRQ(DMCreateMatrix(snes->dm, &J)); 771 CHKERRQ(DMCreateMatrix(snes->dm, &B)); 772 CHKERRQ(SNESSetJacobian(snes, J ? J : B, B, NULL, NULL)); 773 CHKERRQ(MatDestroy(&J)); 774 CHKERRQ(MatDestroy(&B)); 775 } 776 { 777 KSP ksp; 778 CHKERRQ(SNESGetKSP(snes,&ksp)); 779 CHKERRQ(KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes)); 780 CHKERRQ(DMCoarsenHookAdd(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes)); 781 } 782 PetscFunctionReturn(0); 783 } 784 785 static PetscErrorCode SNESMonitorPauseFinal_Internal(SNES snes) 786 { 787 PetscInt i; 788 789 PetscFunctionBegin; 790 if (!snes->pauseFinal) PetscFunctionReturn(0); 791 for (i = 0; i < snes->numbermonitors; ++i) { 792 PetscViewerAndFormat *vf = (PetscViewerAndFormat *) snes->monitorcontext[i]; 793 PetscDraw draw; 794 PetscReal lpause; 795 796 if (!vf) continue; 797 if (vf->lg) { 798 if (!PetscCheckPointer(vf->lg, PETSC_OBJECT)) continue; 799 if (((PetscObject) vf->lg)->classid != PETSC_DRAWLG_CLASSID) continue; 800 CHKERRQ(PetscDrawLGGetDraw(vf->lg, &draw)); 801 CHKERRQ(PetscDrawGetPause(draw, &lpause)); 802 CHKERRQ(PetscDrawSetPause(draw, -1.0)); 803 CHKERRQ(PetscDrawPause(draw)); 804 CHKERRQ(PetscDrawSetPause(draw, lpause)); 805 } else { 806 PetscBool isdraw; 807 808 if (!PetscCheckPointer(vf->viewer, PETSC_OBJECT)) continue; 809 if (((PetscObject) vf->viewer)->classid != PETSC_VIEWER_CLASSID) continue; 810 CHKERRQ(PetscObjectTypeCompare((PetscObject) vf->viewer, PETSCVIEWERDRAW, &isdraw)); 811 if (!isdraw) continue; 812 CHKERRQ(PetscViewerDrawGetDraw(vf->viewer, 0, &draw)); 813 CHKERRQ(PetscDrawGetPause(draw, &lpause)); 814 CHKERRQ(PetscDrawSetPause(draw, -1.0)); 815 CHKERRQ(PetscDrawPause(draw)); 816 CHKERRQ(PetscDrawSetPause(draw, lpause)); 817 } 818 } 819 PetscFunctionReturn(0); 820 } 821 822 /*@C 823 SNESMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 824 825 Collective on SNES 826 827 Input Parameters: 828 + snes - SNES object you wish to monitor 829 . name - the monitor type one is seeking 830 . help - message indicating what monitoring is done 831 . manual - manual page for the monitor 832 . monitor - the monitor function 833 - 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 834 835 Level: developer 836 837 .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 838 PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 839 PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 840 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 841 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 842 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 843 PetscOptionsFList(), PetscOptionsEList() 844 @*/ 845 PetscErrorCode SNESMonitorSetFromOptions(SNES snes,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNES,PetscViewerAndFormat*)) 846 { 847 PetscViewer viewer; 848 PetscViewerFormat format; 849 PetscBool flg; 850 851 PetscFunctionBegin; 852 CHKERRQ(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,name,&viewer,&format,&flg)); 853 if (flg) { 854 PetscViewerAndFormat *vf; 855 CHKERRQ(PetscViewerAndFormatCreate(viewer,format,&vf)); 856 CHKERRQ(PetscObjectDereference((PetscObject)viewer)); 857 if (monitorsetup) { 858 CHKERRQ((*monitorsetup)(snes,vf)); 859 } 860 CHKERRQ(SNESMonitorSet(snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy)); 861 } 862 PetscFunctionReturn(0); 863 } 864 865 /*@ 866 SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 867 868 Collective on SNES 869 870 Input Parameter: 871 . snes - the SNES context 872 873 Options Database Keys: 874 + -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, SNESType for complete list 875 . -snes_stol - convergence tolerance in terms of the norm 876 of the change in the solution between steps 877 . -snes_atol <abstol> - absolute tolerance of residual norm 878 . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 879 . -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence 880 . -snes_force_iteration <force> - force SNESSolve() to take at least one iteration 881 . -snes_max_it <max_it> - maximum number of iterations 882 . -snes_max_funcs <max_funcs> - maximum number of function evaluations 883 . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 884 . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 885 . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 886 . -snes_lag_preconditioner_persists <true,false> - retains the -snes_lag_preconditioner information across multiple SNESSolve() 887 . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 888 . -snes_lag_jacobian_persists <true,false> - retains the -snes_lag_jacobian information across multiple SNESSolve() 889 . -snes_trtol <trtol> - trust region tolerance 890 . -snes_no_convergence_test - skip convergence test in nonlinear 891 solver; hence iterations will continue until max_it 892 or some other criterion is reached. Saves expense 893 of convergence test 894 . -snes_monitor [ascii][:filename][:viewer format] - prints residual norm at each iteration. if no filename given prints to stdout 895 . -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration 896 . -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration 897 . -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration 898 . -snes_monitor_lg_residualnorm - plots residual norm at each iteration 899 . -snes_monitor_lg_range - plots residual norm at each iteration 900 . -snes_monitor_pause_final - Pauses all monitor drawing after the solver ends 901 . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 902 . -snes_fd_color - use finite differences with coloring to compute Jacobian 903 . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 904 . -snes_converged_reason - print the reason for convergence/divergence after each solve 905 . -npc_snes_type <type> - the SNES type to use as a nonlinear preconditioner 906 . -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. 907 - -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. 908 909 Options Database for Eisenstat-Walker method: 910 + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 911 . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 912 . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 913 . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 914 . -snes_ksp_ew_gamma <gamma> - Sets gamma 915 . -snes_ksp_ew_alpha <alpha> - Sets alpha 916 . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 917 - -snes_ksp_ew_threshold <threshold> - Sets threshold 918 919 Notes: 920 To see all options, run your program with the -help option or consult the users manual 921 922 Notes: 923 SNES supports three approaches for computing (approximate) Jacobians: user provided via SNESSetJacobian(), matrix free, and computing explicitly with 924 finite differences and coloring using MatFDColoring. It is also possible to use automatic differentiation and the MatFDColoring object. 925 926 Level: beginner 927 928 .seealso: SNESSetOptionsPrefix(), SNESResetFromOptions(), SNES, SNESCreate() 929 @*/ 930 PetscErrorCode SNESSetFromOptions(SNES snes) 931 { 932 PetscBool flg,pcset,persist,set; 933 PetscInt i,indx,lag,grids; 934 const char *deft = SNESNEWTONLS; 935 const char *convtests[] = {"default","skip","correct_pressure"}; 936 SNESKSPEW *kctx = NULL; 937 char type[256], monfilename[PETSC_MAX_PATH_LEN]; 938 PetscErrorCode ierr; 939 PCSide pcside; 940 const char *optionsprefix; 941 942 PetscFunctionBegin; 943 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 944 CHKERRQ(SNESRegisterAll()); 945 ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 946 if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name; 947 CHKERRQ(PetscOptionsFList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg)); 948 if (flg) { 949 CHKERRQ(SNESSetType(snes,type)); 950 } else if (!((PetscObject)snes)->type_name) { 951 CHKERRQ(SNESSetType(snes,deft)); 952 } 953 CHKERRQ(PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,NULL)); 954 CHKERRQ(PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,NULL)); 955 956 CHKERRQ(PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,NULL)); 957 CHKERRQ(PetscOptionsReal("-snes_divergence_tolerance","Stop if residual norm increases by this factor","SNESSetDivergenceTolerance",snes->divtol,&snes->divtol,NULL)); 958 CHKERRQ(PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,NULL)); 959 CHKERRQ(PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,NULL)); 960 CHKERRQ(PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,NULL)); 961 CHKERRQ(PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,NULL)); 962 CHKERRQ(PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,NULL)); 963 CHKERRQ(PetscOptionsBool("-snes_force_iteration","Force SNESSolve() to take at least one iteration","SNESSetForceIteration",snes->forceiteration,&snes->forceiteration,NULL)); 964 CHKERRQ(PetscOptionsBool("-snes_check_jacobian_domain_error","Check Jacobian domain error after Jacobian evaluation","SNESCheckJacobianDomainError",snes->checkjacdomainerror,&snes->checkjacdomainerror,NULL)); 965 966 CHKERRQ(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 CHKERRQ(SNESSetLagPreconditioner(snes,lag)); 970 } 971 CHKERRQ(PetscOptionsBool("-snes_lag_preconditioner_persists","Preconditioner lagging through multiple SNES solves","SNESSetLagPreconditionerPersists",snes->lagjac_persist,&persist,&flg)); 972 if (flg) { 973 CHKERRQ(SNESSetLagPreconditionerPersists(snes,persist)); 974 } 975 CHKERRQ(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 CHKERRQ(SNESSetLagJacobian(snes,lag)); 979 } 980 CHKERRQ(PetscOptionsBool("-snes_lag_jacobian_persists","Jacobian lagging through multiple SNES solves","SNESSetLagJacobianPersists",snes->lagjac_persist,&persist,&flg)); 981 if (flg) { 982 CHKERRQ(SNESSetLagJacobianPersists(snes,persist)); 983 } 984 985 CHKERRQ(PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg)); 986 if (flg) { 987 CHKERRQ(SNESSetGridSequence(snes,grids)); 988 } 989 990 CHKERRQ(PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,sizeof(convtests)/sizeof(char*),"default",&indx,&flg)); 991 if (flg) { 992 switch (indx) { 993 case 0: CHKERRQ(SNESSetConvergenceTest(snes,SNESConvergedDefault,NULL,NULL)); break; 994 case 1: CHKERRQ(SNESSetConvergenceTest(snes,SNESConvergedSkip,NULL,NULL)); break; 995 case 2: CHKERRQ(SNESSetConvergenceTest(snes,SNESConvergedCorrectPressure,NULL,NULL)); break; 996 } 997 } 998 999 CHKERRQ(PetscOptionsEList("-snes_norm_schedule","SNES Norm schedule","SNESSetNormSchedule",SNESNormSchedules,5,"function",&indx,&flg)); 1000 if (flg) CHKERRQ(SNESSetNormSchedule(snes,(SNESNormSchedule)indx)); 1001 1002 CHKERRQ(PetscOptionsEList("-snes_function_type","SNES Norm schedule","SNESSetFunctionType",SNESFunctionTypes,2,"unpreconditioned",&indx,&flg)); 1003 if (flg) CHKERRQ(SNESSetFunctionType(snes,(SNESFunctionType)indx)); 1004 1005 kctx = (SNESKSPEW*)snes->kspconvctx; 1006 1007 CHKERRQ(PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,NULL)); 1008 1009 CHKERRQ(PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,NULL)); 1010 CHKERRQ(PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,NULL)); 1011 CHKERRQ(PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,NULL)); 1012 CHKERRQ(PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,NULL)); 1013 CHKERRQ(PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,NULL)); 1014 CHKERRQ(PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,NULL)); 1015 CHKERRQ(PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,NULL)); 1016 1017 flg = PETSC_FALSE; 1018 CHKERRQ(PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,&set)); 1019 if (set && flg) CHKERRQ(SNESMonitorCancel(snes)); 1020 1021 CHKERRQ(SNESMonitorSetFromOptions(snes,"-snes_monitor","Monitor norm of function","SNESMonitorDefault",SNESMonitorDefault,SNESMonitorDefaultSetUp)); 1022 CHKERRQ(SNESMonitorSetFromOptions(snes,"-snes_monitor_short","Monitor norm of function with fewer digits","SNESMonitorDefaultShort",SNESMonitorDefaultShort,NULL)); 1023 CHKERRQ(SNESMonitorSetFromOptions(snes,"-snes_monitor_range","Monitor range of elements of function","SNESMonitorRange",SNESMonitorRange,NULL)); 1024 1025 CHKERRQ(SNESMonitorSetFromOptions(snes,"-snes_monitor_ratio","Monitor ratios of the norm of function for consecutive steps","SNESMonitorRatio",SNESMonitorRatio,SNESMonitorRatioSetUp)); 1026 CHKERRQ(SNESMonitorSetFromOptions(snes,"-snes_monitor_field","Monitor norm of function (split into fields)","SNESMonitorDefaultField",SNESMonitorDefaultField,NULL)); 1027 CHKERRQ(SNESMonitorSetFromOptions(snes,"-snes_monitor_solution","View solution at each iteration","SNESMonitorSolution",SNESMonitorSolution,NULL)); 1028 CHKERRQ(SNESMonitorSetFromOptions(snes,"-snes_monitor_solution_update","View correction at each iteration","SNESMonitorSolutionUpdate",SNESMonitorSolutionUpdate,NULL)); 1029 CHKERRQ(SNESMonitorSetFromOptions(snes,"-snes_monitor_residual","View residual at each iteration","SNESMonitorResidual",SNESMonitorResidual,NULL)); 1030 CHKERRQ(SNESMonitorSetFromOptions(snes,"-snes_monitor_jacupdate_spectrum","Print the change in the spectrum of the Jacobian","SNESMonitorJacUpdateSpectrum",SNESMonitorJacUpdateSpectrum,NULL)); 1031 CHKERRQ(SNESMonitorSetFromOptions(snes,"-snes_monitor_fields","Monitor norm of function per field","SNESMonitorSet",SNESMonitorFields,NULL)); 1032 CHKERRQ(PetscOptionsBool("-snes_monitor_pause_final", "Pauses all draw monitors at the final iterate", "SNESMonitorPauseFinal_Internal", PETSC_FALSE, &snes->pauseFinal, NULL)); 1033 1034 CHKERRQ(PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",NULL,monfilename,sizeof(monfilename),&flg)); 1035 if (flg) CHKERRQ(PetscPythonMonitorSet((PetscObject)snes,monfilename)); 1036 1037 flg = PETSC_FALSE; 1038 CHKERRQ(PetscOptionsBool("-snes_monitor_lg_range","Plot function range at each iteration","SNESMonitorLGRange",flg,&flg,NULL)); 1039 if (flg) { 1040 PetscViewer ctx; 1041 1042 CHKERRQ(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx)); 1043 CHKERRQ(SNESMonitorSet(snes,SNESMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy)); 1044 } 1045 1046 flg = PETSC_FALSE; 1047 CHKERRQ(PetscOptionsBool("-snes_converged_reason_view_cancel","Remove all converged reason viewers","SNESConvergedReasonViewCancel",flg,&flg,&set)); 1048 if (set && flg) CHKERRQ(SNESConvergedReasonViewCancel(snes)); 1049 1050 flg = PETSC_FALSE; 1051 CHKERRQ(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 CHKERRQ(SNESGetDM(snes,&dm)); 1057 CHKERRQ(DMGetDMSNES(dm,&sdm)); 1058 sdm->jacobianctx = NULL; 1059 CHKERRQ(SNESGetFunction(snes,NULL,NULL,&functx)); 1060 CHKERRQ(SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefault,functx)); 1061 CHKERRQ(PetscInfo(snes,"Setting default finite difference Jacobian matrix\n")); 1062 } 1063 1064 flg = PETSC_FALSE; 1065 CHKERRQ(PetscOptionsBool("-snes_fd_function","Use finite differences (slow) to compute function from user objective","SNESObjectiveComputeFunctionDefaultFD",flg,&flg,NULL)); 1066 if (flg) { 1067 CHKERRQ(SNESSetFunction(snes,NULL,SNESObjectiveComputeFunctionDefaultFD,NULL)); 1068 } 1069 1070 flg = PETSC_FALSE; 1071 CHKERRQ(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 CHKERRQ(SNESGetDM(snes,&dm)); 1076 CHKERRQ(DMGetDMSNES(dm,&sdm)); 1077 sdm->jacobianctx = NULL; 1078 CHKERRQ(SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefaultColor,NULL)); 1079 CHKERRQ(PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n")); 1080 } 1081 1082 flg = PETSC_FALSE; 1083 CHKERRQ(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 CHKERRQ(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 CHKERRQ(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 CHKERRQ(SNESGetNPCSide(snes,&pcside)); 1095 CHKERRQ(PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetNPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg)); 1096 if (flg) CHKERRQ(SNESSetNPCSide(snes,pcside)); 1097 1098 #if defined(PETSC_HAVE_SAWS) 1099 /* 1100 Publish convergence information using SAWs 1101 */ 1102 flg = PETSC_FALSE; 1103 CHKERRQ(PetscOptionsBool("-snes_monitor_saws","Publish SNES progress using SAWs","SNESMonitorSet",flg,&flg,NULL)); 1104 if (flg) { 1105 void *ctx; 1106 CHKERRQ(SNESMonitorSAWsCreate(snes,&ctx)); 1107 CHKERRQ(SNESMonitorSet(snes,SNESMonitorSAWs,ctx,SNESMonitorSAWsDestroy)); 1108 } 1109 #endif 1110 #if defined(PETSC_HAVE_SAWS) 1111 { 1112 PetscBool set; 1113 flg = PETSC_FALSE; 1114 CHKERRQ(PetscOptionsBool("-snes_saws_block","Block for SAWs at end of SNESSolve","PetscObjectSAWsBlock",((PetscObject)snes)->amspublishblock,&flg,&set)); 1115 if (set) { 1116 CHKERRQ(PetscObjectSAWsSetBlock((PetscObject)snes,flg)); 1117 } 1118 } 1119 #endif 1120 1121 for (i = 0; i < numberofsetfromoptions; i++) { 1122 CHKERRQ((*othersetfromoptions[i])(snes)); 1123 } 1124 1125 if (snes->ops->setfromoptions) { 1126 CHKERRQ((*snes->ops->setfromoptions)(PetscOptionsObject,snes)); 1127 } 1128 1129 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 1130 CHKERRQ(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)snes)); 1131 ierr = PetscOptionsEnd();CHKERRQ(ierr); 1132 1133 if (snes->linesearch) { 1134 CHKERRQ(SNESGetLineSearch(snes, &snes->linesearch)); 1135 CHKERRQ(SNESLineSearchSetFromOptions(snes->linesearch)); 1136 } 1137 1138 if (snes->usesksp) { 1139 if (!snes->ksp) CHKERRQ(SNESGetKSP(snes,&snes->ksp)); 1140 CHKERRQ(KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre)); 1141 CHKERRQ(KSPSetFromOptions(snes->ksp)); 1142 } 1143 1144 /* if user has set the SNES NPC type via options database, create it. */ 1145 CHKERRQ(SNESGetOptionsPrefix(snes, &optionsprefix)); 1146 CHKERRQ(PetscOptionsHasName(((PetscObject)snes)->options,optionsprefix, "-npc_snes_type", &pcset)); 1147 if (pcset && (!snes->npc)) { 1148 CHKERRQ(SNESGetNPC(snes, &snes->npc)); 1149 } 1150 if (snes->npc) { 1151 CHKERRQ(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) CHKERRQ(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 CHKERRQ(SNESGetKSP(snes,&ksp)); 1228 CHKERRQ(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 CHKERRQ(PetscObjectSAWsTakeAccess((PetscObject)snes)); 1384 snes->iter = iter; 1385 CHKERRQ(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 CHKERRQ(PetscObjectReference((PetscObject)ksp)); 1668 if (snes->ksp) CHKERRQ(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 CHKERRQ(SNESInitializePackage()); 1717 1718 CHKERRQ(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 CHKERRQ(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 CHKERRQ(PetscObjectReference((PetscObject)r)); 1871 CHKERRQ(VecDestroy(&snes->vec_func)); 1872 snes->vec_func = r; 1873 } 1874 CHKERRQ(SNESGetDM(snes,&dm)); 1875 CHKERRQ(DMSNESSetFunction(dm,f,ctx)); 1876 if (f == SNESPicardComputeFunction) { 1877 CHKERRQ(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 CHKERRQ(SNESGetFunction(snes,&vec_func,NULL,NULL)); 1917 CHKERRQ(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 CHKERRQ(SNESGetDM(snes,&dm)); 2173 CHKERRQ(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 CHKERRQ(SNESGetDM(snes,&dm)); 2188 CHKERRQ(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 CHKERRQ((*sdm->ops->computepfunction)(snes,x,f,sdm->pctx)); 2194 PetscStackPop; 2195 CHKERRQ(VecScale(f,-1.0)); 2196 if (!snes->picard) { 2197 /* Cannot share nonzero pattern because of the possible use of SNESComputeJacobianDefault() */ 2198 CHKERRQ(MatDuplicate(snes->jacobian_pre,MAT_DO_NOT_COPY_VALUES,&snes->picard)); 2199 } 2200 PetscStackPush("SNES Picard user Jacobian"); 2201 CHKERRQ((*sdm->ops->computepjacobian)(snes,x,snes->picard,snes->picard,sdm->pctx)); 2202 PetscStackPop; 2203 CHKERRQ(MatMultAdd(snes->picard,x,f,f)); 2204 } else { 2205 PetscStackPush("SNES Picard user Jacobian"); 2206 CHKERRQ((*sdm->ops->computepjacobian)(snes,x,snes->picard,snes->picard,sdm->pctx)); 2207 PetscStackPop; 2208 CHKERRQ(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 CHKERRQ(SNESGetDM(snes,&dm)); 2220 CHKERRQ(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 CHKERRQ((*sdm->ops->computepfunction)(snes,x,f,sdm->pctx)); 2226 PetscStackPop; 2227 CHKERRQ(VecScale(f,-1.0)); 2228 PetscStackPush("SNES Picard user Jacobian"); 2229 CHKERRQ((*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx)); 2230 PetscStackPop; 2231 CHKERRQ(MatMultAdd(snes->jacobian_pre,x,f,f)); 2232 } else { 2233 PetscStackPush("SNES Picard user Jacobian"); 2234 CHKERRQ((*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx)); 2235 PetscStackPop; 2236 CHKERRQ(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 CHKERRQ(MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY)); 2247 CHKERRQ(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 CHKERRQ(SNESGetDM(snes, &dm)); 2303 CHKERRQ(DMSNESSetPicard(dm,bp,J,ctx)); 2304 CHKERRQ(DMSNESSetMFFunction(dm,SNESPicardComputeMFFunction,ctx)); 2305 CHKERRQ(SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx)); 2306 CHKERRQ(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 CHKERRQ(SNESGetFunction(snes,r,NULL,NULL)); 2337 CHKERRQ(SNESGetJacobian(snes,Amat,Pmat,NULL,NULL)); 2338 CHKERRQ(SNESGetDM(snes,&dm)); 2339 CHKERRQ(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 CHKERRQ(VecValidValues(x,2,PETSC_TRUE)); 2431 2432 CHKERRQ(SNESGetDM(snes,&dm)); 2433 CHKERRQ(DMGetDMSNES(dm,&sdm)); 2434 if (sdm->ops->computefunction) { 2435 if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) { 2436 CHKERRQ(PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0)); 2437 } 2438 CHKERRQ(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 CHKERRQ((*sdm->ops->computefunction)(snes,x,y,sdm->functionctx)); 2443 PetscStackPop; 2444 CHKERRQ(VecLockReadPop(x)); 2445 if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) { 2446 CHKERRQ(PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0)); 2447 } 2448 } else if (snes->vec_rhs) { 2449 CHKERRQ(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 CHKERRQ(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 CHKERRQ(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 CHKERRQ(VecValidValues(x,2,PETSC_TRUE)); 2501 2502 CHKERRQ(SNESGetDM(snes,&dm)); 2503 CHKERRQ(DMGetDMSNES(dm,&sdm)); 2504 CHKERRQ(PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0)); 2505 CHKERRQ(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 CHKERRQ((*sdm->ops->computemffunction)(snes,x,y,sdm->mffunctionctx)); 2510 PetscStackPop; 2511 CHKERRQ(VecLockReadPop(x)); 2512 CHKERRQ(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 CHKERRQ(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) CHKERRQ(VecValidValues(b,2,PETSC_TRUE)); 2558 CHKERRQ(PetscLogEventBegin(SNES_NGSEval,snes,x,b,0)); 2559 CHKERRQ(SNESGetDM(snes,&dm)); 2560 CHKERRQ(DMGetDMSNES(dm,&sdm)); 2561 if (sdm->ops->computegs) { 2562 if (b) CHKERRQ(VecLockReadPush(b)); 2563 PetscStackPush("SNES user NGS"); 2564 CHKERRQ((*sdm->ops->computegs)(snes,x,b,sdm->gsctx)); 2565 PetscStackPop; 2566 if (b) CHKERRQ(VecLockReadPop(b)); 2567 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve()."); 2568 CHKERRQ(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 PetscErrorCode ierr; 2577 PetscReal nrm,gnorm; 2578 PetscReal threshold = 1.e-5; 2579 MatType mattype; 2580 PetscInt m,n,M,N; 2581 void *functx; 2582 PetscBool complete_print = PETSC_FALSE,threshold_print = PETSC_FALSE,test = PETSC_FALSE,flg,istranspose; 2583 PetscViewer viewer,mviewer; 2584 MPI_Comm comm; 2585 PetscInt tabs; 2586 static PetscBool directionsprinted = PETSC_FALSE; 2587 PetscViewerFormat format; 2588 2589 PetscFunctionBegin; 2590 ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 2591 CHKERRQ(PetscOptionsName("-snes_test_jacobian","Compare hand-coded and finite difference Jacobians","None",&test)); 2592 CHKERRQ(PetscOptionsReal("-snes_test_jacobian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold,NULL)); 2593 CHKERRQ(PetscOptionsViewer("-snes_test_jacobian_view","View difference between hand-coded and finite difference Jacobians element entries","None",&mviewer,&format,&complete_print)); 2594 if (!complete_print) { 2595 CHKERRQ(PetscOptionsDeprecated("-snes_test_jacobian_display","-snes_test_jacobian_view","3.13",NULL)); 2596 CHKERRQ(PetscOptionsViewer("-snes_test_jacobian_display","Display difference between hand-coded and finite difference Jacobians","None",&mviewer,&format,&complete_print)); 2597 } 2598 /* for compatibility with PETSc 3.9 and older. */ 2599 CHKERRQ(PetscOptionsDeprecated("-snes_test_jacobian_display_threshold","-snes_test_jacobian","3.13","-snes_test_jacobian accepts an optional threshold (since v3.10)")); 2600 CHKERRQ(PetscOptionsReal("-snes_test_jacobian_display_threshold", "Display difference between hand-coded and finite difference Jacobians which exceed input threshold", "None", threshold, &threshold, &threshold_print)); 2601 ierr = PetscOptionsEnd();CHKERRQ(ierr); 2602 if (!test) PetscFunctionReturn(0); 2603 2604 CHKERRQ(PetscObjectGetComm((PetscObject)snes,&comm)); 2605 CHKERRQ(PetscViewerASCIIGetStdout(comm,&viewer)); 2606 CHKERRQ(PetscViewerASCIIGetTab(viewer, &tabs)); 2607 CHKERRQ(PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel)); 2608 CHKERRQ(PetscViewerASCIIPrintf(viewer," ---------- Testing Jacobian -------------\n")); 2609 if (!complete_print && !directionsprinted) { 2610 CHKERRQ(PetscViewerASCIIPrintf(viewer," Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference\n")); 2611 CHKERRQ(PetscViewerASCIIPrintf(viewer," of hand-coded and finite difference Jacobian entries greater than <threshold>.\n")); 2612 } 2613 if (!directionsprinted) { 2614 CHKERRQ(PetscViewerASCIIPrintf(viewer," Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n")); 2615 CHKERRQ(PetscViewerASCIIPrintf(viewer," O(1.e-8), the hand-coded Jacobian is probably correct.\n")); 2616 directionsprinted = PETSC_TRUE; 2617 } 2618 if (complete_print) { 2619 CHKERRQ(PetscViewerPushFormat(mviewer,format)); 2620 } 2621 2622 CHKERRQ(PetscObjectTypeCompare((PetscObject)snes->jacobian,MATMFFD,&flg)); 2623 if (!flg) jacobian = snes->jacobian; 2624 else jacobian = snes->jacobian_pre; 2625 2626 if (!x) { 2627 CHKERRQ(MatCreateVecs(jacobian, &x, NULL)); 2628 } else { 2629 CHKERRQ(PetscObjectReference((PetscObject) x)); 2630 } 2631 if (!f) { 2632 CHKERRQ(VecDuplicate(x, &f)); 2633 } else { 2634 CHKERRQ(PetscObjectReference((PetscObject) f)); 2635 } 2636 /* evaluate the function at this point because SNESComputeJacobianDefault() assumes that the function has been evaluated and put into snes->vec_func */ 2637 CHKERRQ(SNESComputeFunction(snes,x,f)); 2638 CHKERRQ(VecDestroy(&f)); 2639 CHKERRQ(PetscObjectTypeCompare((PetscObject)snes,SNESKSPTRANSPOSEONLY,&istranspose)); 2640 while (jacobian) { 2641 Mat JT = NULL, Jsave = NULL; 2642 2643 if (istranspose) { 2644 CHKERRQ(MatCreateTranspose(jacobian,&JT)); 2645 Jsave = jacobian; 2646 jacobian = JT; 2647 } 2648 CHKERRQ(PetscObjectBaseTypeCompareAny((PetscObject)jacobian,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPISBAIJ,"")); 2649 if (flg) { 2650 A = jacobian; 2651 CHKERRQ(PetscObjectReference((PetscObject)A)); 2652 } else { 2653 CHKERRQ(MatComputeOperator(jacobian,MATAIJ,&A)); 2654 } 2655 2656 CHKERRQ(MatGetType(A,&mattype)); 2657 CHKERRQ(MatGetSize(A,&M,&N)); 2658 CHKERRQ(MatGetLocalSize(A,&m,&n)); 2659 CHKERRQ(MatCreate(PetscObjectComm((PetscObject)A),&B)); 2660 CHKERRQ(MatSetType(B,mattype)); 2661 CHKERRQ(MatSetSizes(B,m,n,M,N)); 2662 CHKERRQ(MatSetBlockSizesFromMats(B,A,A)); 2663 CHKERRQ(MatSetUp(B)); 2664 CHKERRQ(MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE)); 2665 2666 CHKERRQ(SNESGetFunction(snes,NULL,NULL,&functx)); 2667 CHKERRQ(SNESComputeJacobianDefault(snes,x,B,B,functx)); 2668 2669 CHKERRQ(MatDuplicate(B,MAT_COPY_VALUES,&D)); 2670 CHKERRQ(MatAYPX(D,-1.0,A,DIFFERENT_NONZERO_PATTERN)); 2671 CHKERRQ(MatNorm(D,NORM_FROBENIUS,&nrm)); 2672 CHKERRQ(MatNorm(A,NORM_FROBENIUS,&gnorm)); 2673 CHKERRQ(MatDestroy(&D)); 2674 if (!gnorm) gnorm = 1; /* just in case */ 2675 CHKERRQ(PetscViewerASCIIPrintf(viewer," ||J - Jfd||_F/||J||_F = %g, ||J - Jfd||_F = %g\n",(double)(nrm/gnorm),(double)nrm)); 2676 2677 if (complete_print) { 2678 CHKERRQ(PetscViewerASCIIPrintf(viewer," Hand-coded Jacobian ----------\n")); 2679 CHKERRQ(MatView(A,mviewer)); 2680 CHKERRQ(PetscViewerASCIIPrintf(viewer," Finite difference Jacobian ----------\n")); 2681 CHKERRQ(MatView(B,mviewer)); 2682 } 2683 2684 if (threshold_print || complete_print) { 2685 PetscInt Istart, Iend, *ccols, bncols, cncols, j, row; 2686 PetscScalar *cvals; 2687 const PetscInt *bcols; 2688 const PetscScalar *bvals; 2689 2690 CHKERRQ(MatCreate(PetscObjectComm((PetscObject)A),&C)); 2691 CHKERRQ(MatSetType(C,mattype)); 2692 CHKERRQ(MatSetSizes(C,m,n,M,N)); 2693 CHKERRQ(MatSetBlockSizesFromMats(C,A,A)); 2694 CHKERRQ(MatSetUp(C)); 2695 CHKERRQ(MatSetOption(C,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE)); 2696 2697 CHKERRQ(MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN)); 2698 CHKERRQ(MatGetOwnershipRange(B,&Istart,&Iend)); 2699 2700 for (row = Istart; row < Iend; row++) { 2701 CHKERRQ(MatGetRow(B,row,&bncols,&bcols,&bvals)); 2702 CHKERRQ(PetscMalloc2(bncols,&ccols,bncols,&cvals)); 2703 for (j = 0, cncols = 0; j < bncols; j++) { 2704 if (PetscAbsScalar(bvals[j]) > threshold) { 2705 ccols[cncols] = bcols[j]; 2706 cvals[cncols] = bvals[j]; 2707 cncols += 1; 2708 } 2709 } 2710 if (cncols) { 2711 CHKERRQ(MatSetValues(C,1,&row,cncols,ccols,cvals,INSERT_VALUES)); 2712 } 2713 CHKERRQ(MatRestoreRow(B,row,&bncols,&bcols,&bvals)); 2714 CHKERRQ(PetscFree2(ccols,cvals)); 2715 } 2716 CHKERRQ(MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY)); 2717 CHKERRQ(MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY)); 2718 CHKERRQ(PetscViewerASCIIPrintf(viewer," Hand-coded minus finite-difference Jacobian with tolerance %g ----------\n",(double)threshold)); 2719 CHKERRQ(MatView(C,complete_print ? mviewer : viewer)); 2720 CHKERRQ(MatDestroy(&C)); 2721 } 2722 CHKERRQ(MatDestroy(&A)); 2723 CHKERRQ(MatDestroy(&B)); 2724 CHKERRQ(MatDestroy(&JT)); 2725 if (Jsave) jacobian = Jsave; 2726 if (jacobian != snes->jacobian_pre) { 2727 jacobian = snes->jacobian_pre; 2728 CHKERRQ(PetscViewerASCIIPrintf(viewer," ---------- Testing Jacobian for preconditioner -------------\n")); 2729 } 2730 else jacobian = NULL; 2731 } 2732 CHKERRQ(VecDestroy(&x)); 2733 if (complete_print) { 2734 CHKERRQ(PetscViewerPopFormat(mviewer)); 2735 } 2736 if (mviewer) CHKERRQ(PetscViewerDestroy(&mviewer)); 2737 CHKERRQ(PetscViewerASCIISetTab(viewer,tabs)); 2738 PetscFunctionReturn(0); 2739 } 2740 2741 /*@ 2742 SNESComputeJacobian - Computes the Jacobian matrix that has been set with SNESSetJacobian(). 2743 2744 Collective on SNES 2745 2746 Input Parameters: 2747 + snes - the SNES context 2748 - x - input vector 2749 2750 Output Parameters: 2751 + A - Jacobian matrix 2752 - B - optional preconditioning matrix 2753 2754 Options Database Keys: 2755 + -snes_lag_preconditioner <lag> - how often to rebuild preconditioner 2756 . -snes_lag_jacobian <lag> - how often to rebuild Jacobian 2757 . -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. 2758 . -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 2759 . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 2760 . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 2761 . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 2762 . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 2763 . -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference 2764 . -snes_compare_coloring_display - Compute the finite difference Jacobian using coloring and display verbose differences 2765 . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 2766 . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2767 . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2768 . -snes_compare_coloring_draw - Compute the finite difference Jacobian using coloring and draw differences 2769 - -snes_compare_coloring_draw_contour - Compute the finite difference Jacobian using coloring and show contours of matrices and differences 2770 2771 Notes: 2772 Most users should not need to explicitly call this routine, as it 2773 is used internally within the nonlinear solvers. 2774 2775 Developer Notes: 2776 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 2777 for with the SNESType of test that has been removed. 2778 2779 Level: developer 2780 2781 .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 2782 @*/ 2783 PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat A,Mat B) 2784 { 2785 PetscBool flag; 2786 DM dm; 2787 DMSNES sdm; 2788 KSP ksp; 2789 2790 PetscFunctionBegin; 2791 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2792 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 2793 PetscCheckSameComm(snes,1,X,2); 2794 CHKERRQ(VecValidValues(X,2,PETSC_TRUE)); 2795 CHKERRQ(SNESGetDM(snes,&dm)); 2796 CHKERRQ(DMGetDMSNES(dm,&sdm)); 2797 2798 PetscCheck(sdm->ops->computejacobian,PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 2799 2800 /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 2801 2802 if (snes->lagjacobian == -2) { 2803 snes->lagjacobian = -1; 2804 2805 CHKERRQ(PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n")); 2806 } else if (snes->lagjacobian == -1) { 2807 CHKERRQ(PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n")); 2808 CHKERRQ(PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag)); 2809 if (flag) { 2810 CHKERRQ(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); 2811 CHKERRQ(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); 2812 } 2813 PetscFunctionReturn(0); 2814 } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) { 2815 CHKERRQ(PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter)); 2816 CHKERRQ(PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag)); 2817 if (flag) { 2818 CHKERRQ(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); 2819 CHKERRQ(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); 2820 } 2821 PetscFunctionReturn(0); 2822 } 2823 if (snes->npc && snes->npcside == PC_LEFT) { 2824 CHKERRQ(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); 2825 CHKERRQ(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); 2826 PetscFunctionReturn(0); 2827 } 2828 2829 CHKERRQ(PetscLogEventBegin(SNES_JacobianEval,snes,X,A,B)); 2830 CHKERRQ(VecLockReadPush(X)); 2831 PetscStackPush("SNES user Jacobian function"); 2832 CHKERRQ((*sdm->ops->computejacobian)(snes,X,A,B,sdm->jacobianctx)); 2833 PetscStackPop; 2834 CHKERRQ(VecLockReadPop(X)); 2835 CHKERRQ(PetscLogEventEnd(SNES_JacobianEval,snes,X,A,B)); 2836 2837 /* attach latest linearization point to the preconditioning matrix */ 2838 CHKERRQ(PetscObjectCompose((PetscObject)B,"__SNES_latest_X",(PetscObject)X)); 2839 2840 /* the next line ensures that snes->ksp exists */ 2841 CHKERRQ(SNESGetKSP(snes,&ksp)); 2842 if (snes->lagpreconditioner == -2) { 2843 CHKERRQ(PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n")); 2844 CHKERRQ(KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE)); 2845 snes->lagpreconditioner = -1; 2846 } else if (snes->lagpreconditioner == -1) { 2847 CHKERRQ(PetscInfo(snes,"Reusing preconditioner because lag is -1\n")); 2848 CHKERRQ(KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE)); 2849 } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) { 2850 CHKERRQ(PetscInfo(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter)); 2851 CHKERRQ(KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE)); 2852 } else { 2853 CHKERRQ(PetscInfo(snes,"Rebuilding preconditioner\n")); 2854 CHKERRQ(KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE)); 2855 } 2856 2857 CHKERRQ(SNESTestJacobian(snes)); 2858 /* make sure user returned a correct Jacobian and preconditioner */ 2859 /* PetscValidHeaderSpecific(A,MAT_CLASSID,3); 2860 PetscValidHeaderSpecific(B,MAT_CLASSID,4); */ 2861 { 2862 PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 2863 CHKERRQ(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit",NULL,NULL,&flag)); 2864 CHKERRQ(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",NULL,NULL,&flag_draw)); 2865 CHKERRQ(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",NULL,NULL,&flag_contour)); 2866 CHKERRQ(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_operator",NULL,NULL,&flag_operator)); 2867 if (flag || flag_draw || flag_contour) { 2868 Mat Bexp_mine = NULL,Bexp,FDexp; 2869 PetscViewer vdraw,vstdout; 2870 PetscBool flg; 2871 if (flag_operator) { 2872 CHKERRQ(MatComputeOperator(A,MATAIJ,&Bexp_mine)); 2873 Bexp = Bexp_mine; 2874 } else { 2875 /* See if the preconditioning matrix can be viewed and added directly */ 2876 CHKERRQ(PetscObjectBaseTypeCompareAny((PetscObject)B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"")); 2877 if (flg) Bexp = B; 2878 else { 2879 /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 2880 CHKERRQ(MatComputeOperator(B,MATAIJ,&Bexp_mine)); 2881 Bexp = Bexp_mine; 2882 } 2883 } 2884 CHKERRQ(MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp)); 2885 CHKERRQ(SNESComputeJacobianDefault(snes,X,FDexp,FDexp,NULL)); 2886 CHKERRQ(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout)); 2887 if (flag_draw || flag_contour) { 2888 CHKERRQ(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw)); 2889 if (flag_contour) CHKERRQ(PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR)); 2890 } else vdraw = NULL; 2891 CHKERRQ(PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator ? "Jacobian" : "preconditioning Jacobian")); 2892 if (flag) CHKERRQ(MatView(Bexp,vstdout)); 2893 if (vdraw) CHKERRQ(MatView(Bexp,vdraw)); 2894 CHKERRQ(PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n")); 2895 if (flag) CHKERRQ(MatView(FDexp,vstdout)); 2896 if (vdraw) CHKERRQ(MatView(FDexp,vdraw)); 2897 CHKERRQ(MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN)); 2898 CHKERRQ(PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n")); 2899 if (flag) CHKERRQ(MatView(FDexp,vstdout)); 2900 if (vdraw) { /* Always use contour for the difference */ 2901 CHKERRQ(PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR)); 2902 CHKERRQ(MatView(FDexp,vdraw)); 2903 CHKERRQ(PetscViewerPopFormat(vdraw)); 2904 } 2905 if (flag_contour) CHKERRQ(PetscViewerPopFormat(vdraw)); 2906 CHKERRQ(PetscViewerDestroy(&vdraw)); 2907 CHKERRQ(MatDestroy(&Bexp_mine)); 2908 CHKERRQ(MatDestroy(&FDexp)); 2909 } 2910 } 2911 { 2912 PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 2913 PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 2914 CHKERRQ(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring",NULL,NULL,&flag)); 2915 CHKERRQ(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_display",NULL,NULL,&flag_display)); 2916 CHKERRQ(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",NULL,NULL,&flag_draw)); 2917 CHKERRQ(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",NULL,NULL,&flag_contour)); 2918 CHKERRQ(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",NULL,NULL,&flag_threshold)); 2919 if (flag_threshold) { 2920 CHKERRQ(PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,NULL)); 2921 CHKERRQ(PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,NULL)); 2922 } 2923 if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 2924 Mat Bfd; 2925 PetscViewer vdraw,vstdout; 2926 MatColoring coloring; 2927 ISColoring iscoloring; 2928 MatFDColoring matfdcoloring; 2929 PetscErrorCode (*func)(SNES,Vec,Vec,void*); 2930 void *funcctx; 2931 PetscReal norm1,norm2,normmax; 2932 2933 CHKERRQ(MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&Bfd)); 2934 CHKERRQ(MatColoringCreate(Bfd,&coloring)); 2935 CHKERRQ(MatColoringSetType(coloring,MATCOLORINGSL)); 2936 CHKERRQ(MatColoringSetFromOptions(coloring)); 2937 CHKERRQ(MatColoringApply(coloring,&iscoloring)); 2938 CHKERRQ(MatColoringDestroy(&coloring)); 2939 CHKERRQ(MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring)); 2940 CHKERRQ(MatFDColoringSetFromOptions(matfdcoloring)); 2941 CHKERRQ(MatFDColoringSetUp(Bfd,iscoloring,matfdcoloring)); 2942 CHKERRQ(ISColoringDestroy(&iscoloring)); 2943 2944 /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 2945 CHKERRQ(SNESGetFunction(snes,NULL,&func,&funcctx)); 2946 CHKERRQ(MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))func,funcctx)); 2947 CHKERRQ(PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix)); 2948 CHKERRQ(PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_")); 2949 CHKERRQ(MatFDColoringSetFromOptions(matfdcoloring)); 2950 CHKERRQ(MatFDColoringApply(Bfd,matfdcoloring,X,snes)); 2951 CHKERRQ(MatFDColoringDestroy(&matfdcoloring)); 2952 2953 CHKERRQ(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout)); 2954 if (flag_draw || flag_contour) { 2955 CHKERRQ(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw)); 2956 if (flag_contour) CHKERRQ(PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR)); 2957 } else vdraw = NULL; 2958 CHKERRQ(PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n")); 2959 if (flag_display) CHKERRQ(MatView(B,vstdout)); 2960 if (vdraw) CHKERRQ(MatView(B,vdraw)); 2961 CHKERRQ(PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n")); 2962 if (flag_display) CHKERRQ(MatView(Bfd,vstdout)); 2963 if (vdraw) CHKERRQ(MatView(Bfd,vdraw)); 2964 CHKERRQ(MatAYPX(Bfd,-1.0,B,SAME_NONZERO_PATTERN)); 2965 CHKERRQ(MatNorm(Bfd,NORM_1,&norm1)); 2966 CHKERRQ(MatNorm(Bfd,NORM_FROBENIUS,&norm2)); 2967 CHKERRQ(MatNorm(Bfd,NORM_MAX,&normmax)); 2968 CHKERRQ(PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%g normFrob=%g normmax=%g\n",(double)norm1,(double)norm2,(double)normmax)); 2969 if (flag_display) CHKERRQ(MatView(Bfd,vstdout)); 2970 if (vdraw) { /* Always use contour for the difference */ 2971 CHKERRQ(PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR)); 2972 CHKERRQ(MatView(Bfd,vdraw)); 2973 CHKERRQ(PetscViewerPopFormat(vdraw)); 2974 } 2975 if (flag_contour) CHKERRQ(PetscViewerPopFormat(vdraw)); 2976 2977 if (flag_threshold) { 2978 PetscInt bs,rstart,rend,i; 2979 CHKERRQ(MatGetBlockSize(B,&bs)); 2980 CHKERRQ(MatGetOwnershipRange(B,&rstart,&rend)); 2981 for (i=rstart; i<rend; i++) { 2982 const PetscScalar *ba,*ca; 2983 const PetscInt *bj,*cj; 2984 PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 2985 PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 2986 CHKERRQ(MatGetRow(B,i,&bn,&bj,&ba)); 2987 CHKERRQ(MatGetRow(Bfd,i,&cn,&cj,&ca)); 2988 PetscCheck(bn == cn,((PetscObject)A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 2989 for (j=0; j<bn; j++) { 2990 PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 2991 if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 2992 maxentrycol = bj[j]; 2993 maxentry = PetscRealPart(ba[j]); 2994 } 2995 if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 2996 maxdiffcol = bj[j]; 2997 maxdiff = PetscRealPart(ca[j]); 2998 } 2999 if (rdiff > maxrdiff) { 3000 maxrdiffcol = bj[j]; 3001 maxrdiff = rdiff; 3002 } 3003 } 3004 if (maxrdiff > 1) { 3005 CHKERRQ(PetscViewerASCIIPrintf(vstdout,"row %D (maxentry=%g at %D, maxdiff=%g at %D, maxrdiff=%g at %D):",i,(double)maxentry,maxentrycol,(double)maxdiff,maxdiffcol,(double)maxrdiff,maxrdiffcol)); 3006 for (j=0; j<bn; j++) { 3007 PetscReal rdiff; 3008 rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 3009 if (rdiff > 1) { 3010 CHKERRQ(PetscViewerASCIIPrintf(vstdout," (%D,%g:%g)",bj[j],(double)PetscRealPart(ba[j]),(double)PetscRealPart(ca[j]))); 3011 } 3012 } 3013 CHKERRQ(PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff)); 3014 } 3015 CHKERRQ(MatRestoreRow(B,i,&bn,&bj,&ba)); 3016 CHKERRQ(MatRestoreRow(Bfd,i,&cn,&cj,&ca)); 3017 } 3018 } 3019 CHKERRQ(PetscViewerDestroy(&vdraw)); 3020 CHKERRQ(MatDestroy(&Bfd)); 3021 } 3022 } 3023 PetscFunctionReturn(0); 3024 } 3025 3026 /*MC 3027 SNESJacobianFunction - Function used to convey the nonlinear Jacobian of the function to be solved by SNES 3028 3029 Synopsis: 3030 #include "petscsnes.h" 3031 PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx); 3032 3033 Collective on snes 3034 3035 Input Parameters: 3036 + x - input vector, the Jacobian is to be computed at this value 3037 - ctx - [optional] user-defined Jacobian context 3038 3039 Output Parameters: 3040 + Amat - the matrix that defines the (approximate) Jacobian 3041 - Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 3042 3043 Level: intermediate 3044 3045 .seealso: SNESSetFunction(), SNESGetFunction(), SNESSetJacobian(), SNESGetJacobian() 3046 M*/ 3047 3048 /*@C 3049 SNESSetJacobian - Sets the function to compute Jacobian as well as the 3050 location to store the matrix. 3051 3052 Logically Collective on SNES 3053 3054 Input Parameters: 3055 + snes - the SNES context 3056 . Amat - the matrix that defines the (approximate) Jacobian 3057 . Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 3058 . J - Jacobian evaluation routine (if NULL then SNES retains any previously set value), see SNESJacobianFunction for details 3059 - ctx - [optional] user-defined context for private data for the 3060 Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value) 3061 3062 Notes: 3063 If the Amat matrix and Pmat matrix are different you must call MatAssemblyBegin/End() on 3064 each matrix. 3065 3066 If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null 3067 space to Amat and the KSP solvers will automatically use that null space as needed during the solution process. 3068 3069 If using SNESComputeJacobianDefaultColor() to assemble a Jacobian, the ctx argument 3070 must be a MatFDColoring. 3071 3072 Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 3073 example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 3074 3075 Level: beginner 3076 3077 .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESComputeJacobianDefaultColor(), MatStructure, J, 3078 SNESSetPicard(), SNESJacobianFunction 3079 @*/ 3080 PetscErrorCode SNESSetJacobian(SNES snes,Mat Amat,Mat Pmat,PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx) 3081 { 3082 DM dm; 3083 3084 PetscFunctionBegin; 3085 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3086 if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 3087 if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 3088 if (Amat) PetscCheckSameComm(snes,1,Amat,2); 3089 if (Pmat) PetscCheckSameComm(snes,1,Pmat,3); 3090 CHKERRQ(SNESGetDM(snes,&dm)); 3091 CHKERRQ(DMSNESSetJacobian(dm,J,ctx)); 3092 if (Amat) { 3093 CHKERRQ(PetscObjectReference((PetscObject)Amat)); 3094 CHKERRQ(MatDestroy(&snes->jacobian)); 3095 3096 snes->jacobian = Amat; 3097 } 3098 if (Pmat) { 3099 CHKERRQ(PetscObjectReference((PetscObject)Pmat)); 3100 CHKERRQ(MatDestroy(&snes->jacobian_pre)); 3101 3102 snes->jacobian_pre = Pmat; 3103 } 3104 PetscFunctionReturn(0); 3105 } 3106 3107 /*@C 3108 SNESGetJacobian - Returns the Jacobian matrix and optionally the user 3109 provided context for evaluating the Jacobian. 3110 3111 Not Collective, but Mat object will be parallel if SNES object is 3112 3113 Input Parameter: 3114 . snes - the nonlinear solver context 3115 3116 Output Parameters: 3117 + Amat - location to stash (approximate) Jacobian matrix (or NULL) 3118 . Pmat - location to stash matrix used to compute the preconditioner (or NULL) 3119 . J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence 3120 - ctx - location to stash Jacobian ctx (or NULL) 3121 3122 Level: advanced 3123 3124 .seealso: SNESSetJacobian(), SNESComputeJacobian(), SNESJacobianFunction, SNESGetFunction() 3125 @*/ 3126 PetscErrorCode SNESGetJacobian(SNES snes,Mat *Amat,Mat *Pmat,PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx) 3127 { 3128 DM dm; 3129 DMSNES sdm; 3130 3131 PetscFunctionBegin; 3132 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3133 if (Amat) *Amat = snes->jacobian; 3134 if (Pmat) *Pmat = snes->jacobian_pre; 3135 CHKERRQ(SNESGetDM(snes,&dm)); 3136 CHKERRQ(DMGetDMSNES(dm,&sdm)); 3137 if (J) *J = sdm->ops->computejacobian; 3138 if (ctx) *ctx = sdm->jacobianctx; 3139 PetscFunctionReturn(0); 3140 } 3141 3142 static PetscErrorCode SNESSetDefaultComputeJacobian(SNES snes) 3143 { 3144 DM dm; 3145 DMSNES sdm; 3146 3147 PetscFunctionBegin; 3148 CHKERRQ(SNESGetDM(snes,&dm)); 3149 CHKERRQ(DMGetDMSNES(dm,&sdm)); 3150 if (!sdm->ops->computejacobian && snes->jacobian_pre) { 3151 DM dm; 3152 PetscBool isdense,ismf; 3153 3154 CHKERRQ(SNESGetDM(snes,&dm)); 3155 CHKERRQ(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre,&isdense,MATSEQDENSE,MATMPIDENSE,MATDENSE,NULL)); 3156 CHKERRQ(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre,&ismf,MATMFFD,MATSHELL,NULL)); 3157 if (isdense) { 3158 CHKERRQ(DMSNESSetJacobian(dm,SNESComputeJacobianDefault,NULL)); 3159 } else if (!ismf) { 3160 CHKERRQ(DMSNESSetJacobian(dm,SNESComputeJacobianDefaultColor,NULL)); 3161 } 3162 } 3163 PetscFunctionReturn(0); 3164 } 3165 3166 /*@ 3167 SNESSetUp - Sets up the internal data structures for the later use 3168 of a nonlinear solver. 3169 3170 Collective on SNES 3171 3172 Input Parameters: 3173 . snes - the SNES context 3174 3175 Notes: 3176 For basic use of the SNES solvers the user need not explicitly call 3177 SNESSetUp(), since these actions will automatically occur during 3178 the call to SNESSolve(). However, if one wishes to control this 3179 phase separately, SNESSetUp() should be called after SNESCreate() 3180 and optional routines of the form SNESSetXXX(), but before SNESSolve(). 3181 3182 Level: advanced 3183 3184 .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 3185 @*/ 3186 PetscErrorCode SNESSetUp(SNES snes) 3187 { 3188 DM dm; 3189 DMSNES sdm; 3190 SNESLineSearch linesearch, pclinesearch; 3191 void *lsprectx,*lspostctx; 3192 PetscErrorCode (*precheck)(SNESLineSearch,Vec,Vec,PetscBool*,void*); 3193 PetscErrorCode (*postcheck)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*); 3194 PetscErrorCode (*func)(SNES,Vec,Vec,void*); 3195 Vec f,fpc; 3196 void *funcctx; 3197 PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*); 3198 void *jacctx,*appctx; 3199 Mat j,jpre; 3200 3201 PetscFunctionBegin; 3202 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3203 if (snes->setupcalled) PetscFunctionReturn(0); 3204 CHKERRQ(PetscLogEventBegin(SNES_Setup,snes,0,0,0)); 3205 3206 if (!((PetscObject)snes)->type_name) { 3207 CHKERRQ(SNESSetType(snes,SNESNEWTONLS)); 3208 } 3209 3210 CHKERRQ(SNESGetFunction(snes,&snes->vec_func,NULL,NULL)); 3211 3212 CHKERRQ(SNESGetDM(snes,&dm)); 3213 CHKERRQ(DMGetDMSNES(dm,&sdm)); 3214 PetscCheck(sdm->ops->computefunction,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Function never provided to SNES object"); 3215 CHKERRQ(SNESSetDefaultComputeJacobian(snes)); 3216 3217 if (!snes->vec_func) { 3218 CHKERRQ(DMCreateGlobalVector(dm,&snes->vec_func)); 3219 } 3220 3221 if (!snes->ksp) { 3222 CHKERRQ(SNESGetKSP(snes, &snes->ksp)); 3223 } 3224 3225 if (snes->linesearch) { 3226 CHKERRQ(SNESGetLineSearch(snes, &snes->linesearch)); 3227 CHKERRQ(SNESLineSearchSetFunction(snes->linesearch,SNESComputeFunction)); 3228 } 3229 3230 if (snes->npc && snes->npcside == PC_LEFT) { 3231 snes->mf = PETSC_TRUE; 3232 snes->mf_operator = PETSC_FALSE; 3233 } 3234 3235 if (snes->npc) { 3236 /* copy the DM over */ 3237 CHKERRQ(SNESGetDM(snes,&dm)); 3238 CHKERRQ(SNESSetDM(snes->npc,dm)); 3239 3240 CHKERRQ(SNESGetFunction(snes,&f,&func,&funcctx)); 3241 CHKERRQ(VecDuplicate(f,&fpc)); 3242 CHKERRQ(SNESSetFunction(snes->npc,fpc,func,funcctx)); 3243 CHKERRQ(SNESGetJacobian(snes,&j,&jpre,&jac,&jacctx)); 3244 CHKERRQ(SNESSetJacobian(snes->npc,j,jpre,jac,jacctx)); 3245 CHKERRQ(SNESGetApplicationContext(snes,&appctx)); 3246 CHKERRQ(SNESSetApplicationContext(snes->npc,appctx)); 3247 CHKERRQ(VecDestroy(&fpc)); 3248 3249 /* copy the function pointers over */ 3250 CHKERRQ(PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->npc)); 3251 3252 /* default to 1 iteration */ 3253 CHKERRQ(SNESSetTolerances(snes->npc,0.0,0.0,0.0,1,snes->npc->max_funcs)); 3254 if (snes->npcside == PC_RIGHT) { 3255 CHKERRQ(SNESSetNormSchedule(snes->npc,SNES_NORM_FINAL_ONLY)); 3256 } else { 3257 CHKERRQ(SNESSetNormSchedule(snes->npc,SNES_NORM_NONE)); 3258 } 3259 CHKERRQ(SNESSetFromOptions(snes->npc)); 3260 3261 /* copy the line search context over */ 3262 if (snes->linesearch && snes->npc->linesearch) { 3263 CHKERRQ(SNESGetLineSearch(snes,&linesearch)); 3264 CHKERRQ(SNESGetLineSearch(snes->npc,&pclinesearch)); 3265 CHKERRQ(SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx)); 3266 CHKERRQ(SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx)); 3267 CHKERRQ(SNESLineSearchSetPreCheck(pclinesearch,precheck,lsprectx)); 3268 CHKERRQ(SNESLineSearchSetPostCheck(pclinesearch,postcheck,lspostctx)); 3269 CHKERRQ(PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch)); 3270 } 3271 } 3272 if (snes->mf) { 3273 CHKERRQ(SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version)); 3274 } 3275 if (snes->ops->usercompute && !snes->user) { 3276 CHKERRQ((*snes->ops->usercompute)(snes,(void**)&snes->user)); 3277 } 3278 3279 snes->jac_iter = 0; 3280 snes->pre_iter = 0; 3281 3282 if (snes->ops->setup) { 3283 CHKERRQ((*snes->ops->setup)(snes)); 3284 } 3285 3286 CHKERRQ(SNESSetDefaultComputeJacobian(snes)); 3287 3288 if (snes->npc && snes->npcside == PC_LEFT) { 3289 if (snes->functype == SNES_FUNCTION_PRECONDITIONED) { 3290 if (snes->linesearch) { 3291 CHKERRQ(SNESGetLineSearch(snes,&linesearch)); 3292 CHKERRQ(SNESLineSearchSetFunction(linesearch,SNESComputeFunctionDefaultNPC)); 3293 } 3294 } 3295 } 3296 CHKERRQ(PetscLogEventEnd(SNES_Setup,snes,0,0,0)); 3297 snes->setupcalled = PETSC_TRUE; 3298 PetscFunctionReturn(0); 3299 } 3300 3301 /*@ 3302 SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 3303 3304 Collective on SNES 3305 3306 Input Parameter: 3307 . snes - iterative context obtained from SNESCreate() 3308 3309 Level: intermediate 3310 3311 Notes: 3312 Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 3313 3314 .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 3315 @*/ 3316 PetscErrorCode SNESReset(SNES snes) 3317 { 3318 PetscFunctionBegin; 3319 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3320 if (snes->ops->userdestroy && snes->user) { 3321 CHKERRQ((*snes->ops->userdestroy)((void**)&snes->user)); 3322 snes->user = NULL; 3323 } 3324 if (snes->npc) { 3325 CHKERRQ(SNESReset(snes->npc)); 3326 } 3327 3328 if (snes->ops->reset) { 3329 CHKERRQ((*snes->ops->reset)(snes)); 3330 } 3331 if (snes->ksp) { 3332 CHKERRQ(KSPReset(snes->ksp)); 3333 } 3334 3335 if (snes->linesearch) { 3336 CHKERRQ(SNESLineSearchReset(snes->linesearch)); 3337 } 3338 3339 CHKERRQ(VecDestroy(&snes->vec_rhs)); 3340 CHKERRQ(VecDestroy(&snes->vec_sol)); 3341 CHKERRQ(VecDestroy(&snes->vec_sol_update)); 3342 CHKERRQ(VecDestroy(&snes->vec_func)); 3343 CHKERRQ(MatDestroy(&snes->jacobian)); 3344 CHKERRQ(MatDestroy(&snes->jacobian_pre)); 3345 CHKERRQ(MatDestroy(&snes->picard)); 3346 CHKERRQ(VecDestroyVecs(snes->nwork,&snes->work)); 3347 CHKERRQ(VecDestroyVecs(snes->nvwork,&snes->vwork)); 3348 3349 snes->alwayscomputesfinalresidual = PETSC_FALSE; 3350 3351 snes->nwork = snes->nvwork = 0; 3352 snes->setupcalled = PETSC_FALSE; 3353 PetscFunctionReturn(0); 3354 } 3355 3356 /*@ 3357 SNESConvergedReasonViewCancel - Clears all the reasonview functions for a SNES object. 3358 3359 Collective on SNES 3360 3361 Input Parameter: 3362 . snes - iterative context obtained from SNESCreate() 3363 3364 Level: intermediate 3365 3366 .seealso: SNESCreate(), SNESDestroy(), SNESReset() 3367 @*/ 3368 PetscErrorCode SNESConvergedReasonViewCancel(SNES snes) 3369 { 3370 PetscInt i; 3371 3372 PetscFunctionBegin; 3373 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3374 for (i=0; i<snes->numberreasonviews; i++) { 3375 if (snes->reasonviewdestroy[i]) { 3376 CHKERRQ((*snes->reasonviewdestroy[i])(&snes->reasonviewcontext[i])); 3377 } 3378 } 3379 snes->numberreasonviews = 0; 3380 PetscFunctionReturn(0); 3381 } 3382 3383 /*@C 3384 SNESDestroy - Destroys the nonlinear solver context that was created 3385 with SNESCreate(). 3386 3387 Collective on SNES 3388 3389 Input Parameter: 3390 . snes - the SNES context 3391 3392 Level: beginner 3393 3394 .seealso: SNESCreate(), SNESSolve() 3395 @*/ 3396 PetscErrorCode SNESDestroy(SNES *snes) 3397 { 3398 PetscFunctionBegin; 3399 if (!*snes) PetscFunctionReturn(0); 3400 PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 3401 if (--((PetscObject)(*snes))->refct > 0) {*snes = NULL; PetscFunctionReturn(0);} 3402 3403 CHKERRQ(SNESReset((*snes))); 3404 CHKERRQ(SNESDestroy(&(*snes)->npc)); 3405 3406 /* if memory was published with SAWs then destroy it */ 3407 CHKERRQ(PetscObjectSAWsViewOff((PetscObject)*snes)); 3408 if ((*snes)->ops->destroy) CHKERRQ((*((*snes))->ops->destroy)((*snes))); 3409 3410 if ((*snes)->dm) CHKERRQ(DMCoarsenHookRemove((*snes)->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,*snes)); 3411 CHKERRQ(DMDestroy(&(*snes)->dm)); 3412 CHKERRQ(KSPDestroy(&(*snes)->ksp)); 3413 CHKERRQ(SNESLineSearchDestroy(&(*snes)->linesearch)); 3414 3415 CHKERRQ(PetscFree((*snes)->kspconvctx)); 3416 if ((*snes)->ops->convergeddestroy) { 3417 CHKERRQ((*(*snes)->ops->convergeddestroy)((*snes)->cnvP)); 3418 } 3419 if ((*snes)->conv_hist_alloc) { 3420 CHKERRQ(PetscFree2((*snes)->conv_hist,(*snes)->conv_hist_its)); 3421 } 3422 CHKERRQ(SNESMonitorCancel((*snes))); 3423 CHKERRQ(SNESConvergedReasonViewCancel((*snes))); 3424 CHKERRQ(PetscHeaderDestroy(snes)); 3425 PetscFunctionReturn(0); 3426 } 3427 3428 /* ----------- Routines to set solver parameters ---------- */ 3429 3430 /*@ 3431 SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 3432 3433 Logically Collective on SNES 3434 3435 Input Parameters: 3436 + snes - the SNES context 3437 - lag - 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 3438 the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3439 3440 Options Database Keys: 3441 + -snes_lag_jacobian_persists <true,false> - sets the persistence 3442 . -snes_lag_jacobian <-2,1,2,...> - sets the lag 3443 . -snes_lag_preconditioner_persists <true,false> - sets the persistence 3444 - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3445 3446 Notes: 3447 The default is 1 3448 The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or SNESSetLagPreconditionerPersists() was called 3449 3450 SNESSetLagPreconditionerPersists() allows using the same uniform lagging (for example every second solve) across multiple solves. 3451 3452 Level: intermediate 3453 3454 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESSetLagPreconditionerPersists(), 3455 SNESSetLagJacobianPersists() 3456 3457 @*/ 3458 PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 3459 { 3460 PetscFunctionBegin; 3461 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3462 PetscCheck(lag >= -2,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 3463 PetscCheck(lag,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 3464 PetscValidLogicalCollectiveInt(snes,lag,2); 3465 snes->lagpreconditioner = lag; 3466 PetscFunctionReturn(0); 3467 } 3468 3469 /*@ 3470 SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 3471 3472 Logically Collective on SNES 3473 3474 Input Parameters: 3475 + snes - the SNES context 3476 - steps - the number of refinements to do, defaults to 0 3477 3478 Options Database Keys: 3479 . -snes_grid_sequence <steps> - Use grid sequencing to generate initial guess 3480 3481 Level: intermediate 3482 3483 Notes: 3484 Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 3485 3486 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetGridSequence() 3487 3488 @*/ 3489 PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 3490 { 3491 PetscFunctionBegin; 3492 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3493 PetscValidLogicalCollectiveInt(snes,steps,2); 3494 snes->gridsequence = steps; 3495 PetscFunctionReturn(0); 3496 } 3497 3498 /*@ 3499 SNESGetGridSequence - gets the number of steps of grid sequencing that SNES does 3500 3501 Logically Collective on SNES 3502 3503 Input Parameter: 3504 . snes - the SNES context 3505 3506 Output Parameter: 3507 . steps - the number of refinements to do, defaults to 0 3508 3509 Options Database Keys: 3510 . -snes_grid_sequence <steps> - set number of refinements 3511 3512 Level: intermediate 3513 3514 Notes: 3515 Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 3516 3517 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESSetGridSequence() 3518 3519 @*/ 3520 PetscErrorCode SNESGetGridSequence(SNES snes,PetscInt *steps) 3521 { 3522 PetscFunctionBegin; 3523 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3524 *steps = snes->gridsequence; 3525 PetscFunctionReturn(0); 3526 } 3527 3528 /*@ 3529 SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 3530 3531 Not Collective 3532 3533 Input Parameter: 3534 . snes - the SNES context 3535 3536 Output Parameter: 3537 . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 3538 the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3539 3540 Options Database Keys: 3541 + -snes_lag_jacobian_persists <true,false> - sets the persistence 3542 . -snes_lag_jacobian <-2,1,2,...> - sets the lag 3543 . -snes_lag_preconditioner_persists <true,false> - sets the persistence 3544 - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3545 3546 Notes: 3547 The default is 1 3548 The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3549 3550 Level: intermediate 3551 3552 .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner(), SNESSetLagJacobianPersists(), SNESSetLagPreconditionerPersists() 3553 3554 @*/ 3555 PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 3556 { 3557 PetscFunctionBegin; 3558 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3559 *lag = snes->lagpreconditioner; 3560 PetscFunctionReturn(0); 3561 } 3562 3563 /*@ 3564 SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 3565 often the preconditioner is rebuilt. 3566 3567 Logically Collective on SNES 3568 3569 Input Parameters: 3570 + snes - the SNES context 3571 - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 3572 the Jacobian is built etc. -2 means rebuild at next chance but then never again 3573 3574 Options Database Keys: 3575 + -snes_lag_jacobian_persists <true,false> - sets the persistence 3576 . -snes_lag_jacobian <-2,1,2,...> - sets the lag 3577 . -snes_lag_preconditioner_persists <true,false> - sets the persistence 3578 - -snes_lag_preconditioner <-2,1,2,...> - sets the lag. 3579 3580 Notes: 3581 The default is 1 3582 The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3583 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 3584 at the next Newton step but never again (unless it is reset to another value) 3585 3586 Level: intermediate 3587 3588 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobianPersists(), SNESSetLagPreconditionerPersists() 3589 3590 @*/ 3591 PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 3592 { 3593 PetscFunctionBegin; 3594 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3595 PetscCheck(lag >= -2,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 3596 PetscCheck(lag,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 3597 PetscValidLogicalCollectiveInt(snes,lag,2); 3598 snes->lagjacobian = lag; 3599 PetscFunctionReturn(0); 3600 } 3601 3602 /*@ 3603 SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 3604 3605 Not Collective 3606 3607 Input Parameter: 3608 . snes - the SNES context 3609 3610 Output Parameter: 3611 . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 3612 the Jacobian is built etc. 3613 3614 Notes: 3615 The default is 1 3616 The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or SNESSetLagJacobianPersists() was called. 3617 3618 Level: intermediate 3619 3620 .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner(), SNESSetLagJacobianPersists(), SNESSetLagPreconditionerPersists() 3621 3622 @*/ 3623 PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 3624 { 3625 PetscFunctionBegin; 3626 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3627 *lag = snes->lagjacobian; 3628 PetscFunctionReturn(0); 3629 } 3630 3631 /*@ 3632 SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple solves 3633 3634 Logically collective on SNES 3635 3636 Input Parameters: 3637 + snes - the SNES context 3638 - flg - jacobian lagging persists if true 3639 3640 Options Database Keys: 3641 + -snes_lag_jacobian_persists <true,false> - sets the persistence 3642 . -snes_lag_jacobian <-2,1,2,...> - sets the lag 3643 . -snes_lag_preconditioner_persists <true,false> - sets the persistence 3644 - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3645 3646 Notes: 3647 This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by 3648 several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several 3649 timesteps may present huge efficiency gains. 3650 3651 Level: developer 3652 3653 .seealso: SNESSetLagPreconditionerPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC(), SNESSetLagJacobianPersists() 3654 3655 @*/ 3656 PetscErrorCode SNESSetLagJacobianPersists(SNES snes,PetscBool flg) 3657 { 3658 PetscFunctionBegin; 3659 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3660 PetscValidLogicalCollectiveBool(snes,flg,2); 3661 snes->lagjac_persist = flg; 3662 PetscFunctionReturn(0); 3663 } 3664 3665 /*@ 3666 SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple nonlinear solves 3667 3668 Logically Collective on SNES 3669 3670 Input Parameters: 3671 + snes - the SNES context 3672 - flg - preconditioner lagging persists if true 3673 3674 Options Database Keys: 3675 + -snes_lag_jacobian_persists <true,false> - sets the persistence 3676 . -snes_lag_jacobian <-2,1,2,...> - sets the lag 3677 . -snes_lag_preconditioner_persists <true,false> - sets the persistence 3678 - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3679 3680 Notes: 3681 This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale 3682 by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over 3683 several timesteps may present huge efficiency gains. 3684 3685 Level: developer 3686 3687 .seealso: SNESSetLagJacobianPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC(), SNESSetLagPreconditioner() 3688 3689 @*/ 3690 PetscErrorCode SNESSetLagPreconditionerPersists(SNES snes,PetscBool flg) 3691 { 3692 PetscFunctionBegin; 3693 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3694 PetscValidLogicalCollectiveBool(snes,flg,2); 3695 snes->lagpre_persist = flg; 3696 PetscFunctionReturn(0); 3697 } 3698 3699 /*@ 3700 SNESSetForceIteration - force SNESSolve() to take at least one iteration regardless of the initial residual norm 3701 3702 Logically Collective on SNES 3703 3704 Input Parameters: 3705 + snes - the SNES context 3706 - force - PETSC_TRUE require at least one iteration 3707 3708 Options Database Keys: 3709 . -snes_force_iteration <force> - Sets forcing an iteration 3710 3711 Notes: 3712 This is used sometimes with TS to prevent TS from detecting a false steady state solution 3713 3714 Level: intermediate 3715 3716 .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance() 3717 @*/ 3718 PetscErrorCode SNESSetForceIteration(SNES snes,PetscBool force) 3719 { 3720 PetscFunctionBegin; 3721 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3722 snes->forceiteration = force; 3723 PetscFunctionReturn(0); 3724 } 3725 3726 /*@ 3727 SNESGetForceIteration - Whether or not to force SNESSolve() take at least one iteration regardless of the initial residual norm 3728 3729 Logically Collective on SNES 3730 3731 Input Parameters: 3732 . snes - the SNES context 3733 3734 Output Parameter: 3735 . force - PETSC_TRUE requires at least one iteration. 3736 3737 Level: intermediate 3738 3739 .seealso: SNESSetForceIteration(), SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance() 3740 @*/ 3741 PetscErrorCode SNESGetForceIteration(SNES snes,PetscBool *force) 3742 { 3743 PetscFunctionBegin; 3744 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3745 *force = snes->forceiteration; 3746 PetscFunctionReturn(0); 3747 } 3748 3749 /*@ 3750 SNESSetTolerances - Sets various parameters used in convergence tests. 3751 3752 Logically Collective on SNES 3753 3754 Input Parameters: 3755 + snes - the SNES context 3756 . abstol - absolute convergence tolerance 3757 . rtol - relative convergence tolerance 3758 . stol - convergence tolerance in terms of the norm of the change in the solution between steps, || delta x || < stol*|| x || 3759 . maxit - maximum number of iterations 3760 - maxf - maximum number of function evaluations (-1 indicates no limit) 3761 3762 Options Database Keys: 3763 + -snes_atol <abstol> - Sets abstol 3764 . -snes_rtol <rtol> - Sets rtol 3765 . -snes_stol <stol> - Sets stol 3766 . -snes_max_it <maxit> - Sets maxit 3767 - -snes_max_funcs <maxf> - Sets maxf 3768 3769 Notes: 3770 The default maximum number of iterations is 50. 3771 The default maximum number of function evaluations is 1000. 3772 3773 Level: intermediate 3774 3775 .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance(), SNESSetForceIteration() 3776 @*/ 3777 PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 3778 { 3779 PetscFunctionBegin; 3780 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3781 PetscValidLogicalCollectiveReal(snes,abstol,2); 3782 PetscValidLogicalCollectiveReal(snes,rtol,3); 3783 PetscValidLogicalCollectiveReal(snes,stol,4); 3784 PetscValidLogicalCollectiveInt(snes,maxit,5); 3785 PetscValidLogicalCollectiveInt(snes,maxf,6); 3786 3787 if (abstol != PETSC_DEFAULT) { 3788 PetscCheck(abstol >= 0.0,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %g must be non-negative",(double)abstol); 3789 snes->abstol = abstol; 3790 } 3791 if (rtol != PETSC_DEFAULT) { 3792 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); 3793 snes->rtol = rtol; 3794 } 3795 if (stol != PETSC_DEFAULT) { 3796 PetscCheck(stol >= 0.0,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %g must be non-negative",(double)stol); 3797 snes->stol = stol; 3798 } 3799 if (maxit != PETSC_DEFAULT) { 3800 PetscCheck(maxit >= 0,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 3801 snes->max_its = maxit; 3802 } 3803 if (maxf != PETSC_DEFAULT) { 3804 PetscCheck(maxf >= -1,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be -1 or nonnegative",maxf); 3805 snes->max_funcs = maxf; 3806 } 3807 snes->tolerancesset = PETSC_TRUE; 3808 PetscFunctionReturn(0); 3809 } 3810 3811 /*@ 3812 SNESSetDivergenceTolerance - Sets the divergence tolerance used for the SNES divergence test. 3813 3814 Logically Collective on SNES 3815 3816 Input Parameters: 3817 + snes - the SNES context 3818 - divtol - the divergence tolerance. Use -1 to deactivate the test. 3819 3820 Options Database Keys: 3821 . -snes_divergence_tolerance <divtol> - Sets divtol 3822 3823 Notes: 3824 The default divergence tolerance is 1e4. 3825 3826 Level: intermediate 3827 3828 .seealso: SNESSetTolerances(), SNESGetDivergenceTolerance 3829 @*/ 3830 PetscErrorCode SNESSetDivergenceTolerance(SNES snes,PetscReal divtol) 3831 { 3832 PetscFunctionBegin; 3833 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3834 PetscValidLogicalCollectiveReal(snes,divtol,2); 3835 3836 if (divtol != PETSC_DEFAULT) { 3837 snes->divtol = divtol; 3838 } 3839 else { 3840 snes->divtol = 1.0e4; 3841 } 3842 PetscFunctionReturn(0); 3843 } 3844 3845 /*@ 3846 SNESGetTolerances - Gets various parameters used in convergence tests. 3847 3848 Not Collective 3849 3850 Input Parameters: 3851 + snes - the SNES context 3852 . atol - absolute convergence tolerance 3853 . rtol - relative convergence tolerance 3854 . stol - convergence tolerance in terms of the norm 3855 of the change in the solution between steps 3856 . maxit - maximum number of iterations 3857 - maxf - maximum number of function evaluations 3858 3859 Notes: 3860 The user can specify NULL for any parameter that is not needed. 3861 3862 Level: intermediate 3863 3864 .seealso: SNESSetTolerances() 3865 @*/ 3866 PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 3867 { 3868 PetscFunctionBegin; 3869 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3870 if (atol) *atol = snes->abstol; 3871 if (rtol) *rtol = snes->rtol; 3872 if (stol) *stol = snes->stol; 3873 if (maxit) *maxit = snes->max_its; 3874 if (maxf) *maxf = snes->max_funcs; 3875 PetscFunctionReturn(0); 3876 } 3877 3878 /*@ 3879 SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test. 3880 3881 Not Collective 3882 3883 Input Parameters: 3884 + snes - the SNES context 3885 - divtol - divergence tolerance 3886 3887 Level: intermediate 3888 3889 .seealso: SNESSetDivergenceTolerance() 3890 @*/ 3891 PetscErrorCode SNESGetDivergenceTolerance(SNES snes,PetscReal *divtol) 3892 { 3893 PetscFunctionBegin; 3894 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3895 if (divtol) *divtol = snes->divtol; 3896 PetscFunctionReturn(0); 3897 } 3898 3899 /*@ 3900 SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 3901 3902 Logically Collective on SNES 3903 3904 Input Parameters: 3905 + snes - the SNES context 3906 - tol - tolerance 3907 3908 Options Database Key: 3909 . -snes_trtol <tol> - Sets tol 3910 3911 Level: intermediate 3912 3913 .seealso: SNESSetTolerances() 3914 @*/ 3915 PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 3916 { 3917 PetscFunctionBegin; 3918 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3919 PetscValidLogicalCollectiveReal(snes,tol,2); 3920 snes->deltatol = tol; 3921 PetscFunctionReturn(0); 3922 } 3923 3924 PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 3925 3926 PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 3927 { 3928 PetscDrawLG lg; 3929 PetscReal x,y,per; 3930 PetscViewer v = (PetscViewer)monctx; 3931 static PetscReal prev; /* should be in the context */ 3932 PetscDraw draw; 3933 3934 PetscFunctionBegin; 3935 PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,4); 3936 CHKERRQ(PetscViewerDrawGetDrawLG(v,0,&lg)); 3937 if (!n) CHKERRQ(PetscDrawLGReset(lg)); 3938 CHKERRQ(PetscDrawLGGetDraw(lg,&draw)); 3939 CHKERRQ(PetscDrawSetTitle(draw,"Residual norm")); 3940 x = (PetscReal)n; 3941 if (rnorm > 0.0) y = PetscLog10Real(rnorm); 3942 else y = -15.0; 3943 CHKERRQ(PetscDrawLGAddPoint(lg,&x,&y)); 3944 if (n < 20 || !(n % 5) || snes->reason) { 3945 CHKERRQ(PetscDrawLGDraw(lg)); 3946 CHKERRQ(PetscDrawLGSave(lg)); 3947 } 3948 3949 CHKERRQ(PetscViewerDrawGetDrawLG(v,1,&lg)); 3950 if (!n) CHKERRQ(PetscDrawLGReset(lg)); 3951 CHKERRQ(PetscDrawLGGetDraw(lg,&draw)); 3952 CHKERRQ(PetscDrawSetTitle(draw,"% elemts > .2*max elemt")); 3953 CHKERRQ(SNESMonitorRange_Private(snes,n,&per)); 3954 x = (PetscReal)n; 3955 y = 100.0*per; 3956 CHKERRQ(PetscDrawLGAddPoint(lg,&x,&y)); 3957 if (n < 20 || !(n % 5) || snes->reason) { 3958 CHKERRQ(PetscDrawLGDraw(lg)); 3959 CHKERRQ(PetscDrawLGSave(lg)); 3960 } 3961 3962 CHKERRQ(PetscViewerDrawGetDrawLG(v,2,&lg)); 3963 if (!n) {prev = rnorm;CHKERRQ(PetscDrawLGReset(lg));} 3964 CHKERRQ(PetscDrawLGGetDraw(lg,&draw)); 3965 CHKERRQ(PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm")); 3966 x = (PetscReal)n; 3967 y = (prev - rnorm)/prev; 3968 CHKERRQ(PetscDrawLGAddPoint(lg,&x,&y)); 3969 if (n < 20 || !(n % 5) || snes->reason) { 3970 CHKERRQ(PetscDrawLGDraw(lg)); 3971 CHKERRQ(PetscDrawLGSave(lg)); 3972 } 3973 3974 CHKERRQ(PetscViewerDrawGetDrawLG(v,3,&lg)); 3975 if (!n) CHKERRQ(PetscDrawLGReset(lg)); 3976 CHKERRQ(PetscDrawLGGetDraw(lg,&draw)); 3977 CHKERRQ(PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)")); 3978 x = (PetscReal)n; 3979 y = (prev - rnorm)/(prev*per); 3980 if (n > 2) { /*skip initial crazy value */ 3981 CHKERRQ(PetscDrawLGAddPoint(lg,&x,&y)); 3982 } 3983 if (n < 20 || !(n % 5) || snes->reason) { 3984 CHKERRQ(PetscDrawLGDraw(lg)); 3985 CHKERRQ(PetscDrawLGSave(lg)); 3986 } 3987 prev = rnorm; 3988 PetscFunctionReturn(0); 3989 } 3990 3991 /*@ 3992 SNESMonitor - runs the user provided monitor routines, if they exist 3993 3994 Collective on SNES 3995 3996 Input Parameters: 3997 + snes - nonlinear solver context obtained from SNESCreate() 3998 . iter - iteration number 3999 - rnorm - relative norm of the residual 4000 4001 Notes: 4002 This routine is called by the SNES implementations. 4003 It does not typically need to be called by the user. 4004 4005 Level: developer 4006 4007 .seealso: SNESMonitorSet() 4008 @*/ 4009 PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 4010 { 4011 PetscInt i,n = snes->numbermonitors; 4012 4013 PetscFunctionBegin; 4014 CHKERRQ(VecLockReadPush(snes->vec_sol)); 4015 for (i=0; i<n; i++) { 4016 CHKERRQ((*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i])); 4017 } 4018 CHKERRQ(VecLockReadPop(snes->vec_sol)); 4019 PetscFunctionReturn(0); 4020 } 4021 4022 /* ------------ Routines to set performance monitoring options ----------- */ 4023 4024 /*MC 4025 SNESMonitorFunction - functional form passed to SNESMonitorSet() to monitor convergence of nonlinear solver 4026 4027 Synopsis: 4028 #include <petscsnes.h> 4029 $ PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx) 4030 4031 Collective on snes 4032 4033 Input Parameters: 4034 + snes - the SNES context 4035 . its - iteration number 4036 . norm - 2-norm function value (may be estimated) 4037 - mctx - [optional] monitoring context 4038 4039 Level: advanced 4040 4041 .seealso: SNESMonitorSet(), SNESMonitorGet() 4042 M*/ 4043 4044 /*@C 4045 SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 4046 iteration of the nonlinear solver to display the iteration's 4047 progress. 4048 4049 Logically Collective on SNES 4050 4051 Input Parameters: 4052 + snes - the SNES context 4053 . f - the monitor function, see SNESMonitorFunction for the calling sequence 4054 . mctx - [optional] user-defined context for private data for the 4055 monitor routine (use NULL if no context is desired) 4056 - monitordestroy - [optional] routine that frees monitor context 4057 (may be NULL) 4058 4059 Options Database Keys: 4060 + -snes_monitor - sets SNESMonitorDefault() 4061 . -snes_monitor draw::draw_lg - sets line graph monitor, 4062 - -snes_monitor_cancel - cancels all monitors that have 4063 been hardwired into a code by 4064 calls to SNESMonitorSet(), but 4065 does not cancel those set via 4066 the options database. 4067 4068 Notes: 4069 Several different monitoring routines may be set by calling 4070 SNESMonitorSet() multiple times; all will be called in the 4071 order in which they were set. 4072 4073 Fortran Notes: 4074 Only a single monitor function can be set for each SNES object 4075 4076 Level: intermediate 4077 4078 .seealso: SNESMonitorDefault(), SNESMonitorCancel(), SNESMonitorFunction 4079 @*/ 4080 PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*f)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 4081 { 4082 PetscInt i; 4083 PetscBool identical; 4084 4085 PetscFunctionBegin; 4086 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4087 for (i=0; i<snes->numbermonitors;i++) { 4088 CHKERRQ(PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))snes->monitor[i],snes->monitorcontext[i],snes->monitordestroy[i],&identical)); 4089 if (identical) PetscFunctionReturn(0); 4090 } 4091 PetscCheck(snes->numbermonitors < MAXSNESMONITORS,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 4092 snes->monitor[snes->numbermonitors] = f; 4093 snes->monitordestroy[snes->numbermonitors] = monitordestroy; 4094 snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 4095 PetscFunctionReturn(0); 4096 } 4097 4098 /*@ 4099 SNESMonitorCancel - Clears all the monitor functions for a SNES object. 4100 4101 Logically Collective on SNES 4102 4103 Input Parameters: 4104 . snes - the SNES context 4105 4106 Options Database Key: 4107 . -snes_monitor_cancel - cancels all monitors that have been hardwired 4108 into a code by calls to SNESMonitorSet(), but does not cancel those 4109 set via the options database 4110 4111 Notes: 4112 There is no way to clear one specific monitor from a SNES object. 4113 4114 Level: intermediate 4115 4116 .seealso: SNESMonitorDefault(), SNESMonitorSet() 4117 @*/ 4118 PetscErrorCode SNESMonitorCancel(SNES snes) 4119 { 4120 PetscInt i; 4121 4122 PetscFunctionBegin; 4123 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4124 for (i=0; i<snes->numbermonitors; i++) { 4125 if (snes->monitordestroy[i]) { 4126 CHKERRQ((*snes->monitordestroy[i])(&snes->monitorcontext[i])); 4127 } 4128 } 4129 snes->numbermonitors = 0; 4130 PetscFunctionReturn(0); 4131 } 4132 4133 /*MC 4134 SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver 4135 4136 Synopsis: 4137 #include <petscsnes.h> 4138 $ PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 4139 4140 Collective on snes 4141 4142 Input Parameters: 4143 + snes - the SNES context 4144 . it - current iteration (0 is the first and is before any Newton step) 4145 . xnorm - 2-norm of current iterate 4146 . gnorm - 2-norm of current step 4147 . f - 2-norm of function 4148 - cctx - [optional] convergence context 4149 4150 Output Parameter: 4151 . reason - reason for convergence/divergence, only needs to be set when convergence or divergence is detected 4152 4153 Level: intermediate 4154 4155 .seealso: SNESSetConvergenceTest(), SNESGetConvergenceTest() 4156 M*/ 4157 4158 /*@C 4159 SNESSetConvergenceTest - Sets the function that is to be used 4160 to test for convergence of the nonlinear iterative solution. 4161 4162 Logically Collective on SNES 4163 4164 Input Parameters: 4165 + snes - the SNES context 4166 . SNESConvergenceTestFunction - routine to test for convergence 4167 . cctx - [optional] context for private data for the convergence routine (may be NULL) 4168 - destroy - [optional] destructor for the context (may be NULL; PETSC_NULL_FUNCTION in Fortran) 4169 4170 Level: advanced 4171 4172 .seealso: SNESConvergedDefault(), SNESConvergedSkip(), SNESConvergenceTestFunction 4173 @*/ 4174 PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*SNESConvergenceTestFunction)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 4175 { 4176 PetscFunctionBegin; 4177 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4178 if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip; 4179 if (snes->ops->convergeddestroy) { 4180 CHKERRQ((*snes->ops->convergeddestroy)(snes->cnvP)); 4181 } 4182 snes->ops->converged = SNESConvergenceTestFunction; 4183 snes->ops->convergeddestroy = destroy; 4184 snes->cnvP = cctx; 4185 PetscFunctionReturn(0); 4186 } 4187 4188 /*@ 4189 SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 4190 4191 Not Collective 4192 4193 Input Parameter: 4194 . snes - the SNES context 4195 4196 Output Parameter: 4197 . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 4198 manual pages for the individual convergence tests for complete lists 4199 4200 Options Database: 4201 . -snes_converged_reason - prints the reason to standard out 4202 4203 Level: intermediate 4204 4205 Notes: 4206 Should only be called after the call the SNESSolve() is complete, if it is called earlier it returns the value SNES__CONVERGED_ITERATING. 4207 4208 .seealso: SNESSetConvergenceTest(), SNESSetConvergedReason(), SNESConvergedReason 4209 @*/ 4210 PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 4211 { 4212 PetscFunctionBegin; 4213 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4214 PetscValidPointer(reason,2); 4215 *reason = snes->reason; 4216 PetscFunctionReturn(0); 4217 } 4218 4219 /*@C 4220 SNESGetConvergedReasonString - Return a human readable string for snes converged reason 4221 4222 Not Collective 4223 4224 Input Parameter: 4225 . snes - the SNES context 4226 4227 Output Parameter: 4228 . strreason - a human readable string that describes SNES converged reason 4229 4230 Level: beginner 4231 4232 .seealso: SNESGetConvergedReason() 4233 @*/ 4234 PetscErrorCode SNESGetConvergedReasonString(SNES snes, const char** strreason) 4235 { 4236 PetscFunctionBegin; 4237 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4238 PetscValidPointer(strreason,2); 4239 *strreason = SNESConvergedReasons[snes->reason]; 4240 PetscFunctionReturn(0); 4241 } 4242 4243 /*@ 4244 SNESSetConvergedReason - Sets the reason the SNES iteration was stopped. 4245 4246 Not Collective 4247 4248 Input Parameters: 4249 + snes - the SNES context 4250 - reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 4251 manual pages for the individual convergence tests for complete lists 4252 4253 Level: intermediate 4254 4255 .seealso: SNESGetConvergedReason(), SNESSetConvergenceTest(), SNESConvergedReason 4256 @*/ 4257 PetscErrorCode SNESSetConvergedReason(SNES snes,SNESConvergedReason reason) 4258 { 4259 PetscFunctionBegin; 4260 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4261 snes->reason = reason; 4262 PetscFunctionReturn(0); 4263 } 4264 4265 /*@ 4266 SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 4267 4268 Logically Collective on SNES 4269 4270 Input Parameters: 4271 + snes - iterative context obtained from SNESCreate() 4272 . a - array to hold history, this array will contain the function norms computed at each step 4273 . its - integer array holds the number of linear iterations for each solve. 4274 . na - size of a and its 4275 - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 4276 else it continues storing new values for new nonlinear solves after the old ones 4277 4278 Notes: 4279 If 'a' and 'its' are NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 4280 default array of length 10000 is allocated. 4281 4282 This routine is useful, e.g., when running a code for purposes 4283 of accurate performance monitoring, when no I/O should be done 4284 during the section of code that is being timed. 4285 4286 Level: intermediate 4287 4288 .seealso: SNESGetConvergenceHistory() 4289 4290 @*/ 4291 PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 4292 { 4293 PetscFunctionBegin; 4294 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4295 if (a) PetscValidRealPointer(a,2); 4296 if (its) PetscValidIntPointer(its,3); 4297 if (!a) { 4298 if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 4299 CHKERRQ(PetscCalloc2(na,&a,na,&its)); 4300 snes->conv_hist_alloc = PETSC_TRUE; 4301 } 4302 snes->conv_hist = a; 4303 snes->conv_hist_its = its; 4304 snes->conv_hist_max = (size_t)na; 4305 snes->conv_hist_len = 0; 4306 snes->conv_hist_reset = reset; 4307 PetscFunctionReturn(0); 4308 } 4309 4310 #if defined(PETSC_HAVE_MATLAB_ENGINE) 4311 #include <engine.h> /* MATLAB include file */ 4312 #include <mex.h> /* MATLAB include file */ 4313 4314 PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 4315 { 4316 mxArray *mat; 4317 PetscInt i; 4318 PetscReal *ar; 4319 4320 PetscFunctionBegin; 4321 mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 4322 ar = (PetscReal*) mxGetData(mat); 4323 for (i=0; i<snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i]; 4324 PetscFunctionReturn(mat); 4325 } 4326 #endif 4327 4328 /*@C 4329 SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 4330 4331 Not Collective 4332 4333 Input Parameter: 4334 . snes - iterative context obtained from SNESCreate() 4335 4336 Output Parameters: 4337 + a - array to hold history 4338 . its - integer array holds the number of linear iterations (or 4339 negative if not converged) for each solve. 4340 - na - size of a and its 4341 4342 Notes: 4343 The calling sequence for this routine in Fortran is 4344 $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 4345 4346 This routine is useful, e.g., when running a code for purposes 4347 of accurate performance monitoring, when no I/O should be done 4348 during the section of code that is being timed. 4349 4350 Level: intermediate 4351 4352 .seealso: SNESSetConvergenceHistory() 4353 4354 @*/ 4355 PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 4356 { 4357 PetscFunctionBegin; 4358 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4359 if (a) *a = snes->conv_hist; 4360 if (its) *its = snes->conv_hist_its; 4361 if (na) *na = (PetscInt) snes->conv_hist_len; 4362 PetscFunctionReturn(0); 4363 } 4364 4365 /*@C 4366 SNESSetUpdate - Sets the general-purpose update function called 4367 at the beginning of every iteration of the nonlinear solve. Specifically 4368 it is called just before the Jacobian is "evaluated". 4369 4370 Logically Collective on SNES 4371 4372 Input Parameters: 4373 + snes - The nonlinear solver context 4374 - func - The function 4375 4376 Calling sequence of func: 4377 $ func (SNES snes, PetscInt step); 4378 4379 . step - The current step of the iteration 4380 4381 Level: advanced 4382 4383 Note: 4384 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() 4385 This is not used by most users. 4386 4387 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. 4388 4389 .seealso SNESSetJacobian(), SNESSolve(), SNESLineSearchSetPreCheck(), SNESLineSearchSetPostCheck(), SNESNewtonTRSetPreCheck(), SNESNewtonTRSetPostCheck(), 4390 SNESMonitorSet(), SNESSetDivergenceTest() 4391 @*/ 4392 PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 4393 { 4394 PetscFunctionBegin; 4395 PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 4396 snes->ops->update = func; 4397 PetscFunctionReturn(0); 4398 } 4399 4400 /* 4401 SNESScaleStep_Private - Scales a step so that its length is less than the 4402 positive parameter delta. 4403 4404 Input Parameters: 4405 + snes - the SNES context 4406 . y - approximate solution of linear system 4407 . fnorm - 2-norm of current function 4408 - delta - trust region size 4409 4410 Output Parameters: 4411 + gpnorm - predicted function norm at the new point, assuming local 4412 linearization. The value is zero if the step lies within the trust 4413 region, and exceeds zero otherwise. 4414 - ynorm - 2-norm of the step 4415 4416 Note: 4417 For non-trust region methods such as SNESNEWTONLS, the parameter delta 4418 is set to be the maximum allowable step size. 4419 4420 */ 4421 PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 4422 { 4423 PetscReal nrm; 4424 PetscScalar cnorm; 4425 4426 PetscFunctionBegin; 4427 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4428 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 4429 PetscCheckSameComm(snes,1,y,2); 4430 4431 CHKERRQ(VecNorm(y,NORM_2,&nrm)); 4432 if (nrm > *delta) { 4433 nrm = *delta/nrm; 4434 *gpnorm = (1.0 - nrm)*(*fnorm); 4435 cnorm = nrm; 4436 CHKERRQ(VecScale(y,cnorm)); 4437 *ynorm = *delta; 4438 } else { 4439 *gpnorm = 0.0; 4440 *ynorm = nrm; 4441 } 4442 PetscFunctionReturn(0); 4443 } 4444 4445 /*@C 4446 SNESConvergedReasonView - Displays the reason a SNES solve converged or diverged to a viewer 4447 4448 Collective on SNES 4449 4450 Parameter: 4451 + snes - iterative context obtained from SNESCreate() 4452 - viewer - the viewer to display the reason 4453 4454 Options Database Keys: 4455 + -snes_converged_reason - print reason for converged or diverged, also prints number of iterations 4456 - -snes_converged_reason ::failed - only print reason and number of iterations when diverged 4457 4458 Notes: 4459 To change the format of the output call PetscViewerPushFormat(viewer,format) before this call. Use PETSC_VIEWER_DEFAULT for the default, 4460 use PETSC_VIEWER_FAILED to only display a reason if it fails. 4461 4462 Level: beginner 4463 4464 .seealso: SNESCreate(), SNESSetUp(), SNESDestroy(), SNESSetTolerances(), SNESConvergedDefault(), SNESGetConvergedReason(), SNESConvergedReasonViewFromOptions(), 4465 PetscViewerPushFormat(), PetscViewerPopFormat() 4466 4467 @*/ 4468 PetscErrorCode SNESConvergedReasonView(SNES snes,PetscViewer viewer) 4469 { 4470 PetscViewerFormat format; 4471 PetscBool isAscii; 4472 4473 PetscFunctionBegin; 4474 if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)); 4475 CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii)); 4476 if (isAscii) { 4477 CHKERRQ(PetscViewerGetFormat(viewer, &format)); 4478 CHKERRQ(PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel)); 4479 if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 4480 DM dm; 4481 Vec u; 4482 PetscDS prob; 4483 PetscInt Nf, f; 4484 PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 4485 void **exactCtx; 4486 PetscReal error; 4487 4488 CHKERRQ(SNESGetDM(snes, &dm)); 4489 CHKERRQ(SNESGetSolution(snes, &u)); 4490 CHKERRQ(DMGetDS(dm, &prob)); 4491 CHKERRQ(PetscDSGetNumFields(prob, &Nf)); 4492 CHKERRQ(PetscMalloc2(Nf, &exactSol, Nf, &exactCtx)); 4493 for (f = 0; f < Nf; ++f) CHKERRQ(PetscDSGetExactSolution(prob, f, &exactSol[f], &exactCtx[f])); 4494 CHKERRQ(DMComputeL2Diff(dm, 0.0, exactSol, exactCtx, u, &error)); 4495 CHKERRQ(PetscFree2(exactSol, exactCtx)); 4496 if (error < 1.0e-11) CHKERRQ(PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n")); 4497 else CHKERRQ(PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", error)); 4498 } 4499 if (snes->reason > 0 && format != PETSC_VIEWER_FAILED) { 4500 if (((PetscObject) snes)->prefix) { 4501 CHKERRQ(PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve converged due to %s iterations %D\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter)); 4502 } else { 4503 CHKERRQ(PetscViewerASCIIPrintf(viewer,"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter)); 4504 } 4505 } else if (snes->reason <= 0) { 4506 if (((PetscObject) snes)->prefix) { 4507 CHKERRQ(PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve did not converge due to %s iterations %D\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter)); 4508 } else { 4509 CHKERRQ(PetscViewerASCIIPrintf(viewer,"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter)); 4510 } 4511 } 4512 CHKERRQ(PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel)); 4513 } 4514 PetscFunctionReturn(0); 4515 } 4516 4517 /*@C 4518 SNESConvergedReasonViewSet - Sets an ADDITIONAL function that is to be used at the 4519 end of the nonlinear solver to display the conver reason of the nonlinear solver. 4520 4521 Logically Collective on SNES 4522 4523 Input Parameters: 4524 + snes - the SNES context 4525 . f - the snes converged reason view function 4526 . vctx - [optional] user-defined context for private data for the 4527 snes converged reason view routine (use NULL if no context is desired) 4528 - reasonviewdestroy - [optional] routine that frees reasonview context 4529 (may be NULL) 4530 4531 Options Database Keys: 4532 + -snes_converged_reason - sets a default SNESConvergedReasonView() 4533 - -snes_converged_reason_view_cancel - cancels all converged reason viewers that have 4534 been hardwired into a code by 4535 calls to SNESConvergedReasonViewSet(), but 4536 does not cancel those set via 4537 the options database. 4538 4539 Notes: 4540 Several different converged reason view routines may be set by calling 4541 SNESConvergedReasonViewSet() multiple times; all will be called in the 4542 order in which they were set. 4543 4544 Level: intermediate 4545 4546 .seealso: SNESConvergedReasonView(), SNESConvergedReasonViewCancel() 4547 @*/ 4548 PetscErrorCode SNESConvergedReasonViewSet(SNES snes,PetscErrorCode (*f)(SNES,void*),void *vctx,PetscErrorCode (*reasonviewdestroy)(void**)) 4549 { 4550 PetscInt i; 4551 PetscBool identical; 4552 4553 PetscFunctionBegin; 4554 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4555 for (i=0; i<snes->numberreasonviews;i++) { 4556 CHKERRQ(PetscMonitorCompare((PetscErrorCode (*)(void))f,vctx,reasonviewdestroy,(PetscErrorCode (*)(void))snes->reasonview[i],snes->reasonviewcontext[i],snes->reasonviewdestroy[i],&identical)); 4557 if (identical) PetscFunctionReturn(0); 4558 } 4559 PetscCheck(snes->numberreasonviews < MAXSNESREASONVIEWS,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many SNES reasonview set"); 4560 snes->reasonview[snes->numberreasonviews] = f; 4561 snes->reasonviewdestroy[snes->numberreasonviews] = reasonviewdestroy; 4562 snes->reasonviewcontext[snes->numberreasonviews++] = (void*)vctx; 4563 PetscFunctionReturn(0); 4564 } 4565 4566 /*@ 4567 SNESConvergedReasonViewFromOptions - Processes command line options to determine if/how a SNESReason is to be viewed. 4568 All the user-provided convergedReasonView routines will be involved as well, if they exist. 4569 4570 Collective on SNES 4571 4572 Input Parameters: 4573 . snes - the SNES object 4574 4575 Level: intermediate 4576 4577 .seealso: SNESCreate(), SNESSetUp(), SNESDestroy(), SNESSetTolerances(), SNESConvergedDefault(), SNESGetConvergedReason(), SNESConvergedReasonView() 4578 4579 @*/ 4580 PetscErrorCode SNESConvergedReasonViewFromOptions(SNES snes) 4581 { 4582 PetscViewer viewer; 4583 PetscBool flg; 4584 static PetscBool incall = PETSC_FALSE; 4585 PetscViewerFormat format; 4586 PetscInt i; 4587 4588 PetscFunctionBegin; 4589 if (incall) PetscFunctionReturn(0); 4590 incall = PETSC_TRUE; 4591 4592 /* All user-provided viewers are called first, if they exist. */ 4593 for (i=0; i<snes->numberreasonviews; i++) { 4594 CHKERRQ((*snes->reasonview[i])(snes,snes->reasonviewcontext[i])); 4595 } 4596 4597 /* Call PETSc default routine if users ask for it */ 4598 CHKERRQ(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_converged_reason",&viewer,&format,&flg)); 4599 if (flg) { 4600 CHKERRQ(PetscViewerPushFormat(viewer,format)); 4601 CHKERRQ(SNESConvergedReasonView(snes,viewer)); 4602 CHKERRQ(PetscViewerPopFormat(viewer)); 4603 CHKERRQ(PetscViewerDestroy(&viewer)); 4604 } 4605 incall = PETSC_FALSE; 4606 PetscFunctionReturn(0); 4607 } 4608 4609 /*@ 4610 SNESSolve - Solves a nonlinear system F(x) = b. 4611 Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 4612 4613 Collective on SNES 4614 4615 Input Parameters: 4616 + snes - the SNES context 4617 . b - the constant part of the equation F(x) = b, or NULL to use zero. 4618 - x - the solution vector. 4619 4620 Notes: 4621 The user should initialize the vector,x, with the initial guess 4622 for the nonlinear solve prior to calling SNESSolve(). In particular, 4623 to employ an initial guess of zero, the user should explicitly set 4624 this vector to zero by calling VecSet(). 4625 4626 Level: beginner 4627 4628 .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution(), 4629 SNESNewtonTRSetPreCheck(), SNESNewtonTRGetPreCheck(), SNESNewtonTRSetPostCheck(), SNESNewtonTRGetPostCheck(), 4630 SNESLineSearchSetPostCheck(), SNESLineSearchGetPostCheck(), SNESLineSearchSetPreCheck(), SNESLineSearchGetPreCheck() 4631 @*/ 4632 PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 4633 { 4634 PetscBool flg; 4635 PetscInt grid; 4636 Vec xcreated = NULL; 4637 DM dm; 4638 4639 PetscFunctionBegin; 4640 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4641 if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 4642 if (x) PetscCheckSameComm(snes,1,x,3); 4643 if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4644 if (b) PetscCheckSameComm(snes,1,b,2); 4645 4646 /* High level operations using the nonlinear solver */ 4647 { 4648 PetscViewer viewer; 4649 PetscViewerFormat format; 4650 PetscInt num; 4651 PetscBool flg; 4652 static PetscBool incall = PETSC_FALSE; 4653 4654 if (!incall) { 4655 /* Estimate the convergence rate of the discretization */ 4656 CHKERRQ(PetscOptionsGetViewer(PetscObjectComm((PetscObject) snes),((PetscObject)snes)->options, ((PetscObject) snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg)); 4657 if (flg) { 4658 PetscConvEst conv; 4659 DM dm; 4660 PetscReal *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */ 4661 PetscInt Nf; 4662 4663 incall = PETSC_TRUE; 4664 CHKERRQ(SNESGetDM(snes, &dm)); 4665 CHKERRQ(DMGetNumFields(dm, &Nf)); 4666 CHKERRQ(PetscCalloc1(Nf, &alpha)); 4667 CHKERRQ(PetscConvEstCreate(PetscObjectComm((PetscObject) snes), &conv)); 4668 CHKERRQ(PetscConvEstSetSolver(conv, (PetscObject) snes)); 4669 CHKERRQ(PetscConvEstSetFromOptions(conv)); 4670 CHKERRQ(PetscConvEstSetUp(conv)); 4671 CHKERRQ(PetscConvEstGetConvRate(conv, alpha)); 4672 CHKERRQ(PetscViewerPushFormat(viewer, format)); 4673 CHKERRQ(PetscConvEstRateView(conv, alpha, viewer)); 4674 CHKERRQ(PetscViewerPopFormat(viewer)); 4675 CHKERRQ(PetscViewerDestroy(&viewer)); 4676 CHKERRQ(PetscConvEstDestroy(&conv)); 4677 CHKERRQ(PetscFree(alpha)); 4678 incall = PETSC_FALSE; 4679 } 4680 /* Adaptively refine the initial grid */ 4681 num = 1; 4682 CHKERRQ(PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_initial", &num, &flg)); 4683 if (flg) { 4684 DMAdaptor adaptor; 4685 4686 incall = PETSC_TRUE; 4687 CHKERRQ(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor)); 4688 CHKERRQ(DMAdaptorSetSolver(adaptor, snes)); 4689 CHKERRQ(DMAdaptorSetSequenceLength(adaptor, num)); 4690 CHKERRQ(DMAdaptorSetFromOptions(adaptor)); 4691 CHKERRQ(DMAdaptorSetUp(adaptor)); 4692 CHKERRQ(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x)); 4693 CHKERRQ(DMAdaptorDestroy(&adaptor)); 4694 incall = PETSC_FALSE; 4695 } 4696 /* Use grid sequencing to adapt */ 4697 num = 0; 4698 CHKERRQ(PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_sequence", &num, NULL)); 4699 if (num) { 4700 DMAdaptor adaptor; 4701 4702 incall = PETSC_TRUE; 4703 CHKERRQ(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor)); 4704 CHKERRQ(DMAdaptorSetSolver(adaptor, snes)); 4705 CHKERRQ(DMAdaptorSetSequenceLength(adaptor, num)); 4706 CHKERRQ(DMAdaptorSetFromOptions(adaptor)); 4707 CHKERRQ(DMAdaptorSetUp(adaptor)); 4708 CHKERRQ(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x)); 4709 CHKERRQ(DMAdaptorDestroy(&adaptor)); 4710 incall = PETSC_FALSE; 4711 } 4712 } 4713 } 4714 if (!x) { x = snes->vec_sol; } 4715 if (!x) { 4716 CHKERRQ(SNESGetDM(snes,&dm)); 4717 CHKERRQ(DMCreateGlobalVector(dm,&xcreated)); 4718 x = xcreated; 4719 } 4720 CHKERRQ(SNESViewFromOptions(snes,NULL,"-snes_view_pre")); 4721 4722 for (grid=0; grid<snes->gridsequence; grid++) CHKERRQ(PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)))); 4723 for (grid=0; grid<snes->gridsequence+1; grid++) { 4724 4725 /* set solution vector */ 4726 if (!grid) CHKERRQ(PetscObjectReference((PetscObject)x)); 4727 CHKERRQ(VecDestroy(&snes->vec_sol)); 4728 snes->vec_sol = x; 4729 CHKERRQ(SNESGetDM(snes,&dm)); 4730 4731 /* set affine vector if provided */ 4732 if (b) CHKERRQ(PetscObjectReference((PetscObject)b)); 4733 CHKERRQ(VecDestroy(&snes->vec_rhs)); 4734 snes->vec_rhs = b; 4735 4736 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"); 4737 PetscCheck(snes->vec_func != snes->vec_sol,PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 4738 PetscCheck(snes->vec_rhs != snes->vec_sol,PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 4739 if (!snes->vec_sol_update /* && snes->vec_sol */) { 4740 CHKERRQ(VecDuplicate(snes->vec_sol,&snes->vec_sol_update)); 4741 CHKERRQ(PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->vec_sol_update)); 4742 } 4743 CHKERRQ(DMShellSetGlobalVector(dm,snes->vec_sol)); 4744 CHKERRQ(SNESSetUp(snes)); 4745 4746 if (!grid) { 4747 if (snes->ops->computeinitialguess) { 4748 CHKERRQ((*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP)); 4749 } 4750 } 4751 4752 if (snes->conv_hist_reset) snes->conv_hist_len = 0; 4753 if (snes->counters_reset) {snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;} 4754 4755 CHKERRQ(PetscLogEventBegin(SNES_Solve,snes,0,0,0)); 4756 CHKERRQ((*snes->ops->solve)(snes)); 4757 CHKERRQ(PetscLogEventEnd(SNES_Solve,snes,0,0,0)); 4758 PetscCheck(snes->reason,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 4759 snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */ 4760 4761 if (snes->lagjac_persist) snes->jac_iter += snes->iter; 4762 if (snes->lagpre_persist) snes->pre_iter += snes->iter; 4763 4764 CHKERRQ(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_test_local_min",NULL,NULL,&flg)); 4765 if (flg && !PetscPreLoadingOn) CHKERRQ(SNESTestLocalMin(snes)); 4766 /* Call converged reason views. This may involve user-provided viewers as well */ 4767 CHKERRQ(SNESConvergedReasonViewFromOptions(snes)); 4768 4769 if (snes->errorifnotconverged) PetscCheck(snes->reason >= 0,PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 4770 if (snes->reason < 0) break; 4771 if (grid < snes->gridsequence) { 4772 DM fine; 4773 Vec xnew; 4774 Mat interp; 4775 4776 CHKERRQ(DMRefine(snes->dm,PetscObjectComm((PetscObject)snes),&fine)); 4777 PetscCheck(fine,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 4778 CHKERRQ(DMCreateInterpolation(snes->dm,fine,&interp,NULL)); 4779 CHKERRQ(DMCreateGlobalVector(fine,&xnew)); 4780 CHKERRQ(MatInterpolate(interp,x,xnew)); 4781 CHKERRQ(DMInterpolate(snes->dm,interp,fine)); 4782 CHKERRQ(MatDestroy(&interp)); 4783 x = xnew; 4784 4785 CHKERRQ(SNESReset(snes)); 4786 CHKERRQ(SNESSetDM(snes,fine)); 4787 CHKERRQ(SNESResetFromOptions(snes)); 4788 CHKERRQ(DMDestroy(&fine)); 4789 CHKERRQ(PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)))); 4790 } 4791 } 4792 CHKERRQ(SNESViewFromOptions(snes,NULL,"-snes_view")); 4793 CHKERRQ(VecViewFromOptions(snes->vec_sol,(PetscObject)snes,"-snes_view_solution")); 4794 CHKERRQ(DMMonitor(snes->dm)); 4795 CHKERRQ(SNESMonitorPauseFinal_Internal(snes)); 4796 4797 CHKERRQ(VecDestroy(&xcreated)); 4798 CHKERRQ(PetscObjectSAWsBlock((PetscObject)snes)); 4799 PetscFunctionReturn(0); 4800 } 4801 4802 /* --------- Internal routines for SNES Package --------- */ 4803 4804 /*@C 4805 SNESSetType - Sets the method for the nonlinear solver. 4806 4807 Collective on SNES 4808 4809 Input Parameters: 4810 + snes - the SNES context 4811 - type - a known method 4812 4813 Options Database Key: 4814 . -snes_type <type> - Sets the method; use -help for a list 4815 of available methods (for instance, newtonls or newtontr) 4816 4817 Notes: 4818 See "petsc/include/petscsnes.h" for available methods (for instance) 4819 + SNESNEWTONLS - Newton's method with line search 4820 (systems of nonlinear equations) 4821 - SNESNEWTONTR - Newton's method with trust region 4822 (systems of nonlinear equations) 4823 4824 Normally, it is best to use the SNESSetFromOptions() command and then 4825 set the SNES solver type from the options database rather than by using 4826 this routine. Using the options database provides the user with 4827 maximum flexibility in evaluating the many nonlinear solvers. 4828 The SNESSetType() routine is provided for those situations where it 4829 is necessary to set the nonlinear solver independently of the command 4830 line or options database. This might be the case, for example, when 4831 the choice of solver changes during the execution of the program, 4832 and the user's application is taking responsibility for choosing the 4833 appropriate method. 4834 4835 Developer Notes: 4836 SNESRegister() adds a constructor for a new SNESType to SNESList, SNESSetType() locates 4837 the constructor in that list and calls it to create the spexific object. 4838 4839 Level: intermediate 4840 4841 .seealso: SNESType, SNESCreate(), SNESDestroy(), SNESGetType(), SNESSetFromOptions() 4842 4843 @*/ 4844 PetscErrorCode SNESSetType(SNES snes,SNESType type) 4845 { 4846 PetscBool match; 4847 PetscErrorCode (*r)(SNES); 4848 4849 PetscFunctionBegin; 4850 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4851 PetscValidCharPointer(type,2); 4852 4853 CHKERRQ(PetscObjectTypeCompare((PetscObject)snes,type,&match)); 4854 if (match) PetscFunctionReturn(0); 4855 4856 CHKERRQ(PetscFunctionListFind(SNESList,type,&r)); 4857 PetscCheck(r,PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 4858 /* Destroy the previous private SNES context */ 4859 if (snes->ops->destroy) { 4860 CHKERRQ((*(snes)->ops->destroy)(snes)); 4861 snes->ops->destroy = NULL; 4862 } 4863 /* Reinitialize function pointers in SNESOps structure */ 4864 snes->ops->setup = NULL; 4865 snes->ops->solve = NULL; 4866 snes->ops->view = NULL; 4867 snes->ops->setfromoptions = NULL; 4868 snes->ops->destroy = NULL; 4869 4870 /* It may happen the user has customized the line search before calling SNESSetType */ 4871 if (((PetscObject)snes)->type_name) CHKERRQ(SNESLineSearchDestroy(&snes->linesearch)); 4872 4873 /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 4874 snes->setupcalled = PETSC_FALSE; 4875 4876 CHKERRQ(PetscObjectChangeTypeName((PetscObject)snes,type)); 4877 CHKERRQ((*r)(snes)); 4878 PetscFunctionReturn(0); 4879 } 4880 4881 /*@C 4882 SNESGetType - Gets the SNES method type and name (as a string). 4883 4884 Not Collective 4885 4886 Input Parameter: 4887 . snes - nonlinear solver context 4888 4889 Output Parameter: 4890 . type - SNES method (a character string) 4891 4892 Level: intermediate 4893 4894 @*/ 4895 PetscErrorCode SNESGetType(SNES snes,SNESType *type) 4896 { 4897 PetscFunctionBegin; 4898 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4899 PetscValidPointer(type,2); 4900 *type = ((PetscObject)snes)->type_name; 4901 PetscFunctionReturn(0); 4902 } 4903 4904 /*@ 4905 SNESSetSolution - Sets the solution vector for use by the SNES routines. 4906 4907 Logically Collective on SNES 4908 4909 Input Parameters: 4910 + snes - the SNES context obtained from SNESCreate() 4911 - u - the solution vector 4912 4913 Level: beginner 4914 4915 @*/ 4916 PetscErrorCode SNESSetSolution(SNES snes, Vec u) 4917 { 4918 DM dm; 4919 4920 PetscFunctionBegin; 4921 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4922 PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 4923 CHKERRQ(PetscObjectReference((PetscObject) u)); 4924 CHKERRQ(VecDestroy(&snes->vec_sol)); 4925 4926 snes->vec_sol = u; 4927 4928 CHKERRQ(SNESGetDM(snes, &dm)); 4929 CHKERRQ(DMShellSetGlobalVector(dm, u)); 4930 PetscFunctionReturn(0); 4931 } 4932 4933 /*@ 4934 SNESGetSolution - Returns the vector where the approximate solution is 4935 stored. This is the fine grid solution when using SNESSetGridSequence(). 4936 4937 Not Collective, but Vec is parallel if SNES is parallel 4938 4939 Input Parameter: 4940 . snes - the SNES context 4941 4942 Output Parameter: 4943 . x - the solution 4944 4945 Level: intermediate 4946 4947 .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 4948 @*/ 4949 PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 4950 { 4951 PetscFunctionBegin; 4952 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4953 PetscValidPointer(x,2); 4954 *x = snes->vec_sol; 4955 PetscFunctionReturn(0); 4956 } 4957 4958 /*@ 4959 SNESGetSolutionUpdate - Returns the vector where the solution update is 4960 stored. 4961 4962 Not Collective, but Vec is parallel if SNES is parallel 4963 4964 Input Parameter: 4965 . snes - the SNES context 4966 4967 Output Parameter: 4968 . x - the solution update 4969 4970 Level: advanced 4971 4972 .seealso: SNESGetSolution(), SNESGetFunction() 4973 @*/ 4974 PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 4975 { 4976 PetscFunctionBegin; 4977 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4978 PetscValidPointer(x,2); 4979 *x = snes->vec_sol_update; 4980 PetscFunctionReturn(0); 4981 } 4982 4983 /*@C 4984 SNESGetFunction - Returns the vector where the function is stored. 4985 4986 Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 4987 4988 Input Parameter: 4989 . snes - the SNES context 4990 4991 Output Parameters: 4992 + r - the vector that is used to store residuals (or NULL if you don't want it) 4993 . f - the function (or NULL if you don't want it); see SNESFunction for calling sequence details 4994 - ctx - the function context (or NULL if you don't want it) 4995 4996 Level: advanced 4997 4998 Notes: The vector r DOES NOT, in general contain the current value of the SNES nonlinear function 4999 5000 .seealso: SNESSetFunction(), SNESGetSolution(), SNESFunction 5001 @*/ 5002 PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx) 5003 { 5004 DM dm; 5005 5006 PetscFunctionBegin; 5007 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5008 if (r) { 5009 if (!snes->vec_func) { 5010 if (snes->vec_rhs) { 5011 CHKERRQ(VecDuplicate(snes->vec_rhs,&snes->vec_func)); 5012 } else if (snes->vec_sol) { 5013 CHKERRQ(VecDuplicate(snes->vec_sol,&snes->vec_func)); 5014 } else if (snes->dm) { 5015 CHKERRQ(DMCreateGlobalVector(snes->dm,&snes->vec_func)); 5016 } 5017 } 5018 *r = snes->vec_func; 5019 } 5020 CHKERRQ(SNESGetDM(snes,&dm)); 5021 CHKERRQ(DMSNESGetFunction(dm,f,ctx)); 5022 PetscFunctionReturn(0); 5023 } 5024 5025 /*@C 5026 SNESGetNGS - Returns the NGS function and context. 5027 5028 Input Parameter: 5029 . snes - the SNES context 5030 5031 Output Parameters: 5032 + f - the function (or NULL) see SNESNGSFunction for details 5033 - ctx - the function context (or NULL) 5034 5035 Level: advanced 5036 5037 .seealso: SNESSetNGS(), SNESGetFunction() 5038 @*/ 5039 5040 PetscErrorCode SNESGetNGS (SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void*), void ** ctx) 5041 { 5042 DM dm; 5043 5044 PetscFunctionBegin; 5045 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5046 CHKERRQ(SNESGetDM(snes,&dm)); 5047 CHKERRQ(DMSNESGetNGS(dm,f,ctx)); 5048 PetscFunctionReturn(0); 5049 } 5050 5051 /*@C 5052 SNESSetOptionsPrefix - Sets the prefix used for searching for all 5053 SNES options in the database. 5054 5055 Logically Collective on SNES 5056 5057 Input Parameters: 5058 + snes - the SNES context 5059 - prefix - the prefix to prepend to all option names 5060 5061 Notes: 5062 A hyphen (-) must NOT be given at the beginning of the prefix name. 5063 The first character of all runtime options is AUTOMATICALLY the hyphen. 5064 5065 Level: advanced 5066 5067 .seealso: SNESSetFromOptions() 5068 @*/ 5069 PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 5070 { 5071 PetscFunctionBegin; 5072 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5073 CHKERRQ(PetscObjectSetOptionsPrefix((PetscObject)snes,prefix)); 5074 if (!snes->ksp) CHKERRQ(SNESGetKSP(snes,&snes->ksp)); 5075 if (snes->linesearch) { 5076 CHKERRQ(SNESGetLineSearch(snes,&snes->linesearch)); 5077 CHKERRQ(PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix)); 5078 } 5079 CHKERRQ(KSPSetOptionsPrefix(snes->ksp,prefix)); 5080 PetscFunctionReturn(0); 5081 } 5082 5083 /*@C 5084 SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 5085 SNES options in the database. 5086 5087 Logically Collective on SNES 5088 5089 Input Parameters: 5090 + snes - the SNES context 5091 - prefix - the prefix to prepend to all option names 5092 5093 Notes: 5094 A hyphen (-) must NOT be given at the beginning of the prefix name. 5095 The first character of all runtime options is AUTOMATICALLY the hyphen. 5096 5097 Level: advanced 5098 5099 .seealso: SNESGetOptionsPrefix() 5100 @*/ 5101 PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 5102 { 5103 PetscFunctionBegin; 5104 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5105 CHKERRQ(PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix)); 5106 if (!snes->ksp) CHKERRQ(SNESGetKSP(snes,&snes->ksp)); 5107 if (snes->linesearch) { 5108 CHKERRQ(SNESGetLineSearch(snes,&snes->linesearch)); 5109 CHKERRQ(PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix)); 5110 } 5111 CHKERRQ(KSPAppendOptionsPrefix(snes->ksp,prefix)); 5112 PetscFunctionReturn(0); 5113 } 5114 5115 /*@C 5116 SNESGetOptionsPrefix - Sets the prefix used for searching for all 5117 SNES options in the database. 5118 5119 Not Collective 5120 5121 Input Parameter: 5122 . snes - the SNES context 5123 5124 Output Parameter: 5125 . prefix - pointer to the prefix string used 5126 5127 Notes: 5128 On the fortran side, the user should pass in a string 'prefix' of 5129 sufficient length to hold the prefix. 5130 5131 Level: advanced 5132 5133 .seealso: SNESAppendOptionsPrefix() 5134 @*/ 5135 PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 5136 { 5137 PetscFunctionBegin; 5138 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5139 CHKERRQ(PetscObjectGetOptionsPrefix((PetscObject)snes,prefix)); 5140 PetscFunctionReturn(0); 5141 } 5142 5143 /*@C 5144 SNESRegister - Adds a method to the nonlinear solver package. 5145 5146 Not collective 5147 5148 Input Parameters: 5149 + name_solver - name of a new user-defined solver 5150 - routine_create - routine to create method context 5151 5152 Notes: 5153 SNESRegister() may be called multiple times to add several user-defined solvers. 5154 5155 Sample usage: 5156 .vb 5157 SNESRegister("my_solver",MySolverCreate); 5158 .ve 5159 5160 Then, your solver can be chosen with the procedural interface via 5161 $ SNESSetType(snes,"my_solver") 5162 or at runtime via the option 5163 $ -snes_type my_solver 5164 5165 Level: advanced 5166 5167 Note: If your function is not being put into a shared library then use SNESRegister() instead 5168 5169 .seealso: SNESRegisterAll(), SNESRegisterDestroy() 5170 5171 Level: advanced 5172 @*/ 5173 PetscErrorCode SNESRegister(const char sname[],PetscErrorCode (*function)(SNES)) 5174 { 5175 PetscFunctionBegin; 5176 CHKERRQ(SNESInitializePackage()); 5177 CHKERRQ(PetscFunctionListAdd(&SNESList,sname,function)); 5178 PetscFunctionReturn(0); 5179 } 5180 5181 PetscErrorCode SNESTestLocalMin(SNES snes) 5182 { 5183 PetscInt N,i,j; 5184 Vec u,uh,fh; 5185 PetscScalar value; 5186 PetscReal norm; 5187 5188 PetscFunctionBegin; 5189 CHKERRQ(SNESGetSolution(snes,&u)); 5190 CHKERRQ(VecDuplicate(u,&uh)); 5191 CHKERRQ(VecDuplicate(u,&fh)); 5192 5193 /* currently only works for sequential */ 5194 CHKERRQ(PetscPrintf(PetscObjectComm((PetscObject)snes),"Testing FormFunction() for local min\n")); 5195 CHKERRQ(VecGetSize(u,&N)); 5196 for (i=0; i<N; i++) { 5197 CHKERRQ(VecCopy(u,uh)); 5198 CHKERRQ(PetscPrintf(PetscObjectComm((PetscObject)snes),"i = %D\n",i)); 5199 for (j=-10; j<11; j++) { 5200 value = PetscSign(j)*PetscExpReal(PetscAbs(j)-10.0); 5201 CHKERRQ(VecSetValue(uh,i,value,ADD_VALUES)); 5202 CHKERRQ(SNESComputeFunction(snes,uh,fh)); 5203 CHKERRQ(VecNorm(fh,NORM_2,&norm)); 5204 CHKERRQ(PetscPrintf(PetscObjectComm((PetscObject)snes)," j norm %D %18.16e\n",j,norm)); 5205 value = -value; 5206 CHKERRQ(VecSetValue(uh,i,value,ADD_VALUES)); 5207 } 5208 } 5209 CHKERRQ(VecDestroy(&uh)); 5210 CHKERRQ(VecDestroy(&fh)); 5211 PetscFunctionReturn(0); 5212 } 5213 5214 /*@ 5215 SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 5216 computing relative tolerance for linear solvers within an inexact 5217 Newton method. 5218 5219 Logically Collective on SNES 5220 5221 Input Parameters: 5222 + snes - SNES context 5223 - flag - PETSC_TRUE or PETSC_FALSE 5224 5225 Options Database: 5226 + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 5227 . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 5228 . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 5229 . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 5230 . -snes_ksp_ew_gamma <gamma> - Sets gamma 5231 . -snes_ksp_ew_alpha <alpha> - Sets alpha 5232 . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 5233 - -snes_ksp_ew_threshold <threshold> - Sets threshold 5234 5235 Notes: 5236 Currently, the default is to use a constant relative tolerance for 5237 the inner linear solvers. Alternatively, one can use the 5238 Eisenstat-Walker method, where the relative convergence tolerance 5239 is reset at each Newton iteration according progress of the nonlinear 5240 solver. 5241 5242 Level: advanced 5243 5244 Reference: 5245 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 5246 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 5247 5248 .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 5249 @*/ 5250 PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 5251 { 5252 PetscFunctionBegin; 5253 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5254 PetscValidLogicalCollectiveBool(snes,flag,2); 5255 snes->ksp_ewconv = flag; 5256 PetscFunctionReturn(0); 5257 } 5258 5259 /*@ 5260 SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 5261 for computing relative tolerance for linear solvers within an 5262 inexact Newton method. 5263 5264 Not Collective 5265 5266 Input Parameter: 5267 . snes - SNES context 5268 5269 Output Parameter: 5270 . flag - PETSC_TRUE or PETSC_FALSE 5271 5272 Notes: 5273 Currently, the default is to use a constant relative tolerance for 5274 the inner linear solvers. Alternatively, one can use the 5275 Eisenstat-Walker method, where the relative convergence tolerance 5276 is reset at each Newton iteration according progress of the nonlinear 5277 solver. 5278 5279 Level: advanced 5280 5281 Reference: 5282 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 5283 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 5284 5285 .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 5286 @*/ 5287 PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 5288 { 5289 PetscFunctionBegin; 5290 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5291 PetscValidBoolPointer(flag,2); 5292 *flag = snes->ksp_ewconv; 5293 PetscFunctionReturn(0); 5294 } 5295 5296 /*@ 5297 SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 5298 convergence criteria for the linear solvers within an inexact 5299 Newton method. 5300 5301 Logically Collective on SNES 5302 5303 Input Parameters: 5304 + snes - SNES context 5305 . version - version 1, 2 (default is 2) or 3 5306 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 5307 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 5308 . gamma - multiplicative factor for version 2 rtol computation 5309 (0 <= gamma2 <= 1) 5310 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 5311 . alpha2 - power for safeguard 5312 - threshold - threshold for imposing safeguard (0 < threshold < 1) 5313 5314 Note: 5315 Version 3 was contributed by Luis Chacon, June 2006. 5316 5317 Use PETSC_DEFAULT to retain the default for any of the parameters. 5318 5319 Level: advanced 5320 5321 Reference: 5322 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 5323 inexact Newton method", Utah State University Math. Stat. Dept. Res. 5324 Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 5325 5326 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 5327 @*/ 5328 PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 5329 { 5330 SNESKSPEW *kctx; 5331 5332 PetscFunctionBegin; 5333 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5334 kctx = (SNESKSPEW*)snes->kspconvctx; 5335 PetscCheck(kctx,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 5336 PetscValidLogicalCollectiveInt(snes,version,2); 5337 PetscValidLogicalCollectiveReal(snes,rtol_0,3); 5338 PetscValidLogicalCollectiveReal(snes,rtol_max,4); 5339 PetscValidLogicalCollectiveReal(snes,gamma,5); 5340 PetscValidLogicalCollectiveReal(snes,alpha,6); 5341 PetscValidLogicalCollectiveReal(snes,alpha2,7); 5342 PetscValidLogicalCollectiveReal(snes,threshold,8); 5343 5344 if (version != PETSC_DEFAULT) kctx->version = version; 5345 if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 5346 if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 5347 if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 5348 if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 5349 if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 5350 if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 5351 5352 PetscCheck(kctx->version >= 1 && kctx->version <= 3,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 5353 PetscCheckFalse(kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %g",(double)kctx->rtol_0); 5354 PetscCheckFalse(kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%g) < 1.0",(double)kctx->rtol_max); 5355 PetscCheckFalse(kctx->gamma < 0.0 || kctx->gamma > 1.0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%g) <= 1.0",(double)kctx->gamma); 5356 PetscCheckFalse(kctx->alpha <= 1.0 || kctx->alpha > 2.0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%g) <= 2.0",(double)kctx->alpha); 5357 PetscCheckFalse(kctx->threshold <= 0.0 || kctx->threshold >= 1.0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%g) < 1.0",(double)kctx->threshold); 5358 PetscFunctionReturn(0); 5359 } 5360 5361 /*@ 5362 SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 5363 convergence criteria for the linear solvers within an inexact 5364 Newton method. 5365 5366 Not Collective 5367 5368 Input Parameter: 5369 . snes - SNES context 5370 5371 Output Parameters: 5372 + version - version 1, 2 (default is 2) or 3 5373 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 5374 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 5375 . gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1) 5376 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 5377 . alpha2 - power for safeguard 5378 - threshold - threshold for imposing safeguard (0 < threshold < 1) 5379 5380 Level: advanced 5381 5382 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 5383 @*/ 5384 PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 5385 { 5386 SNESKSPEW *kctx; 5387 5388 PetscFunctionBegin; 5389 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5390 kctx = (SNESKSPEW*)snes->kspconvctx; 5391 PetscCheck(kctx,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 5392 if (version) *version = kctx->version; 5393 if (rtol_0) *rtol_0 = kctx->rtol_0; 5394 if (rtol_max) *rtol_max = kctx->rtol_max; 5395 if (gamma) *gamma = kctx->gamma; 5396 if (alpha) *alpha = kctx->alpha; 5397 if (alpha2) *alpha2 = kctx->alpha2; 5398 if (threshold) *threshold = kctx->threshold; 5399 PetscFunctionReturn(0); 5400 } 5401 5402 PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 5403 { 5404 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 5405 PetscReal rtol = PETSC_DEFAULT,stol; 5406 5407 PetscFunctionBegin; 5408 if (!snes->ksp_ewconv) PetscFunctionReturn(0); 5409 if (!snes->iter) { 5410 rtol = kctx->rtol_0; /* first time in, so use the original user rtol */ 5411 CHKERRQ(VecNorm(snes->vec_func,NORM_2,&kctx->norm_first)); 5412 } 5413 else { 5414 if (kctx->version == 1) { 5415 rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 5416 if (rtol < 0.0) rtol = -rtol; 5417 stol = PetscPowReal(kctx->rtol_last,kctx->alpha2); 5418 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 5419 } else if (kctx->version == 2) { 5420 rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 5421 stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha); 5422 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 5423 } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */ 5424 rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 5425 /* safeguard: avoid sharp decrease of rtol */ 5426 stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha); 5427 stol = PetscMax(rtol,stol); 5428 rtol = PetscMin(kctx->rtol_0,stol); 5429 /* safeguard: avoid oversolving */ 5430 stol = kctx->gamma*(kctx->norm_first*snes->rtol)/snes->norm; 5431 stol = PetscMax(rtol,stol); 5432 rtol = PetscMin(kctx->rtol_0,stol); 5433 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 5434 } 5435 /* safeguard: avoid rtol greater than one */ 5436 rtol = PetscMin(rtol,kctx->rtol_max); 5437 CHKERRQ(KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT)); 5438 CHKERRQ(PetscInfo(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%g\n",snes->iter,kctx->version,(double)rtol)); 5439 PetscFunctionReturn(0); 5440 } 5441 5442 PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 5443 { 5444 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 5445 PCSide pcside; 5446 Vec lres; 5447 5448 PetscFunctionBegin; 5449 if (!snes->ksp_ewconv) PetscFunctionReturn(0); 5450 CHKERRQ(KSPGetTolerances(ksp,&kctx->rtol_last,NULL,NULL,NULL)); 5451 kctx->norm_last = snes->norm; 5452 if (kctx->version == 1) { 5453 PC pc; 5454 PetscBool isNone; 5455 5456 CHKERRQ(KSPGetPC(ksp, &pc)); 5457 CHKERRQ(PetscObjectTypeCompare((PetscObject) pc, PCNONE, &isNone)); 5458 CHKERRQ(KSPGetPCSide(ksp,&pcside)); 5459 if (pcside == PC_RIGHT || isNone) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 5460 /* KSP residual is true linear residual */ 5461 CHKERRQ(KSPGetResidualNorm(ksp,&kctx->lresid_last)); 5462 } else { 5463 /* KSP residual is preconditioned residual */ 5464 /* compute true linear residual norm */ 5465 CHKERRQ(VecDuplicate(b,&lres)); 5466 CHKERRQ(MatMult(snes->jacobian,x,lres)); 5467 CHKERRQ(VecAYPX(lres,-1.0,b)); 5468 CHKERRQ(VecNorm(lres,NORM_2,&kctx->lresid_last)); 5469 CHKERRQ(VecDestroy(&lres)); 5470 } 5471 } 5472 PetscFunctionReturn(0); 5473 } 5474 5475 /*@ 5476 SNESGetKSP - Returns the KSP context for a SNES solver. 5477 5478 Not Collective, but if SNES object is parallel, then KSP object is parallel 5479 5480 Input Parameter: 5481 . snes - the SNES context 5482 5483 Output Parameter: 5484 . ksp - the KSP context 5485 5486 Notes: 5487 The user can then directly manipulate the KSP context to set various 5488 options, etc. Likewise, the user can then extract and manipulate the 5489 PC contexts as well. 5490 5491 Level: beginner 5492 5493 .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 5494 @*/ 5495 PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 5496 { 5497 PetscFunctionBegin; 5498 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5499 PetscValidPointer(ksp,2); 5500 5501 if (!snes->ksp) { 5502 CHKERRQ(KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp)); 5503 CHKERRQ(PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1)); 5504 CHKERRQ(PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->ksp)); 5505 5506 CHKERRQ(KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPreSolve_SNESEW,snes)); 5507 CHKERRQ(KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPostSolve_SNESEW,snes)); 5508 5509 CHKERRQ(KSPMonitorSetFromOptions(snes->ksp, "-snes_monitor_ksp", "snes_preconditioned_residual", snes)); 5510 CHKERRQ(PetscObjectSetOptions((PetscObject)snes->ksp,((PetscObject)snes)->options)); 5511 } 5512 *ksp = snes->ksp; 5513 PetscFunctionReturn(0); 5514 } 5515 5516 #include <petsc/private/dmimpl.h> 5517 /*@ 5518 SNESSetDM - Sets the DM that may be used by some nonlinear solvers or their underlying preconditioners 5519 5520 Logically Collective on SNES 5521 5522 Input Parameters: 5523 + snes - the nonlinear solver context 5524 - dm - the dm, cannot be NULL 5525 5526 Notes: 5527 A DM can only be used for solving one problem at a time because information about the problem is stored on the DM, 5528 even when not using interfaces like DMSNESSetFunction(). Use DMClone() to get a distinct DM when solving different 5529 problems using the same function space. 5530 5531 Level: intermediate 5532 5533 .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 5534 @*/ 5535 PetscErrorCode SNESSetDM(SNES snes,DM dm) 5536 { 5537 KSP ksp; 5538 DMSNES sdm; 5539 5540 PetscFunctionBegin; 5541 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5542 PetscValidHeaderSpecific(dm,DM_CLASSID,2); 5543 CHKERRQ(PetscObjectReference((PetscObject)dm)); 5544 if (snes->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */ 5545 if (snes->dm->dmsnes && !dm->dmsnes) { 5546 CHKERRQ(DMCopyDMSNES(snes->dm,dm)); 5547 CHKERRQ(DMGetDMSNES(snes->dm,&sdm)); 5548 if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */ 5549 } 5550 CHKERRQ(DMCoarsenHookRemove(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes)); 5551 CHKERRQ(DMDestroy(&snes->dm)); 5552 } 5553 snes->dm = dm; 5554 snes->dmAuto = PETSC_FALSE; 5555 5556 CHKERRQ(SNESGetKSP(snes,&ksp)); 5557 CHKERRQ(KSPSetDM(ksp,dm)); 5558 CHKERRQ(KSPSetDMActive(ksp,PETSC_FALSE)); 5559 if (snes->npc) { 5560 CHKERRQ(SNESSetDM(snes->npc,snes->dm)); 5561 CHKERRQ(SNESSetNPCSide(snes,snes->npcside)); 5562 } 5563 PetscFunctionReturn(0); 5564 } 5565 5566 /*@ 5567 SNESGetDM - Gets the DM that may be used by some preconditioners 5568 5569 Not Collective but DM obtained is parallel on SNES 5570 5571 Input Parameter: 5572 . snes - the preconditioner context 5573 5574 Output Parameter: 5575 . dm - the dm 5576 5577 Level: intermediate 5578 5579 .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 5580 @*/ 5581 PetscErrorCode SNESGetDM(SNES snes,DM *dm) 5582 { 5583 PetscFunctionBegin; 5584 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5585 if (!snes->dm) { 5586 CHKERRQ(DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm)); 5587 snes->dmAuto = PETSC_TRUE; 5588 } 5589 *dm = snes->dm; 5590 PetscFunctionReturn(0); 5591 } 5592 5593 /*@ 5594 SNESSetNPC - Sets the nonlinear preconditioner to be used. 5595 5596 Collective on SNES 5597 5598 Input Parameters: 5599 + snes - iterative context obtained from SNESCreate() 5600 - pc - the preconditioner object 5601 5602 Notes: 5603 Use SNESGetNPC() to retrieve the preconditioner context (for example, 5604 to configure it using the API). 5605 5606 Level: developer 5607 5608 .seealso: SNESGetNPC(), SNESHasNPC() 5609 @*/ 5610 PetscErrorCode SNESSetNPC(SNES snes, SNES pc) 5611 { 5612 PetscFunctionBegin; 5613 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5614 PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 5615 PetscCheckSameComm(snes, 1, pc, 2); 5616 CHKERRQ(PetscObjectReference((PetscObject) pc)); 5617 CHKERRQ(SNESDestroy(&snes->npc)); 5618 snes->npc = pc; 5619 CHKERRQ(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->npc)); 5620 PetscFunctionReturn(0); 5621 } 5622 5623 /*@ 5624 SNESGetNPC - Creates a nonlinear preconditioning solver (SNES) to be used to precondition the nonlinear solver. 5625 5626 Not Collective; but any changes to the obtained SNES object must be applied collectively 5627 5628 Input Parameter: 5629 . snes - iterative context obtained from SNESCreate() 5630 5631 Output Parameter: 5632 . pc - preconditioner context 5633 5634 Options Database: 5635 . -npc_snes_type <type> - set the type of the SNES to use as the nonlinear preconditioner 5636 5637 Notes: 5638 If a SNES was previously set with SNESSetNPC() then that SNES is returned, otherwise a new SNES object is created. 5639 5640 The (preconditioner) SNES returned automatically inherits the same nonlinear function and Jacobian supplied to the original 5641 SNES during SNESSetUp() 5642 5643 Level: developer 5644 5645 .seealso: SNESSetNPC(), SNESHasNPC(), SNES, SNESCreate() 5646 @*/ 5647 PetscErrorCode SNESGetNPC(SNES snes, SNES *pc) 5648 { 5649 const char *optionsprefix; 5650 5651 PetscFunctionBegin; 5652 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5653 PetscValidPointer(pc, 2); 5654 if (!snes->npc) { 5655 CHKERRQ(SNESCreate(PetscObjectComm((PetscObject)snes),&snes->npc)); 5656 CHKERRQ(PetscObjectIncrementTabLevel((PetscObject)snes->npc,(PetscObject)snes,1)); 5657 CHKERRQ(PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->npc)); 5658 CHKERRQ(SNESGetOptionsPrefix(snes,&optionsprefix)); 5659 CHKERRQ(SNESSetOptionsPrefix(snes->npc,optionsprefix)); 5660 CHKERRQ(SNESAppendOptionsPrefix(snes->npc,"npc_")); 5661 CHKERRQ(SNESSetCountersReset(snes->npc,PETSC_FALSE)); 5662 } 5663 *pc = snes->npc; 5664 PetscFunctionReturn(0); 5665 } 5666 5667 /*@ 5668 SNESHasNPC - Returns whether a nonlinear preconditioner exists 5669 5670 Not Collective 5671 5672 Input Parameter: 5673 . snes - iterative context obtained from SNESCreate() 5674 5675 Output Parameter: 5676 . has_npc - whether the SNES has an NPC or not 5677 5678 Level: developer 5679 5680 .seealso: SNESSetNPC(), SNESGetNPC() 5681 @*/ 5682 PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc) 5683 { 5684 PetscFunctionBegin; 5685 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5686 *has_npc = (PetscBool) (snes->npc ? PETSC_TRUE : PETSC_FALSE); 5687 PetscFunctionReturn(0); 5688 } 5689 5690 /*@ 5691 SNESSetNPCSide - Sets the preconditioning side. 5692 5693 Logically Collective on SNES 5694 5695 Input Parameter: 5696 . snes - iterative context obtained from SNESCreate() 5697 5698 Output Parameter: 5699 . side - the preconditioning side, where side is one of 5700 .vb 5701 PC_LEFT - left preconditioning 5702 PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5703 .ve 5704 5705 Options Database Keys: 5706 . -snes_npc_side <right,left> - nonlinear preconditioner side 5707 5708 Notes: 5709 SNESNRICHARDSON and SNESNCG only support left preconditioning. 5710 5711 Level: intermediate 5712 5713 .seealso: SNESGetNPCSide(), KSPSetPCSide() 5714 @*/ 5715 PetscErrorCode SNESSetNPCSide(SNES snes,PCSide side) 5716 { 5717 PetscFunctionBegin; 5718 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5719 PetscValidLogicalCollectiveEnum(snes,side,2); 5720 if (side == PC_SIDE_DEFAULT) side = PC_RIGHT; 5721 PetscCheck((side == PC_LEFT) || (side == PC_RIGHT),PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONG,"Only PC_LEFT and PC_RIGHT are supported"); 5722 snes->npcside = side; 5723 PetscFunctionReturn(0); 5724 } 5725 5726 /*@ 5727 SNESGetNPCSide - Gets the preconditioning side. 5728 5729 Not Collective 5730 5731 Input Parameter: 5732 . snes - iterative context obtained from SNESCreate() 5733 5734 Output Parameter: 5735 . side - the preconditioning side, where side is one of 5736 .vb 5737 PC_LEFT - left preconditioning 5738 PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5739 .ve 5740 5741 Level: intermediate 5742 5743 .seealso: SNESSetNPCSide(), KSPGetPCSide() 5744 @*/ 5745 PetscErrorCode SNESGetNPCSide(SNES snes,PCSide *side) 5746 { 5747 PetscFunctionBegin; 5748 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5749 PetscValidPointer(side,2); 5750 *side = snes->npcside; 5751 PetscFunctionReturn(0); 5752 } 5753 5754 /*@ 5755 SNESSetLineSearch - Sets the linesearch on the SNES instance. 5756 5757 Collective on SNES 5758 5759 Input Parameters: 5760 + snes - iterative context obtained from SNESCreate() 5761 - linesearch - the linesearch object 5762 5763 Notes: 5764 Use SNESGetLineSearch() to retrieve the preconditioner context (for example, 5765 to configure it using the API). 5766 5767 Level: developer 5768 5769 .seealso: SNESGetLineSearch() 5770 @*/ 5771 PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch) 5772 { 5773 PetscFunctionBegin; 5774 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5775 PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 5776 PetscCheckSameComm(snes, 1, linesearch, 2); 5777 CHKERRQ(PetscObjectReference((PetscObject) linesearch)); 5778 CHKERRQ(SNESLineSearchDestroy(&snes->linesearch)); 5779 5780 snes->linesearch = linesearch; 5781 5782 CHKERRQ(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch)); 5783 PetscFunctionReturn(0); 5784 } 5785 5786 /*@ 5787 SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch() 5788 or creates a default line search instance associated with the SNES and returns it. 5789 5790 Not Collective 5791 5792 Input Parameter: 5793 . snes - iterative context obtained from SNESCreate() 5794 5795 Output Parameter: 5796 . linesearch - linesearch context 5797 5798 Level: beginner 5799 5800 .seealso: SNESSetLineSearch(), SNESLineSearchCreate() 5801 @*/ 5802 PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch) 5803 { 5804 const char *optionsprefix; 5805 5806 PetscFunctionBegin; 5807 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5808 PetscValidPointer(linesearch, 2); 5809 if (!snes->linesearch) { 5810 CHKERRQ(SNESGetOptionsPrefix(snes, &optionsprefix)); 5811 CHKERRQ(SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch)); 5812 CHKERRQ(SNESLineSearchSetSNES(snes->linesearch, snes)); 5813 CHKERRQ(SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix)); 5814 CHKERRQ(PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1)); 5815 CHKERRQ(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch)); 5816 } 5817 *linesearch = snes->linesearch; 5818 PetscFunctionReturn(0); 5819 } 5820