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