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