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