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 PetscValidPointer(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 PetscValidPointer(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 PetscValidPointer(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 PetscValidPointer(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 PetscInt m,n,M,N; 2403 void *functx; 2404 PetscBool complete_print = PETSC_FALSE,threshold_print = PETSC_FALSE,test = PETSC_FALSE,flg; 2405 PetscViewer viewer,mviewer; 2406 MPI_Comm comm; 2407 PetscInt tabs; 2408 static PetscBool directionsprinted = PETSC_FALSE; 2409 PetscViewerFormat format; 2410 2411 PetscFunctionBegin; 2412 ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 2413 ierr = PetscOptionsName("-snes_test_jacobian","Compare hand-coded and finite difference Jacobians","None",&test);CHKERRQ(ierr); 2414 ierr = PetscOptionsReal("-snes_test_jacobian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold,NULL);CHKERRQ(ierr); 2415 ierr = PetscOptionsViewer("-snes_test_jacobian_view","View difference between hand-coded and finite difference Jacobians element entries","None",&mviewer,&format,&complete_print);CHKERRQ(ierr); 2416 if (!complete_print) { 2417 ierr = PetscOptionsViewer("-snes_test_jacobian_display","Display difference between hand-coded and finite difference Jacobians","None",&mviewer,&format,&complete_print);CHKERRQ(ierr); 2418 } 2419 /* for compatibility with PETSc 3.9 and older. */ 2420 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); 2421 ierr = PetscOptionsEnd();CHKERRQ(ierr); 2422 if (!test) PetscFunctionReturn(0); 2423 2424 ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2425 ierr = PetscViewerASCIIGetStdout(comm,&viewer);CHKERRQ(ierr); 2426 ierr = PetscViewerASCIIGetTab(viewer, &tabs);CHKERRQ(ierr); 2427 ierr = PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel);CHKERRQ(ierr); 2428 ierr = PetscViewerASCIIPrintf(viewer," ---------- Testing Jacobian -------------\n");CHKERRQ(ierr); 2429 if (!complete_print && !directionsprinted) { 2430 ierr = PetscViewerASCIIPrintf(viewer," Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference\n");CHKERRQ(ierr); 2431 ierr = PetscViewerASCIIPrintf(viewer," of hand-coded and finite difference Jacobian entries greater than <threshold>.\n");CHKERRQ(ierr); 2432 } 2433 if (!directionsprinted) { 2434 ierr = PetscViewerASCIIPrintf(viewer," Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n");CHKERRQ(ierr); 2435 ierr = PetscViewerASCIIPrintf(viewer," O(1.e-8), the hand-coded Jacobian is probably correct.\n");CHKERRQ(ierr); 2436 directionsprinted = PETSC_TRUE; 2437 } 2438 if (complete_print) { 2439 ierr = PetscViewerPushFormat(mviewer,format);CHKERRQ(ierr); 2440 } 2441 2442 ierr = PetscObjectTypeCompare((PetscObject)snes->jacobian,MATMFFD,&flg);CHKERRQ(ierr); 2443 if (!flg) jacobian = snes->jacobian; 2444 else jacobian = snes->jacobian_pre; 2445 2446 if (!x) { 2447 ierr = MatCreateVecs(jacobian, &x, NULL);CHKERRQ(ierr); 2448 } else { 2449 ierr = PetscObjectReference((PetscObject) x);CHKERRQ(ierr); 2450 } 2451 if (!f) { 2452 ierr = VecDuplicate(x, &f);CHKERRQ(ierr); 2453 } else { 2454 ierr = PetscObjectReference((PetscObject) f);CHKERRQ(ierr); 2455 } 2456 /* evaluate the function at this point because SNESComputeJacobianDefault() assumes that the function has been evaluated and put into snes->vec_func */ 2457 ierr = SNESComputeFunction(snes,x,f);CHKERRQ(ierr); 2458 ierr = VecDestroy(&f);CHKERRQ(ierr); 2459 2460 while (jacobian) { 2461 ierr = PetscObjectBaseTypeCompareAny((PetscObject)jacobian,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 2462 if (flg) { 2463 A = jacobian; 2464 ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 2465 } else { 2466 ierr = MatComputeOperator(jacobian,MATAIJ,&A);CHKERRQ(ierr); 2467 } 2468 2469 ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr); 2470 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 2471 ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 2472 ierr = MatSetSizes(B,m,n,M,N);CHKERRQ(ierr); 2473 ierr = MatSetType(B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2474 ierr = MatSetUp(B);CHKERRQ(ierr); 2475 ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 2476 2477 ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr); 2478 ierr = SNESComputeJacobianDefault(snes,x,B,B,functx);CHKERRQ(ierr); 2479 2480 ierr = MatDuplicate(B,MAT_COPY_VALUES,&D);CHKERRQ(ierr); 2481 ierr = MatAYPX(D,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 2482 ierr = MatNorm(D,NORM_FROBENIUS,&nrm);CHKERRQ(ierr); 2483 ierr = MatNorm(A,NORM_FROBENIUS,&gnorm);CHKERRQ(ierr); 2484 ierr = MatDestroy(&D);CHKERRQ(ierr); 2485 if (!gnorm) gnorm = 1; /* just in case */ 2486 ierr = PetscViewerASCIIPrintf(viewer," ||J - Jfd||_F/||J||_F = %g, ||J - Jfd||_F = %g\n",(double)(nrm/gnorm),(double)nrm);CHKERRQ(ierr); 2487 2488 if (complete_print) { 2489 ierr = PetscViewerASCIIPrintf(viewer," Hand-coded Jacobian ----------\n");CHKERRQ(ierr); 2490 ierr = MatView(jacobian,mviewer);CHKERRQ(ierr); 2491 ierr = PetscViewerASCIIPrintf(viewer," Finite difference Jacobian ----------\n");CHKERRQ(ierr); 2492 ierr = MatView(B,mviewer);CHKERRQ(ierr); 2493 } 2494 2495 if (threshold_print || complete_print) { 2496 PetscInt Istart, Iend, *ccols, bncols, cncols, j, row; 2497 PetscScalar *cvals; 2498 const PetscInt *bcols; 2499 const PetscScalar *bvals; 2500 2501 ierr = MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 2502 ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2503 ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr); 2504 ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2505 ierr = MatSetUp(C);CHKERRQ(ierr); 2506 ierr = MatSetOption(C,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 2507 ierr = MatGetOwnershipRange(B,&Istart,&Iend);CHKERRQ(ierr); 2508 2509 for (row = Istart; row < Iend; row++) { 2510 ierr = MatGetRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr); 2511 ierr = PetscMalloc2(bncols,&ccols,bncols,&cvals);CHKERRQ(ierr); 2512 for (j = 0, cncols = 0; j < bncols; j++) { 2513 if (PetscAbsScalar(bvals[j]) > threshold) { 2514 ccols[cncols] = bcols[j]; 2515 cvals[cncols] = bvals[j]; 2516 cncols += 1; 2517 } 2518 } 2519 if (cncols) { 2520 ierr = MatSetValues(C,1,&row,cncols,ccols,cvals,INSERT_VALUES);CHKERRQ(ierr); 2521 } 2522 ierr = MatRestoreRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr); 2523 ierr = PetscFree2(ccols,cvals);CHKERRQ(ierr); 2524 } 2525 ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2526 ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2527 ierr = PetscViewerASCIIPrintf(viewer," Hand-coded minus finite-difference Jacobian with tolerance %g ----------\n",(double)threshold);CHKERRQ(ierr); 2528 ierr = MatView(C,complete_print ? mviewer : viewer);CHKERRQ(ierr); 2529 ierr = MatDestroy(&C);CHKERRQ(ierr); 2530 } 2531 ierr = MatDestroy(&A);CHKERRQ(ierr); 2532 ierr = MatDestroy(&B);CHKERRQ(ierr); 2533 2534 if (jacobian != snes->jacobian_pre) { 2535 jacobian = snes->jacobian_pre; 2536 ierr = PetscViewerASCIIPrintf(viewer," ---------- Testing Jacobian for preconditioner -------------\n");CHKERRQ(ierr); 2537 } 2538 else jacobian = NULL; 2539 } 2540 ierr = VecDestroy(&x);CHKERRQ(ierr); 2541 if (complete_print) { 2542 ierr = PetscViewerPopFormat(mviewer);CHKERRQ(ierr); 2543 } 2544 if (mviewer) { ierr = PetscViewerDestroy(&mviewer);CHKERRQ(ierr); } 2545 ierr = PetscViewerASCIISetTab(viewer,tabs);CHKERRQ(ierr); 2546 PetscFunctionReturn(0); 2547 } 2548 2549 /*@ 2550 SNESComputeJacobian - Computes the Jacobian matrix that has been set with SNESSetJacobian(). 2551 2552 Collective on SNES 2553 2554 Input Parameters: 2555 + snes - the SNES context 2556 - x - input vector 2557 2558 Output Parameters: 2559 + A - Jacobian matrix 2560 - B - optional preconditioning matrix 2561 2562 Options Database Keys: 2563 + -snes_lag_preconditioner <lag> 2564 . -snes_lag_jacobian <lag> 2565 . -snes_test_jacobian - compare the user provided Jacobian with one compute via finite differences to check for errors 2566 . -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 2567 . -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 2568 . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 2569 . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 2570 . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 2571 . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 2572 . -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference 2573 . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 2574 . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 2575 . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2576 . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2577 . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 2578 - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 2579 2580 2581 Notes: 2582 Most users should not need to explicitly call this routine, as it 2583 is used internally within the nonlinear solvers. 2584 2585 Developer Notes: 2586 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 2587 for with the SNESType of test that has been removed. 2588 2589 Level: developer 2590 2591 .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 2592 @*/ 2593 PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat A,Mat B) 2594 { 2595 PetscErrorCode ierr; 2596 PetscBool flag; 2597 DM dm; 2598 DMSNES sdm; 2599 KSP ksp; 2600 2601 PetscFunctionBegin; 2602 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2603 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 2604 PetscCheckSameComm(snes,1,X,2); 2605 ierr = VecValidValues(X,2,PETSC_TRUE);CHKERRQ(ierr); 2606 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2607 ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 2608 2609 if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 2610 2611 /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 2612 2613 if (snes->lagjacobian == -2) { 2614 snes->lagjacobian = -1; 2615 2616 ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 2617 } else if (snes->lagjacobian == -1) { 2618 ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 2619 ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr); 2620 if (flag) { 2621 ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2622 ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2623 } 2624 PetscFunctionReturn(0); 2625 } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) { 2626 ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 2627 ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr); 2628 if (flag) { 2629 ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2630 ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2631 } 2632 PetscFunctionReturn(0); 2633 } 2634 if (snes->npc && snes->npcside== PC_LEFT) { 2635 ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2636 ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2637 PetscFunctionReturn(0); 2638 } 2639 2640 ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr); 2641 ierr = VecLockReadPush(X);CHKERRQ(ierr); 2642 PetscStackPush("SNES user Jacobian function"); 2643 ierr = (*sdm->ops->computejacobian)(snes,X,A,B,sdm->jacobianctx);CHKERRQ(ierr); 2644 PetscStackPop; 2645 ierr = VecLockReadPop(X);CHKERRQ(ierr); 2646 ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr); 2647 2648 /* the next line ensures that snes->ksp exists */ 2649 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 2650 if (snes->lagpreconditioner == -2) { 2651 ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 2652 ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr); 2653 snes->lagpreconditioner = -1; 2654 } else if (snes->lagpreconditioner == -1) { 2655 ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 2656 ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr); 2657 } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) { 2658 ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 2659 ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr); 2660 } else { 2661 ierr = PetscInfo(snes,"Rebuilding preconditioner\n");CHKERRQ(ierr); 2662 ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr); 2663 } 2664 2665 ierr = SNESTestJacobian(snes);CHKERRQ(ierr); 2666 /* make sure user returned a correct Jacobian and preconditioner */ 2667 /* PetscValidHeaderSpecific(A,MAT_CLASSID,3); 2668 PetscValidHeaderSpecific(B,MAT_CLASSID,4); */ 2669 { 2670 PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 2671 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit",NULL,NULL,&flag);CHKERRQ(ierr); 2672 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr); 2673 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr); 2674 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_operator",NULL,NULL,&flag_operator);CHKERRQ(ierr); 2675 if (flag || flag_draw || flag_contour) { 2676 Mat Bexp_mine = NULL,Bexp,FDexp; 2677 PetscViewer vdraw,vstdout; 2678 PetscBool flg; 2679 if (flag_operator) { 2680 ierr = MatComputeOperator(A,MATAIJ,&Bexp_mine);CHKERRQ(ierr); 2681 Bexp = Bexp_mine; 2682 } else { 2683 /* See if the preconditioning matrix can be viewed and added directly */ 2684 ierr = PetscObjectBaseTypeCompareAny((PetscObject)B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 2685 if (flg) Bexp = B; 2686 else { 2687 /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 2688 ierr = MatComputeOperator(B,MATAIJ,&Bexp_mine);CHKERRQ(ierr); 2689 Bexp = Bexp_mine; 2690 } 2691 } 2692 ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 2693 ierr = SNESComputeJacobianDefault(snes,X,FDexp,FDexp,NULL);CHKERRQ(ierr); 2694 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr); 2695 if (flag_draw || flag_contour) { 2696 ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 2697 if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 2698 } else vdraw = NULL; 2699 ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator ? "Jacobian" : "preconditioning Jacobian");CHKERRQ(ierr); 2700 if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 2701 if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 2702 ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 2703 if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2704 if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 2705 ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2706 ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 2707 if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2708 if (vdraw) { /* Always use contour for the difference */ 2709 ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 2710 ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 2711 ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 2712 } 2713 if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 2714 ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 2715 ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 2716 ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 2717 } 2718 } 2719 { 2720 PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 2721 PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 2722 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring",NULL,NULL,&flag);CHKERRQ(ierr); 2723 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_display",NULL,NULL,&flag_display);CHKERRQ(ierr); 2724 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr); 2725 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr); 2726 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",NULL,NULL,&flag_threshold);CHKERRQ(ierr); 2727 if (flag_threshold) { 2728 ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,NULL);CHKERRQ(ierr); 2729 ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,NULL);CHKERRQ(ierr); 2730 } 2731 if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 2732 Mat Bfd; 2733 PetscViewer vdraw,vstdout; 2734 MatColoring coloring; 2735 ISColoring iscoloring; 2736 MatFDColoring matfdcoloring; 2737 PetscErrorCode (*func)(SNES,Vec,Vec,void*); 2738 void *funcctx; 2739 PetscReal norm1,norm2,normmax; 2740 2741 ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 2742 ierr = MatColoringCreate(Bfd,&coloring);CHKERRQ(ierr); 2743 ierr = MatColoringSetType(coloring,MATCOLORINGSL);CHKERRQ(ierr); 2744 ierr = MatColoringSetFromOptions(coloring);CHKERRQ(ierr); 2745 ierr = MatColoringApply(coloring,&iscoloring);CHKERRQ(ierr); 2746 ierr = MatColoringDestroy(&coloring);CHKERRQ(ierr); 2747 ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 2748 ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 2749 ierr = MatFDColoringSetUp(Bfd,iscoloring,matfdcoloring);CHKERRQ(ierr); 2750 ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 2751 2752 /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 2753 ierr = SNESGetFunction(snes,NULL,&func,&funcctx);CHKERRQ(ierr); 2754 ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr); 2755 ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 2756 ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 2757 ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 2758 ierr = MatFDColoringApply(Bfd,matfdcoloring,X,snes);CHKERRQ(ierr); 2759 ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 2760 2761 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr); 2762 if (flag_draw || flag_contour) { 2763 ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 2764 if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 2765 } else vdraw = NULL; 2766 ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 2767 if (flag_display) {ierr = MatView(B,vstdout);CHKERRQ(ierr);} 2768 if (vdraw) {ierr = MatView(B,vdraw);CHKERRQ(ierr);} 2769 ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 2770 if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 2771 if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 2772 ierr = MatAYPX(Bfd,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2773 ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 2774 ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 2775 ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 2776 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); 2777 if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 2778 if (vdraw) { /* Always use contour for the difference */ 2779 ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 2780 ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 2781 ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 2782 } 2783 if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 2784 2785 if (flag_threshold) { 2786 PetscInt bs,rstart,rend,i; 2787 ierr = MatGetBlockSize(B,&bs);CHKERRQ(ierr); 2788 ierr = MatGetOwnershipRange(B,&rstart,&rend);CHKERRQ(ierr); 2789 for (i=rstart; i<rend; i++) { 2790 const PetscScalar *ba,*ca; 2791 const PetscInt *bj,*cj; 2792 PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 2793 PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 2794 ierr = MatGetRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr); 2795 ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 2796 if (bn != cn) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 2797 for (j=0; j<bn; j++) { 2798 PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 2799 if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 2800 maxentrycol = bj[j]; 2801 maxentry = PetscRealPart(ba[j]); 2802 } 2803 if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 2804 maxdiffcol = bj[j]; 2805 maxdiff = PetscRealPart(ca[j]); 2806 } 2807 if (rdiff > maxrdiff) { 2808 maxrdiffcol = bj[j]; 2809 maxrdiff = rdiff; 2810 } 2811 } 2812 if (maxrdiff > 1) { 2813 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); 2814 for (j=0; j<bn; j++) { 2815 PetscReal rdiff; 2816 rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 2817 if (rdiff > 1) { 2818 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%g:%g)",bj[j],(double)PetscRealPart(ba[j]),(double)PetscRealPart(ca[j]));CHKERRQ(ierr); 2819 } 2820 } 2821 ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 2822 } 2823 ierr = MatRestoreRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr); 2824 ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 2825 } 2826 } 2827 ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 2828 ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 2829 } 2830 } 2831 PetscFunctionReturn(0); 2832 } 2833 2834 /*MC 2835 SNESJacobianFunction - Function used to convey the nonlinear Jacobian of the function to be solved by SNES 2836 2837 Synopsis: 2838 #include "petscsnes.h" 2839 PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx); 2840 2841 + x - input vector 2842 . Amat - the matrix that defines the (approximate) Jacobian 2843 . Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 2844 - ctx - [optional] user-defined Jacobian context 2845 2846 Level: intermediate 2847 2848 .seealso: SNESSetFunction(), SNESGetFunction(), SNESSetJacobian(), SNESGetJacobian() 2849 M*/ 2850 2851 /*@C 2852 SNESSetJacobian - Sets the function to compute Jacobian as well as the 2853 location to store the matrix. 2854 2855 Logically Collective on SNES 2856 2857 Input Parameters: 2858 + snes - the SNES context 2859 . Amat - the matrix that defines the (approximate) Jacobian 2860 . Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 2861 . J - Jacobian evaluation routine (if NULL then SNES retains any previously set value), see SNESJacobianFunction for details 2862 - ctx - [optional] user-defined context for private data for the 2863 Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value) 2864 2865 Notes: 2866 If the Amat matrix and Pmat matrix are different you must call MatAssemblyBegin/End() on 2867 each matrix. 2868 2869 If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null 2870 space to Amat and the KSP solvers will automatically use that null space as needed during the solution process. 2871 2872 If using SNESComputeJacobianDefaultColor() to assemble a Jacobian, the ctx argument 2873 must be a MatFDColoring. 2874 2875 Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2876 example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2877 2878 Level: beginner 2879 2880 .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESComputeJacobianDefaultColor(), MatStructure, J, 2881 SNESSetPicard(), SNESJacobianFunction 2882 @*/ 2883 PetscErrorCode SNESSetJacobian(SNES snes,Mat Amat,Mat Pmat,PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx) 2884 { 2885 PetscErrorCode ierr; 2886 DM dm; 2887 2888 PetscFunctionBegin; 2889 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2890 if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 2891 if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 2892 if (Amat) PetscCheckSameComm(snes,1,Amat,2); 2893 if (Pmat) PetscCheckSameComm(snes,1,Pmat,3); 2894 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2895 ierr = DMSNESSetJacobian(dm,J,ctx);CHKERRQ(ierr); 2896 if (Amat) { 2897 ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr); 2898 ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 2899 2900 snes->jacobian = Amat; 2901 } 2902 if (Pmat) { 2903 ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr); 2904 ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2905 2906 snes->jacobian_pre = Pmat; 2907 } 2908 PetscFunctionReturn(0); 2909 } 2910 2911 /*@C 2912 SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2913 provided context for evaluating the Jacobian. 2914 2915 Not Collective, but Mat object will be parallel if SNES object is 2916 2917 Input Parameter: 2918 . snes - the nonlinear solver context 2919 2920 Output Parameters: 2921 + Amat - location to stash (approximate) Jacobian matrix (or NULL) 2922 . Pmat - location to stash matrix used to compute the preconditioner (or NULL) 2923 . J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence 2924 - ctx - location to stash Jacobian ctx (or NULL) 2925 2926 Level: advanced 2927 2928 .seealso: SNESSetJacobian(), SNESComputeJacobian(), SNESJacobianFunction, SNESGetFunction() 2929 @*/ 2930 PetscErrorCode SNESGetJacobian(SNES snes,Mat *Amat,Mat *Pmat,PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx) 2931 { 2932 PetscErrorCode ierr; 2933 DM dm; 2934 DMSNES sdm; 2935 2936 PetscFunctionBegin; 2937 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2938 if (Amat) *Amat = snes->jacobian; 2939 if (Pmat) *Pmat = snes->jacobian_pre; 2940 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2941 ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 2942 if (J) *J = sdm->ops->computejacobian; 2943 if (ctx) *ctx = sdm->jacobianctx; 2944 PetscFunctionReturn(0); 2945 } 2946 2947 /*@ 2948 SNESSetUp - Sets up the internal data structures for the later use 2949 of a nonlinear solver. 2950 2951 Collective on SNES 2952 2953 Input Parameters: 2954 . snes - the SNES context 2955 2956 Notes: 2957 For basic use of the SNES solvers the user need not explicitly call 2958 SNESSetUp(), since these actions will automatically occur during 2959 the call to SNESSolve(). However, if one wishes to control this 2960 phase separately, SNESSetUp() should be called after SNESCreate() 2961 and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2962 2963 Level: advanced 2964 2965 .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 2966 @*/ 2967 PetscErrorCode SNESSetUp(SNES snes) 2968 { 2969 PetscErrorCode ierr; 2970 DM dm; 2971 DMSNES sdm; 2972 SNESLineSearch linesearch, pclinesearch; 2973 void *lsprectx,*lspostctx; 2974 PetscErrorCode (*precheck)(SNESLineSearch,Vec,Vec,PetscBool*,void*); 2975 PetscErrorCode (*postcheck)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*); 2976 PetscErrorCode (*func)(SNES,Vec,Vec,void*); 2977 Vec f,fpc; 2978 void *funcctx; 2979 PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*); 2980 void *jacctx,*appctx; 2981 Mat j,jpre; 2982 2983 PetscFunctionBegin; 2984 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2985 if (snes->setupcalled) PetscFunctionReturn(0); 2986 ierr = PetscLogEventBegin(SNES_Setup,snes,0,0,0);CHKERRQ(ierr); 2987 2988 if (!((PetscObject)snes)->type_name) { 2989 ierr = SNESSetType(snes,SNESNEWTONLS);CHKERRQ(ierr); 2990 } 2991 2992 ierr = SNESGetFunction(snes,&snes->vec_func,NULL,NULL);CHKERRQ(ierr); 2993 2994 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 2995 ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr); 2996 if (!sdm->ops->computefunction) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Function never provided to SNES object"); 2997 if (!sdm->ops->computejacobian) { 2998 ierr = DMSNESSetJacobian(dm,SNESComputeJacobianDefaultColor,NULL);CHKERRQ(ierr); 2999 } 3000 if (!snes->vec_func) { 3001 ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 3002 } 3003 3004 if (!snes->ksp) { 3005 ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr); 3006 } 3007 3008 if (snes->linesearch) { 3009 ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 3010 ierr = SNESLineSearchSetFunction(snes->linesearch,SNESComputeFunction);CHKERRQ(ierr); 3011 } 3012 3013 if (snes->npc && (snes->npcside== PC_LEFT)) { 3014 snes->mf = PETSC_TRUE; 3015 snes->mf_operator = PETSC_FALSE; 3016 } 3017 3018 if (snes->npc) { 3019 /* copy the DM over */ 3020 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3021 ierr = SNESSetDM(snes->npc,dm);CHKERRQ(ierr); 3022 3023 ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr); 3024 ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr); 3025 ierr = SNESSetFunction(snes->npc,fpc,func,funcctx);CHKERRQ(ierr); 3026 ierr = SNESGetJacobian(snes,&j,&jpre,&jac,&jacctx);CHKERRQ(ierr); 3027 ierr = SNESSetJacobian(snes->npc,j,jpre,jac,jacctx);CHKERRQ(ierr); 3028 ierr = SNESGetApplicationContext(snes,&appctx);CHKERRQ(ierr); 3029 ierr = SNESSetApplicationContext(snes->npc,appctx);CHKERRQ(ierr); 3030 ierr = VecDestroy(&fpc);CHKERRQ(ierr); 3031 3032 /* copy the function pointers over */ 3033 ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->npc);CHKERRQ(ierr); 3034 3035 /* default to 1 iteration */ 3036 ierr = SNESSetTolerances(snes->npc,0.0,0.0,0.0,1,snes->npc->max_funcs);CHKERRQ(ierr); 3037 if (snes->npcside==PC_RIGHT) { 3038 ierr = SNESSetNormSchedule(snes->npc,SNES_NORM_FINAL_ONLY);CHKERRQ(ierr); 3039 } else { 3040 ierr = SNESSetNormSchedule(snes->npc,SNES_NORM_NONE);CHKERRQ(ierr); 3041 } 3042 ierr = SNESSetFromOptions(snes->npc);CHKERRQ(ierr); 3043 3044 /* copy the line search context over */ 3045 if (snes->linesearch && snes->npc->linesearch) { 3046 ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); 3047 ierr = SNESGetLineSearch(snes->npc,&pclinesearch);CHKERRQ(ierr); 3048 ierr = SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx);CHKERRQ(ierr); 3049 ierr = SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx);CHKERRQ(ierr); 3050 ierr = SNESLineSearchSetPreCheck(pclinesearch,precheck,lsprectx);CHKERRQ(ierr); 3051 ierr = SNESLineSearchSetPostCheck(pclinesearch,postcheck,lspostctx);CHKERRQ(ierr); 3052 ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr); 3053 } 3054 } 3055 if (snes->mf) { 3056 ierr = SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version);CHKERRQ(ierr); 3057 } 3058 if (snes->ops->usercompute && !snes->user) { 3059 ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 3060 } 3061 3062 snes->jac_iter = 0; 3063 snes->pre_iter = 0; 3064 3065 if (snes->ops->setup) { 3066 ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 3067 } 3068 3069 if (snes->npc && (snes->npcside== PC_LEFT)) { 3070 if (snes->functype == SNES_FUNCTION_PRECONDITIONED) { 3071 if (snes->linesearch){ 3072 ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr); 3073 ierr = SNESLineSearchSetFunction(linesearch,SNESComputeFunctionDefaultNPC);CHKERRQ(ierr); 3074 } 3075 } 3076 } 3077 ierr = PetscLogEventEnd(SNES_Setup,snes,0,0,0);CHKERRQ(ierr); 3078 snes->setupcalled = PETSC_TRUE; 3079 PetscFunctionReturn(0); 3080 } 3081 3082 /*@ 3083 SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 3084 3085 Collective on SNES 3086 3087 Input Parameter: 3088 . snes - iterative context obtained from SNESCreate() 3089 3090 Level: intermediate 3091 3092 Notes: 3093 Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 3094 3095 .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 3096 @*/ 3097 PetscErrorCode SNESReset(SNES snes) 3098 { 3099 PetscErrorCode ierr; 3100 3101 PetscFunctionBegin; 3102 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3103 if (snes->ops->userdestroy && snes->user) { 3104 ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 3105 snes->user = NULL; 3106 } 3107 if (snes->npc) { 3108 ierr = SNESReset(snes->npc);CHKERRQ(ierr); 3109 } 3110 3111 if (snes->ops->reset) { 3112 ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 3113 } 3114 if (snes->ksp) { 3115 ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 3116 } 3117 3118 if (snes->linesearch) { 3119 ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr); 3120 } 3121 3122 ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 3123 ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 3124 ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 3125 ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 3126 ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 3127 ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 3128 ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 3129 ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 3130 3131 snes->alwayscomputesfinalresidual = PETSC_FALSE; 3132 3133 snes->nwork = snes->nvwork = 0; 3134 snes->setupcalled = PETSC_FALSE; 3135 PetscFunctionReturn(0); 3136 } 3137 3138 /*@ 3139 SNESDestroy - Destroys the nonlinear solver context that was created 3140 with SNESCreate(). 3141 3142 Collective on SNES 3143 3144 Input Parameter: 3145 . snes - the SNES context 3146 3147 Level: beginner 3148 3149 .seealso: SNESCreate(), SNESSolve() 3150 @*/ 3151 PetscErrorCode SNESDestroy(SNES *snes) 3152 { 3153 PetscErrorCode ierr; 3154 3155 PetscFunctionBegin; 3156 if (!*snes) PetscFunctionReturn(0); 3157 PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 3158 if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 3159 3160 ierr = SNESReset((*snes));CHKERRQ(ierr); 3161 ierr = SNESDestroy(&(*snes)->npc);CHKERRQ(ierr); 3162 3163 /* if memory was published with SAWs then destroy it */ 3164 ierr = PetscObjectSAWsViewOff((PetscObject)*snes);CHKERRQ(ierr); 3165 if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 3166 3167 if ((*snes)->dm) {ierr = DMCoarsenHookRemove((*snes)->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,*snes);CHKERRQ(ierr);} 3168 ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 3169 ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 3170 ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 3171 3172 ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 3173 if ((*snes)->ops->convergeddestroy) { 3174 ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 3175 } 3176 if ((*snes)->conv_hist_alloc) { 3177 ierr = PetscFree2((*snes)->conv_hist,(*snes)->conv_hist_its);CHKERRQ(ierr); 3178 } 3179 ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 3180 ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 3181 PetscFunctionReturn(0); 3182 } 3183 3184 /* ----------- Routines to set solver parameters ---------- */ 3185 3186 /*@ 3187 SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 3188 3189 Logically Collective on SNES 3190 3191 Input Parameters: 3192 + snes - the SNES context 3193 - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 3194 the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3195 3196 Options Database Keys: 3197 . -snes_lag_preconditioner <lag> 3198 3199 Notes: 3200 The default is 1 3201 The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3202 If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 3203 3204 Level: intermediate 3205 3206 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 3207 3208 @*/ 3209 PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 3210 { 3211 PetscFunctionBegin; 3212 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3213 if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 3214 if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 3215 PetscValidLogicalCollectiveInt(snes,lag,2); 3216 snes->lagpreconditioner = lag; 3217 PetscFunctionReturn(0); 3218 } 3219 3220 /*@ 3221 SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 3222 3223 Logically Collective on SNES 3224 3225 Input Parameters: 3226 + snes - the SNES context 3227 - steps - the number of refinements to do, defaults to 0 3228 3229 Options Database Keys: 3230 . -snes_grid_sequence <steps> 3231 3232 Level: intermediate 3233 3234 Notes: 3235 Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 3236 3237 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetGridSequence() 3238 3239 @*/ 3240 PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 3241 { 3242 PetscFunctionBegin; 3243 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3244 PetscValidLogicalCollectiveInt(snes,steps,2); 3245 snes->gridsequence = steps; 3246 PetscFunctionReturn(0); 3247 } 3248 3249 /*@ 3250 SNESGetGridSequence - gets the number of steps of grid sequencing that SNES does 3251 3252 Logically Collective on SNES 3253 3254 Input Parameter: 3255 . snes - the SNES context 3256 3257 Output Parameter: 3258 . steps - the number of refinements to do, defaults to 0 3259 3260 Options Database Keys: 3261 . -snes_grid_sequence <steps> 3262 3263 Level: intermediate 3264 3265 Notes: 3266 Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 3267 3268 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESSetGridSequence() 3269 3270 @*/ 3271 PetscErrorCode SNESGetGridSequence(SNES snes,PetscInt *steps) 3272 { 3273 PetscFunctionBegin; 3274 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3275 *steps = snes->gridsequence; 3276 PetscFunctionReturn(0); 3277 } 3278 3279 /*@ 3280 SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 3281 3282 Not Collective 3283 3284 Input Parameter: 3285 . snes - the SNES context 3286 3287 Output Parameter: 3288 . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 3289 the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3290 3291 Options Database Keys: 3292 . -snes_lag_preconditioner <lag> 3293 3294 Notes: 3295 The default is 1 3296 The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3297 3298 Level: intermediate 3299 3300 .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 3301 3302 @*/ 3303 PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 3304 { 3305 PetscFunctionBegin; 3306 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3307 *lag = snes->lagpreconditioner; 3308 PetscFunctionReturn(0); 3309 } 3310 3311 /*@ 3312 SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 3313 often the preconditioner is rebuilt. 3314 3315 Logically Collective on SNES 3316 3317 Input Parameters: 3318 + snes - the SNES context 3319 - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 3320 the Jacobian is built etc. -2 means rebuild at next chance but then never again 3321 3322 Options Database Keys: 3323 . -snes_lag_jacobian <lag> 3324 3325 Notes: 3326 The default is 1 3327 The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3328 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 3329 at the next Newton step but never again (unless it is reset to another value) 3330 3331 Level: intermediate 3332 3333 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 3334 3335 @*/ 3336 PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 3337 { 3338 PetscFunctionBegin; 3339 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3340 if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 3341 if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 3342 PetscValidLogicalCollectiveInt(snes,lag,2); 3343 snes->lagjacobian = lag; 3344 PetscFunctionReturn(0); 3345 } 3346 3347 /*@ 3348 SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 3349 3350 Not Collective 3351 3352 Input Parameter: 3353 . snes - the SNES context 3354 3355 Output Parameter: 3356 . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 3357 the Jacobian is built etc. 3358 3359 Options Database Keys: 3360 . -snes_lag_jacobian <lag> 3361 3362 Notes: 3363 The default is 1 3364 The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3365 3366 Level: intermediate 3367 3368 .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 3369 3370 @*/ 3371 PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 3372 { 3373 PetscFunctionBegin; 3374 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3375 *lag = snes->lagjacobian; 3376 PetscFunctionReturn(0); 3377 } 3378 3379 /*@ 3380 SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple solves 3381 3382 Logically collective on SNES 3383 3384 Input Parameter: 3385 + snes - the SNES context 3386 - flg - jacobian lagging persists if true 3387 3388 Options Database Keys: 3389 . -snes_lag_jacobian_persists <flg> 3390 3391 Notes: 3392 This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by 3393 several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several 3394 timesteps may present huge efficiency gains. 3395 3396 Level: developer 3397 3398 .seealso: SNESSetLagPreconditionerPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC() 3399 3400 @*/ 3401 PetscErrorCode SNESSetLagJacobianPersists(SNES snes,PetscBool flg) 3402 { 3403 PetscFunctionBegin; 3404 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3405 PetscValidLogicalCollectiveBool(snes,flg,2); 3406 snes->lagjac_persist = flg; 3407 PetscFunctionReturn(0); 3408 } 3409 3410 /*@ 3411 SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple solves 3412 3413 Logically Collective on SNES 3414 3415 Input Parameter: 3416 + snes - the SNES context 3417 - flg - preconditioner lagging persists if true 3418 3419 Options Database Keys: 3420 . -snes_lag_jacobian_persists <flg> 3421 3422 Notes: 3423 This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale 3424 by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over 3425 several timesteps may present huge efficiency gains. 3426 3427 Level: developer 3428 3429 .seealso: SNESSetLagJacobianPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC() 3430 3431 @*/ 3432 PetscErrorCode SNESSetLagPreconditionerPersists(SNES snes,PetscBool flg) 3433 { 3434 PetscFunctionBegin; 3435 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3436 PetscValidLogicalCollectiveBool(snes,flg,2); 3437 snes->lagpre_persist = flg; 3438 PetscFunctionReturn(0); 3439 } 3440 3441 /*@ 3442 SNESSetForceIteration - force SNESSolve() to take at least one iteration regardless of the initial residual norm 3443 3444 Logically Collective on SNES 3445 3446 Input Parameters: 3447 + snes - the SNES context 3448 - force - PETSC_TRUE require at least one iteration 3449 3450 Options Database Keys: 3451 . -snes_force_iteration <force> - Sets forcing an iteration 3452 3453 Notes: 3454 This is used sometimes with TS to prevent TS from detecting a false steady state solution 3455 3456 Level: intermediate 3457 3458 .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance() 3459 @*/ 3460 PetscErrorCode SNESSetForceIteration(SNES snes,PetscBool force) 3461 { 3462 PetscFunctionBegin; 3463 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3464 snes->forceiteration = force; 3465 PetscFunctionReturn(0); 3466 } 3467 3468 /*@ 3469 SNESGetForceIteration - Whether or not to force SNESSolve() take at least one iteration regardless of the initial residual norm 3470 3471 Logically Collective on SNES 3472 3473 Input Parameters: 3474 . snes - the SNES context 3475 3476 Output Parameter: 3477 . force - PETSC_TRUE requires at least one iteration. 3478 3479 Level: intermediate 3480 3481 .seealso: SNESSetForceIteration(), SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance() 3482 @*/ 3483 PetscErrorCode SNESGetForceIteration(SNES snes,PetscBool *force) 3484 { 3485 PetscFunctionBegin; 3486 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3487 *force = snes->forceiteration; 3488 PetscFunctionReturn(0); 3489 } 3490 3491 /*@ 3492 SNESSetTolerances - Sets various parameters used in convergence tests. 3493 3494 Logically Collective on SNES 3495 3496 Input Parameters: 3497 + snes - the SNES context 3498 . abstol - absolute convergence tolerance 3499 . rtol - relative convergence tolerance 3500 . stol - convergence tolerance in terms of the norm of the change in the solution between steps, || delta x || < stol*|| x || 3501 . maxit - maximum number of iterations 3502 - maxf - maximum number of function evaluations (-1 indicates no limit) 3503 3504 Options Database Keys: 3505 + -snes_atol <abstol> - Sets abstol 3506 . -snes_rtol <rtol> - Sets rtol 3507 . -snes_stol <stol> - Sets stol 3508 . -snes_max_it <maxit> - Sets maxit 3509 - -snes_max_funcs <maxf> - Sets maxf 3510 3511 Notes: 3512 The default maximum number of iterations is 50. 3513 The default maximum number of function evaluations is 1000. 3514 3515 Level: intermediate 3516 3517 .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance(), SNESSetForceIteration() 3518 @*/ 3519 PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 3520 { 3521 PetscFunctionBegin; 3522 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3523 PetscValidLogicalCollectiveReal(snes,abstol,2); 3524 PetscValidLogicalCollectiveReal(snes,rtol,3); 3525 PetscValidLogicalCollectiveReal(snes,stol,4); 3526 PetscValidLogicalCollectiveInt(snes,maxit,5); 3527 PetscValidLogicalCollectiveInt(snes,maxf,6); 3528 3529 if (abstol != PETSC_DEFAULT) { 3530 if (abstol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %g must be non-negative",(double)abstol); 3531 snes->abstol = abstol; 3532 } 3533 if (rtol != PETSC_DEFAULT) { 3534 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); 3535 snes->rtol = rtol; 3536 } 3537 if (stol != PETSC_DEFAULT) { 3538 if (stol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %g must be non-negative",(double)stol); 3539 snes->stol = stol; 3540 } 3541 if (maxit != PETSC_DEFAULT) { 3542 if (maxit < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 3543 snes->max_its = maxit; 3544 } 3545 if (maxf != PETSC_DEFAULT) { 3546 if (maxf < -1) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be -1 or nonnegative",maxf); 3547 snes->max_funcs = maxf; 3548 } 3549 snes->tolerancesset = PETSC_TRUE; 3550 PetscFunctionReturn(0); 3551 } 3552 3553 /*@ 3554 SNESSetDivergenceTolerance - Sets the divergence tolerance used for the SNES divergence test. 3555 3556 Logically Collective on SNES 3557 3558 Input Parameters: 3559 + snes - the SNES context 3560 - divtol - the divergence tolerance. Use -1 to deactivate the test. 3561 3562 Options Database Keys: 3563 . -snes_divergence_tolerance <divtol> - Sets divtol 3564 3565 Notes: 3566 The default divergence tolerance is 1e4. 3567 3568 Level: intermediate 3569 3570 .seealso: SNESSetTolerances(), SNESGetDivergenceTolerance 3571 @*/ 3572 PetscErrorCode SNESSetDivergenceTolerance(SNES snes,PetscReal divtol) 3573 { 3574 PetscFunctionBegin; 3575 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3576 PetscValidLogicalCollectiveReal(snes,divtol,2); 3577 3578 if (divtol != PETSC_DEFAULT) { 3579 snes->divtol = divtol; 3580 } 3581 else { 3582 snes->divtol = 1.0e4; 3583 } 3584 PetscFunctionReturn(0); 3585 } 3586 3587 /*@ 3588 SNESGetTolerances - Gets various parameters used in convergence tests. 3589 3590 Not Collective 3591 3592 Input Parameters: 3593 + snes - the SNES context 3594 . atol - absolute convergence tolerance 3595 . rtol - relative convergence tolerance 3596 . stol - convergence tolerance in terms of the norm 3597 of the change in the solution between steps 3598 . maxit - maximum number of iterations 3599 - maxf - maximum number of function evaluations 3600 3601 Notes: 3602 The user can specify NULL for any parameter that is not needed. 3603 3604 Level: intermediate 3605 3606 .seealso: SNESSetTolerances() 3607 @*/ 3608 PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 3609 { 3610 PetscFunctionBegin; 3611 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3612 if (atol) *atol = snes->abstol; 3613 if (rtol) *rtol = snes->rtol; 3614 if (stol) *stol = snes->stol; 3615 if (maxit) *maxit = snes->max_its; 3616 if (maxf) *maxf = snes->max_funcs; 3617 PetscFunctionReturn(0); 3618 } 3619 3620 /*@ 3621 SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test. 3622 3623 Not Collective 3624 3625 Input Parameters: 3626 + snes - the SNES context 3627 - divtol - divergence tolerance 3628 3629 Level: intermediate 3630 3631 .seealso: SNESSetDivergenceTolerance() 3632 @*/ 3633 PetscErrorCode SNESGetDivergenceTolerance(SNES snes,PetscReal *divtol) 3634 { 3635 PetscFunctionBegin; 3636 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3637 if (divtol) *divtol = snes->divtol; 3638 PetscFunctionReturn(0); 3639 } 3640 3641 /*@ 3642 SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 3643 3644 Logically Collective on SNES 3645 3646 Input Parameters: 3647 + snes - the SNES context 3648 - tol - tolerance 3649 3650 Options Database Key: 3651 . -snes_trtol <tol> - Sets tol 3652 3653 Level: intermediate 3654 3655 .seealso: SNESSetTolerances() 3656 @*/ 3657 PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 3658 { 3659 PetscFunctionBegin; 3660 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3661 PetscValidLogicalCollectiveReal(snes,tol,2); 3662 snes->deltatol = tol; 3663 PetscFunctionReturn(0); 3664 } 3665 3666 /* 3667 Duplicate the lg monitors for SNES from KSP; for some reason with 3668 dynamic libraries things don't work under Sun4 if we just use 3669 macros instead of functions 3670 */ 3671 PetscErrorCode SNESMonitorLGResidualNorm(SNES snes,PetscInt it,PetscReal norm,void *ctx) 3672 { 3673 PetscErrorCode ierr; 3674 3675 PetscFunctionBegin; 3676 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3677 ierr = KSPMonitorLGResidualNorm((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 3678 PetscFunctionReturn(0); 3679 } 3680 3681 PetscErrorCode SNESMonitorLGCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *lgctx) 3682 { 3683 PetscErrorCode ierr; 3684 3685 PetscFunctionBegin; 3686 ierr = KSPMonitorLGResidualNormCreate(comm,host,label,x,y,m,n,lgctx);CHKERRQ(ierr); 3687 PetscFunctionReturn(0); 3688 } 3689 3690 PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 3691 3692 PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 3693 { 3694 PetscDrawLG lg; 3695 PetscErrorCode ierr; 3696 PetscReal x,y,per; 3697 PetscViewer v = (PetscViewer)monctx; 3698 static PetscReal prev; /* should be in the context */ 3699 PetscDraw draw; 3700 3701 PetscFunctionBegin; 3702 PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,4); 3703 ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 3704 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3705 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3706 ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 3707 x = (PetscReal)n; 3708 if (rnorm > 0.0) y = PetscLog10Real(rnorm); 3709 else y = -15.0; 3710 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3711 if (n < 20 || !(n % 5) || snes->reason) { 3712 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 3713 ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3714 } 3715 3716 ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 3717 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3718 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3719 ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 3720 ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 3721 x = (PetscReal)n; 3722 y = 100.0*per; 3723 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3724 if (n < 20 || !(n % 5) || snes->reason) { 3725 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 3726 ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3727 } 3728 3729 ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 3730 if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3731 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3732 ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 3733 x = (PetscReal)n; 3734 y = (prev - rnorm)/prev; 3735 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3736 if (n < 20 || !(n % 5) || snes->reason) { 3737 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 3738 ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3739 } 3740 3741 ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 3742 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 3743 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 3744 ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 3745 x = (PetscReal)n; 3746 y = (prev - rnorm)/(prev*per); 3747 if (n > 2) { /*skip initial crazy value */ 3748 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 3749 } 3750 if (n < 20 || !(n % 5) || snes->reason) { 3751 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 3752 ierr = PetscDrawLGSave(lg);CHKERRQ(ierr); 3753 } 3754 prev = rnorm; 3755 PetscFunctionReturn(0); 3756 } 3757 3758 /*@ 3759 SNESMonitor - runs the user provided monitor routines, if they exist 3760 3761 Collective on SNES 3762 3763 Input Parameters: 3764 + snes - nonlinear solver context obtained from SNESCreate() 3765 . iter - iteration number 3766 - rnorm - relative norm of the residual 3767 3768 Notes: 3769 This routine is called by the SNES implementations. 3770 It does not typically need to be called by the user. 3771 3772 Level: developer 3773 3774 .seealso: SNESMonitorSet() 3775 @*/ 3776 PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 3777 { 3778 PetscErrorCode ierr; 3779 PetscInt i,n = snes->numbermonitors; 3780 3781 PetscFunctionBegin; 3782 ierr = VecLockReadPush(snes->vec_sol);CHKERRQ(ierr); 3783 for (i=0; i<n; i++) { 3784 ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 3785 } 3786 ierr = VecLockReadPop(snes->vec_sol);CHKERRQ(ierr); 3787 PetscFunctionReturn(0); 3788 } 3789 3790 /* ------------ Routines to set performance monitoring options ----------- */ 3791 3792 /*MC 3793 SNESMonitorFunction - functional form passed to SNESMonitorSet() to monitor convergence of nonlinear solver 3794 3795 Synopsis: 3796 #include <petscsnes.h> 3797 $ PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx) 3798 3799 + snes - the SNES context 3800 . its - iteration number 3801 . norm - 2-norm function value (may be estimated) 3802 - mctx - [optional] monitoring context 3803 3804 Level: advanced 3805 3806 .seealso: SNESMonitorSet(), SNESMonitorGet() 3807 M*/ 3808 3809 /*@C 3810 SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 3811 iteration of the nonlinear solver to display the iteration's 3812 progress. 3813 3814 Logically Collective on SNES 3815 3816 Input Parameters: 3817 + snes - the SNES context 3818 . f - the monitor function, see SNESMonitorFunction for the calling sequence 3819 . mctx - [optional] user-defined context for private data for the 3820 monitor routine (use NULL if no context is desired) 3821 - monitordestroy - [optional] routine that frees monitor context 3822 (may be NULL) 3823 3824 Options Database Keys: 3825 + -snes_monitor - sets SNESMonitorDefault() 3826 . -snes_monitor_lg_residualnorm - sets line graph monitor, 3827 uses SNESMonitorLGCreate() 3828 - -snes_monitor_cancel - cancels all monitors that have 3829 been hardwired into a code by 3830 calls to SNESMonitorSet(), but 3831 does not cancel those set via 3832 the options database. 3833 3834 Notes: 3835 Several different monitoring routines may be set by calling 3836 SNESMonitorSet() multiple times; all will be called in the 3837 order in which they were set. 3838 3839 Fortran Notes: 3840 Only a single monitor function can be set for each SNES object 3841 3842 Level: intermediate 3843 3844 .seealso: SNESMonitorDefault(), SNESMonitorCancel(), SNESMonitorFunction 3845 @*/ 3846 PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*f)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 3847 { 3848 PetscInt i; 3849 PetscErrorCode ierr; 3850 PetscBool identical; 3851 3852 PetscFunctionBegin; 3853 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3854 for (i=0; i<snes->numbermonitors;i++) { 3855 ierr = PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))snes->monitor[i],snes->monitorcontext[i],snes->monitordestroy[i],&identical);CHKERRQ(ierr); 3856 if (identical) PetscFunctionReturn(0); 3857 } 3858 if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 3859 snes->monitor[snes->numbermonitors] = f; 3860 snes->monitordestroy[snes->numbermonitors] = monitordestroy; 3861 snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 3862 PetscFunctionReturn(0); 3863 } 3864 3865 /*@ 3866 SNESMonitorCancel - Clears all the monitor functions for a SNES object. 3867 3868 Logically Collective on SNES 3869 3870 Input Parameters: 3871 . snes - the SNES context 3872 3873 Options Database Key: 3874 . -snes_monitor_cancel - cancels all monitors that have been hardwired 3875 into a code by calls to SNESMonitorSet(), but does not cancel those 3876 set via the options database 3877 3878 Notes: 3879 There is no way to clear one specific monitor from a SNES object. 3880 3881 Level: intermediate 3882 3883 .seealso: SNESMonitorDefault(), SNESMonitorSet() 3884 @*/ 3885 PetscErrorCode SNESMonitorCancel(SNES snes) 3886 { 3887 PetscErrorCode ierr; 3888 PetscInt i; 3889 3890 PetscFunctionBegin; 3891 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3892 for (i=0; i<snes->numbermonitors; i++) { 3893 if (snes->monitordestroy[i]) { 3894 ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 3895 } 3896 } 3897 snes->numbermonitors = 0; 3898 PetscFunctionReturn(0); 3899 } 3900 3901 /*MC 3902 SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver 3903 3904 Synopsis: 3905 #include <petscsnes.h> 3906 $ PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 3907 3908 + snes - the SNES context 3909 . it - current iteration (0 is the first and is before any Newton step) 3910 . cctx - [optional] convergence context 3911 . reason - reason for convergence/divergence 3912 . xnorm - 2-norm of current iterate 3913 . gnorm - 2-norm of current step 3914 - f - 2-norm of function 3915 3916 Level: intermediate 3917 3918 .seealso: SNESSetConvergenceTest(), SNESGetConvergenceTest() 3919 M*/ 3920 3921 /*@C 3922 SNESSetConvergenceTest - Sets the function that is to be used 3923 to test for convergence of the nonlinear iterative solution. 3924 3925 Logically Collective on SNES 3926 3927 Input Parameters: 3928 + snes - the SNES context 3929 . SNESConvergenceTestFunction - routine to test for convergence 3930 . cctx - [optional] context for private data for the convergence routine (may be NULL) 3931 - destroy - [optional] destructor for the context (may be NULL; PETSC_NULL_FUNCTION in Fortran) 3932 3933 Level: advanced 3934 3935 .seealso: SNESConvergedDefault(), SNESConvergedSkip(), SNESConvergenceTestFunction 3936 @*/ 3937 PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*SNESConvergenceTestFunction)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 3938 { 3939 PetscErrorCode ierr; 3940 3941 PetscFunctionBegin; 3942 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3943 if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip; 3944 if (snes->ops->convergeddestroy) { 3945 ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 3946 } 3947 snes->ops->converged = SNESConvergenceTestFunction; 3948 snes->ops->convergeddestroy = destroy; 3949 snes->cnvP = cctx; 3950 PetscFunctionReturn(0); 3951 } 3952 3953 /*@ 3954 SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 3955 3956 Not Collective 3957 3958 Input Parameter: 3959 . snes - the SNES context 3960 3961 Output Parameter: 3962 . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 3963 manual pages for the individual convergence tests for complete lists 3964 3965 Options Database: 3966 . -snes_converged_reason - prints the reason to standard out 3967 3968 Level: intermediate 3969 3970 Notes: 3971 Should only be called after the call the SNESSolve() is complete, if it is called earlier it returns the value SNES__CONVERGED_ITERATING. 3972 3973 .seealso: SNESSetConvergenceTest(), SNESSetConvergedReason(), SNESConvergedReason 3974 @*/ 3975 PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 3976 { 3977 PetscFunctionBegin; 3978 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3979 PetscValidPointer(reason,2); 3980 *reason = snes->reason; 3981 PetscFunctionReturn(0); 3982 } 3983 3984 /*@ 3985 SNESSetConvergedReason - Sets the reason the SNES iteration was stopped. 3986 3987 Not Collective 3988 3989 Input Parameters: 3990 + snes - the SNES context 3991 - reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 3992 manual pages for the individual convergence tests for complete lists 3993 3994 Level: intermediate 3995 3996 .seealso: SNESGetConvergedReason(), SNESSetConvergenceTest(), SNESConvergedReason 3997 @*/ 3998 PetscErrorCode SNESSetConvergedReason(SNES snes,SNESConvergedReason reason) 3999 { 4000 PetscFunctionBegin; 4001 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4002 snes->reason = reason; 4003 PetscFunctionReturn(0); 4004 } 4005 4006 /*@ 4007 SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 4008 4009 Logically Collective on SNES 4010 4011 Input Parameters: 4012 + snes - iterative context obtained from SNESCreate() 4013 . a - array to hold history, this array will contain the function norms computed at each step 4014 . its - integer array holds the number of linear iterations for each solve. 4015 . na - size of a and its 4016 - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 4017 else it continues storing new values for new nonlinear solves after the old ones 4018 4019 Notes: 4020 If 'a' and 'its' are NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 4021 default array of length 10000 is allocated. 4022 4023 This routine is useful, e.g., when running a code for purposes 4024 of accurate performance monitoring, when no I/O should be done 4025 during the section of code that is being timed. 4026 4027 Level: intermediate 4028 4029 .seealso: SNESGetConvergenceHistory() 4030 4031 @*/ 4032 PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 4033 { 4034 PetscErrorCode ierr; 4035 4036 PetscFunctionBegin; 4037 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4038 if (a) PetscValidScalarPointer(a,2); 4039 if (its) PetscValidIntPointer(its,3); 4040 if (!a) { 4041 if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 4042 ierr = PetscCalloc2(na,&a,na,&its);CHKERRQ(ierr); 4043 snes->conv_hist_alloc = PETSC_TRUE; 4044 } 4045 snes->conv_hist = a; 4046 snes->conv_hist_its = its; 4047 snes->conv_hist_max = na; 4048 snes->conv_hist_len = 0; 4049 snes->conv_hist_reset = reset; 4050 PetscFunctionReturn(0); 4051 } 4052 4053 #if defined(PETSC_HAVE_MATLAB_ENGINE) 4054 #include <engine.h> /* MATLAB include file */ 4055 #include <mex.h> /* MATLAB include file */ 4056 4057 PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 4058 { 4059 mxArray *mat; 4060 PetscInt i; 4061 PetscReal *ar; 4062 4063 PetscFunctionBegin; 4064 mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 4065 ar = (PetscReal*) mxGetData(mat); 4066 for (i=0; i<snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i]; 4067 PetscFunctionReturn(mat); 4068 } 4069 #endif 4070 4071 /*@C 4072 SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 4073 4074 Not Collective 4075 4076 Input Parameter: 4077 . snes - iterative context obtained from SNESCreate() 4078 4079 Output Parameters: 4080 + a - array to hold history 4081 . its - integer array holds the number of linear iterations (or 4082 negative if not converged) for each solve. 4083 - na - size of a and its 4084 4085 Notes: 4086 The calling sequence for this routine in Fortran is 4087 $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 4088 4089 This routine is useful, e.g., when running a code for purposes 4090 of accurate performance monitoring, when no I/O should be done 4091 during the section of code that is being timed. 4092 4093 Level: intermediate 4094 4095 .seealso: SNESSetConvergencHistory() 4096 4097 @*/ 4098 PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 4099 { 4100 PetscFunctionBegin; 4101 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4102 if (a) *a = snes->conv_hist; 4103 if (its) *its = snes->conv_hist_its; 4104 if (na) *na = snes->conv_hist_len; 4105 PetscFunctionReturn(0); 4106 } 4107 4108 /*@C 4109 SNESSetUpdate - Sets the general-purpose update function called 4110 at the beginning of every iteration of the nonlinear solve. Specifically 4111 it is called just before the Jacobian is "evaluated". 4112 4113 Logically Collective on SNES 4114 4115 Input Parameters: 4116 + snes - The nonlinear solver context 4117 - func - The function 4118 4119 Calling sequence of func: 4120 $ func (SNES snes, PetscInt step); 4121 4122 . step - The current step of the iteration 4123 4124 Level: advanced 4125 4126 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() 4127 This is not used by most users. 4128 4129 .seealso SNESSetJacobian(), SNESSolve() 4130 @*/ 4131 PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 4132 { 4133 PetscFunctionBegin; 4134 PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 4135 snes->ops->update = func; 4136 PetscFunctionReturn(0); 4137 } 4138 4139 /* 4140 SNESScaleStep_Private - Scales a step so that its length is less than the 4141 positive parameter delta. 4142 4143 Input Parameters: 4144 + snes - the SNES context 4145 . y - approximate solution of linear system 4146 . fnorm - 2-norm of current function 4147 - delta - trust region size 4148 4149 Output Parameters: 4150 + gpnorm - predicted function norm at the new point, assuming local 4151 linearization. The value is zero if the step lies within the trust 4152 region, and exceeds zero otherwise. 4153 - ynorm - 2-norm of the step 4154 4155 Note: 4156 For non-trust region methods such as SNESNEWTONLS, the parameter delta 4157 is set to be the maximum allowable step size. 4158 4159 */ 4160 PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 4161 { 4162 PetscReal nrm; 4163 PetscScalar cnorm; 4164 PetscErrorCode ierr; 4165 4166 PetscFunctionBegin; 4167 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4168 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 4169 PetscCheckSameComm(snes,1,y,2); 4170 4171 ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 4172 if (nrm > *delta) { 4173 nrm = *delta/nrm; 4174 *gpnorm = (1.0 - nrm)*(*fnorm); 4175 cnorm = nrm; 4176 ierr = VecScale(y,cnorm);CHKERRQ(ierr); 4177 *ynorm = *delta; 4178 } else { 4179 *gpnorm = 0.0; 4180 *ynorm = nrm; 4181 } 4182 PetscFunctionReturn(0); 4183 } 4184 4185 /*@ 4186 SNESReasonView - Displays the reason a SNES solve converged or diverged to a viewer 4187 4188 Collective on SNES 4189 4190 Parameter: 4191 + snes - iterative context obtained from SNESCreate() 4192 - viewer - the viewer to display the reason 4193 4194 4195 Options Database Keys: 4196 . -snes_converged_reason - print reason for converged or diverged, also prints number of iterations 4197 4198 Level: beginner 4199 4200 .seealso: SNESCreate(), SNESSetUp(), SNESDestroy(), SNESSetTolerances(), SNESConvergedDefault() 4201 4202 @*/ 4203 PetscErrorCode SNESReasonView(SNES snes,PetscViewer viewer) 4204 { 4205 PetscViewerFormat format; 4206 PetscBool isAscii; 4207 PetscErrorCode ierr; 4208 4209 PetscFunctionBegin; 4210 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii);CHKERRQ(ierr); 4211 if (isAscii) { 4212 ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr); 4213 ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 4214 if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 4215 DM dm; 4216 Vec u; 4217 PetscDS prob; 4218 PetscInt Nf, f; 4219 PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 4220 void **exactCtx; 4221 PetscReal error; 4222 4223 ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 4224 ierr = SNESGetSolution(snes, &u);CHKERRQ(ierr); 4225 ierr = DMGetDS(dm, &prob);CHKERRQ(ierr); 4226 ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr); 4227 ierr = PetscMalloc2(Nf, &exactSol, Nf, &exactCtx);CHKERRQ(ierr); 4228 for (f = 0; f < Nf; ++f) {ierr = PetscDSGetExactSolution(prob, f, &exactSol[f], &exactCtx[f]);CHKERRQ(ierr);} 4229 ierr = DMComputeL2Diff(dm, 0.0, exactSol, exactCtx, u, &error);CHKERRQ(ierr); 4230 ierr = PetscFree2(exactSol, exactCtx);CHKERRQ(ierr); 4231 if (error < 1.0e-11) {ierr = PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n");CHKERRQ(ierr);} 4232 else {ierr = PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", error);CHKERRQ(ierr);} 4233 } 4234 if (snes->reason > 0) { 4235 if (((PetscObject) snes)->prefix) { 4236 ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve converged due to %s iterations %D\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 4237 } else { 4238 ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 4239 } 4240 } else { 4241 if (((PetscObject) snes)->prefix) { 4242 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); 4243 } else { 4244 ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 4245 } 4246 } 4247 ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr); 4248 } 4249 PetscFunctionReturn(0); 4250 } 4251 4252 /*@C 4253 SNESReasonViewFromOptions - Processes command line options to determine if/how a SNESReason is to be viewed. 4254 4255 Collective on SNES 4256 4257 Input Parameters: 4258 . snes - the SNES object 4259 4260 Level: intermediate 4261 4262 @*/ 4263 PetscErrorCode SNESReasonViewFromOptions(SNES snes) 4264 { 4265 PetscErrorCode ierr; 4266 PetscViewer viewer; 4267 PetscBool flg; 4268 static PetscBool incall = PETSC_FALSE; 4269 PetscViewerFormat format; 4270 4271 PetscFunctionBegin; 4272 if (incall) PetscFunctionReturn(0); 4273 incall = PETSC_TRUE; 4274 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_converged_reason",&viewer,&format,&flg);CHKERRQ(ierr); 4275 if (flg) { 4276 ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr); 4277 ierr = SNESReasonView(snes,viewer);CHKERRQ(ierr); 4278 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 4279 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4280 } 4281 incall = PETSC_FALSE; 4282 PetscFunctionReturn(0); 4283 } 4284 4285 /*@ 4286 SNESSolve - Solves a nonlinear system F(x) = b. 4287 Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 4288 4289 Collective on SNES 4290 4291 Input Parameters: 4292 + snes - the SNES context 4293 . b - the constant part of the equation F(x) = b, or NULL to use zero. 4294 - x - the solution vector. 4295 4296 Notes: 4297 The user should initialize the vector,x, with the initial guess 4298 for the nonlinear solve prior to calling SNESSolve. In particular, 4299 to employ an initial guess of zero, the user should explicitly set 4300 this vector to zero by calling VecSet(). 4301 4302 Level: beginner 4303 4304 .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 4305 @*/ 4306 PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 4307 { 4308 PetscErrorCode ierr; 4309 PetscBool flg; 4310 PetscInt grid; 4311 Vec xcreated = NULL; 4312 DM dm; 4313 4314 PetscFunctionBegin; 4315 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4316 if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 4317 if (x) PetscCheckSameComm(snes,1,x,3); 4318 if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4319 if (b) PetscCheckSameComm(snes,1,b,2); 4320 4321 /* High level operations using the nonlinear solver */ 4322 { 4323 PetscViewer viewer; 4324 PetscViewerFormat format; 4325 PetscInt num; 4326 PetscBool flg; 4327 static PetscBool incall = PETSC_FALSE; 4328 4329 if (!incall) { 4330 /* Estimate the convergence rate of the discretization */ 4331 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) snes),((PetscObject)snes)->options, ((PetscObject) snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg);CHKERRQ(ierr); 4332 if (flg) { 4333 PetscConvEst conv; 4334 DM dm; 4335 PetscReal *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */ 4336 PetscInt Nf; 4337 4338 incall = PETSC_TRUE; 4339 ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 4340 ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr); 4341 ierr = PetscCalloc1(Nf, &alpha);CHKERRQ(ierr); 4342 ierr = PetscConvEstCreate(PetscObjectComm((PetscObject) snes), &conv);CHKERRQ(ierr); 4343 ierr = PetscConvEstSetSolver(conv, snes);CHKERRQ(ierr); 4344 ierr = PetscConvEstSetFromOptions(conv);CHKERRQ(ierr); 4345 ierr = PetscConvEstSetUp(conv);CHKERRQ(ierr); 4346 ierr = PetscConvEstGetConvRate(conv, alpha);CHKERRQ(ierr); 4347 ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr); 4348 ierr = PetscConvEstRateView(conv, alpha, viewer);CHKERRQ(ierr); 4349 ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 4350 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4351 ierr = PetscConvEstDestroy(&conv);CHKERRQ(ierr); 4352 ierr = PetscFree(alpha);CHKERRQ(ierr); 4353 incall = PETSC_FALSE; 4354 } 4355 /* Adaptively refine the initial grid */ 4356 num = 1; 4357 ierr = PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_initial", &num, &flg);CHKERRQ(ierr); 4358 if (flg) { 4359 DMAdaptor adaptor; 4360 4361 incall = PETSC_TRUE; 4362 ierr = DMAdaptorCreate(PETSC_COMM_WORLD, &adaptor);CHKERRQ(ierr); 4363 ierr = DMAdaptorSetSolver(adaptor, snes);CHKERRQ(ierr); 4364 ierr = DMAdaptorSetSequenceLength(adaptor, num);CHKERRQ(ierr); 4365 ierr = DMAdaptorSetFromOptions(adaptor);CHKERRQ(ierr); 4366 ierr = DMAdaptorSetUp(adaptor);CHKERRQ(ierr); 4367 ierr = DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x);CHKERRQ(ierr); 4368 ierr = DMAdaptorDestroy(&adaptor);CHKERRQ(ierr); 4369 incall = PETSC_FALSE; 4370 } 4371 /* Use grid sequencing to adapt */ 4372 num = 0; 4373 ierr = PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_sequence", &num, NULL);CHKERRQ(ierr); 4374 if (num) { 4375 DMAdaptor adaptor; 4376 4377 incall = PETSC_TRUE; 4378 ierr = DMAdaptorCreate(PETSC_COMM_WORLD, &adaptor);CHKERRQ(ierr); 4379 ierr = DMAdaptorSetSolver(adaptor, snes);CHKERRQ(ierr); 4380 ierr = DMAdaptorSetSequenceLength(adaptor, num);CHKERRQ(ierr); 4381 ierr = DMAdaptorSetFromOptions(adaptor);CHKERRQ(ierr); 4382 ierr = DMAdaptorSetUp(adaptor);CHKERRQ(ierr); 4383 ierr = DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x);CHKERRQ(ierr); 4384 ierr = DMAdaptorDestroy(&adaptor);CHKERRQ(ierr); 4385 incall = PETSC_FALSE; 4386 } 4387 } 4388 } 4389 if (!x) { 4390 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4391 ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 4392 x = xcreated; 4393 } 4394 ierr = SNESViewFromOptions(snes,NULL,"-snes_view_pre");CHKERRQ(ierr); 4395 4396 for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr);} 4397 for (grid=0; grid<snes->gridsequence+1; grid++) { 4398 4399 /* set solution vector */ 4400 if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 4401 ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 4402 snes->vec_sol = x; 4403 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4404 4405 /* set affine vector if provided */ 4406 if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 4407 ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 4408 snes->vec_rhs = b; 4409 4410 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"); 4411 if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 4412 if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 4413 if (!snes->vec_sol_update /* && snes->vec_sol */) { 4414 ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 4415 ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->vec_sol_update);CHKERRQ(ierr); 4416 } 4417 ierr = DMShellSetGlobalVector(dm,snes->vec_sol);CHKERRQ(ierr); 4418 ierr = SNESSetUp(snes);CHKERRQ(ierr); 4419 4420 if (!grid) { 4421 if (snes->ops->computeinitialguess) { 4422 ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 4423 } 4424 } 4425 4426 if (snes->conv_hist_reset) snes->conv_hist_len = 0; 4427 if (snes->counters_reset) {snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;} 4428 4429 ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 4430 ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 4431 ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 4432 if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 4433 snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */ 4434 4435 if (snes->lagjac_persist) snes->jac_iter += snes->iter; 4436 if (snes->lagpre_persist) snes->pre_iter += snes->iter; 4437 4438 ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_test_local_min",NULL,NULL,&flg);CHKERRQ(ierr); 4439 if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 4440 ierr = SNESReasonViewFromOptions(snes);CHKERRQ(ierr); 4441 4442 if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 4443 if (snes->reason < 0) break; 4444 if (grid < snes->gridsequence) { 4445 DM fine; 4446 Vec xnew; 4447 Mat interp; 4448 4449 ierr = DMRefine(snes->dm,PetscObjectComm((PetscObject)snes),&fine);CHKERRQ(ierr); 4450 if (!fine) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 4451 ierr = DMCreateInterpolation(snes->dm,fine,&interp,NULL);CHKERRQ(ierr); 4452 ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 4453 ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 4454 ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr); 4455 ierr = MatDestroy(&interp);CHKERRQ(ierr); 4456 x = xnew; 4457 4458 ierr = SNESReset(snes);CHKERRQ(ierr); 4459 ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 4460 ierr = SNESResetFromOptions(snes);CHKERRQ(ierr); 4461 ierr = DMDestroy(&fine);CHKERRQ(ierr); 4462 ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr); 4463 } 4464 } 4465 ierr = SNESViewFromOptions(snes,NULL,"-snes_view");CHKERRQ(ierr); 4466 ierr = VecViewFromOptions(snes->vec_sol,(PetscObject)snes,"-snes_view_solution");CHKERRQ(ierr); 4467 4468 ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 4469 ierr = PetscObjectSAWsBlock((PetscObject)snes);CHKERRQ(ierr); 4470 PetscFunctionReturn(0); 4471 } 4472 4473 /* --------- Internal routines for SNES Package --------- */ 4474 4475 /*@C 4476 SNESSetType - Sets the method for the nonlinear solver. 4477 4478 Collective on SNES 4479 4480 Input Parameters: 4481 + snes - the SNES context 4482 - type - a known method 4483 4484 Options Database Key: 4485 . -snes_type <type> - Sets the method; use -help for a list 4486 of available methods (for instance, newtonls or newtontr) 4487 4488 Notes: 4489 See "petsc/include/petscsnes.h" for available methods (for instance) 4490 + SNESNEWTONLS - Newton's method with line search 4491 (systems of nonlinear equations) 4492 - SNESNEWTONTR - Newton's method with trust region 4493 (systems of nonlinear equations) 4494 4495 Normally, it is best to use the SNESSetFromOptions() command and then 4496 set the SNES solver type from the options database rather than by using 4497 this routine. Using the options database provides the user with 4498 maximum flexibility in evaluating the many nonlinear solvers. 4499 The SNESSetType() routine is provided for those situations where it 4500 is necessary to set the nonlinear solver independently of the command 4501 line or options database. This might be the case, for example, when 4502 the choice of solver changes during the execution of the program, 4503 and the user's application is taking responsibility for choosing the 4504 appropriate method. 4505 4506 Developer Notes: 4507 SNESRegister() adds a constructor for a new SNESType to SNESList, SNESSetType() locates 4508 the constructor in that list and calls it to create the spexific object. 4509 4510 Level: intermediate 4511 4512 .seealso: SNESType, SNESCreate(), SNESDestroy(), SNESGetType(), SNESSetFromOptions() 4513 4514 @*/ 4515 PetscErrorCode SNESSetType(SNES snes,SNESType type) 4516 { 4517 PetscErrorCode ierr,(*r)(SNES); 4518 PetscBool match; 4519 4520 PetscFunctionBegin; 4521 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4522 PetscValidCharPointer(type,2); 4523 4524 ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 4525 if (match) PetscFunctionReturn(0); 4526 4527 ierr = PetscFunctionListFind(SNESList,type,&r);CHKERRQ(ierr); 4528 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 4529 /* Destroy the previous private SNES context */ 4530 if (snes->ops->destroy) { 4531 ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 4532 snes->ops->destroy = NULL; 4533 } 4534 /* Reinitialize function pointers in SNESOps structure */ 4535 snes->ops->setup = 0; 4536 snes->ops->solve = 0; 4537 snes->ops->view = 0; 4538 snes->ops->setfromoptions = 0; 4539 snes->ops->destroy = 0; 4540 ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 4541 /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 4542 snes->setupcalled = PETSC_FALSE; 4543 4544 ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 4545 ierr = (*r)(snes);CHKERRQ(ierr); 4546 PetscFunctionReturn(0); 4547 } 4548 4549 /*@C 4550 SNESGetType - Gets the SNES method type and name (as a string). 4551 4552 Not Collective 4553 4554 Input Parameter: 4555 . snes - nonlinear solver context 4556 4557 Output Parameter: 4558 . type - SNES method (a character string) 4559 4560 Level: intermediate 4561 4562 @*/ 4563 PetscErrorCode SNESGetType(SNES snes,SNESType *type) 4564 { 4565 PetscFunctionBegin; 4566 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4567 PetscValidPointer(type,2); 4568 *type = ((PetscObject)snes)->type_name; 4569 PetscFunctionReturn(0); 4570 } 4571 4572 /*@ 4573 SNESSetSolution - Sets the solution vector for use by the SNES routines. 4574 4575 Logically Collective on SNES 4576 4577 Input Parameters: 4578 + snes - the SNES context obtained from SNESCreate() 4579 - u - the solution vector 4580 4581 Level: beginner 4582 4583 @*/ 4584 PetscErrorCode SNESSetSolution(SNES snes, Vec u) 4585 { 4586 DM dm; 4587 PetscErrorCode ierr; 4588 4589 PetscFunctionBegin; 4590 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4591 PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 4592 ierr = PetscObjectReference((PetscObject) u);CHKERRQ(ierr); 4593 ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 4594 4595 snes->vec_sol = u; 4596 4597 ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 4598 ierr = DMShellSetGlobalVector(dm, u);CHKERRQ(ierr); 4599 PetscFunctionReturn(0); 4600 } 4601 4602 /*@ 4603 SNESGetSolution - Returns the vector where the approximate solution is 4604 stored. This is the fine grid solution when using SNESSetGridSequence(). 4605 4606 Not Collective, but Vec is parallel if SNES is parallel 4607 4608 Input Parameter: 4609 . snes - the SNES context 4610 4611 Output Parameter: 4612 . x - the solution 4613 4614 Level: intermediate 4615 4616 .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 4617 @*/ 4618 PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 4619 { 4620 PetscFunctionBegin; 4621 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4622 PetscValidPointer(x,2); 4623 *x = snes->vec_sol; 4624 PetscFunctionReturn(0); 4625 } 4626 4627 /*@ 4628 SNESGetSolutionUpdate - Returns the vector where the solution update is 4629 stored. 4630 4631 Not Collective, but Vec is parallel if SNES is parallel 4632 4633 Input Parameter: 4634 . snes - the SNES context 4635 4636 Output Parameter: 4637 . x - the solution update 4638 4639 Level: advanced 4640 4641 .seealso: SNESGetSolution(), SNESGetFunction() 4642 @*/ 4643 PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 4644 { 4645 PetscFunctionBegin; 4646 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4647 PetscValidPointer(x,2); 4648 *x = snes->vec_sol_update; 4649 PetscFunctionReturn(0); 4650 } 4651 4652 /*@C 4653 SNESGetFunction - Returns the vector where the function is stored. 4654 4655 Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 4656 4657 Input Parameter: 4658 . snes - the SNES context 4659 4660 Output Parameter: 4661 + r - the vector that is used to store residuals (or NULL if you don't want it) 4662 . f - the function (or NULL if you don't want it); see SNESFunction for calling sequence details 4663 - ctx - the function context (or NULL if you don't want it) 4664 4665 Level: advanced 4666 4667 Notes: The vector r DOES NOT, in general contain the current value of the SNES nonlinear function 4668 4669 .seealso: SNESSetFunction(), SNESGetSolution(), SNESFunction 4670 @*/ 4671 PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx) 4672 { 4673 PetscErrorCode ierr; 4674 DM dm; 4675 4676 PetscFunctionBegin; 4677 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4678 if (r) { 4679 if (!snes->vec_func) { 4680 if (snes->vec_rhs) { 4681 ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 4682 } else if (snes->vec_sol) { 4683 ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 4684 } else if (snes->dm) { 4685 ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 4686 } 4687 } 4688 *r = snes->vec_func; 4689 } 4690 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4691 ierr = DMSNESGetFunction(dm,f,ctx);CHKERRQ(ierr); 4692 PetscFunctionReturn(0); 4693 } 4694 4695 /*@C 4696 SNESGetNGS - Returns the NGS function and context. 4697 4698 Input Parameter: 4699 . snes - the SNES context 4700 4701 Output Parameter: 4702 + f - the function (or NULL) see SNESNGSFunction for details 4703 - ctx - the function context (or NULL) 4704 4705 Level: advanced 4706 4707 .seealso: SNESSetNGS(), SNESGetFunction() 4708 @*/ 4709 4710 PetscErrorCode SNESGetNGS (SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void*), void ** ctx) 4711 { 4712 PetscErrorCode ierr; 4713 DM dm; 4714 4715 PetscFunctionBegin; 4716 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4717 ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4718 ierr = DMSNESGetNGS(dm,f,ctx);CHKERRQ(ierr); 4719 PetscFunctionReturn(0); 4720 } 4721 4722 /*@C 4723 SNESSetOptionsPrefix - Sets the prefix used for searching for all 4724 SNES options in the database. 4725 4726 Logically Collective on SNES 4727 4728 Input Parameter: 4729 + snes - the SNES context 4730 - prefix - the prefix to prepend to all option names 4731 4732 Notes: 4733 A hyphen (-) must NOT be given at the beginning of the prefix name. 4734 The first character of all runtime options is AUTOMATICALLY the hyphen. 4735 4736 Level: advanced 4737 4738 .seealso: SNESSetFromOptions() 4739 @*/ 4740 PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 4741 { 4742 PetscErrorCode ierr; 4743 4744 PetscFunctionBegin; 4745 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4746 ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 4747 if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 4748 if (snes->linesearch) { 4749 ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr); 4750 ierr = PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr); 4751 } 4752 ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 4753 PetscFunctionReturn(0); 4754 } 4755 4756 /*@C 4757 SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 4758 SNES options in the database. 4759 4760 Logically Collective on SNES 4761 4762 Input Parameters: 4763 + snes - the SNES context 4764 - prefix - the prefix to prepend to all option names 4765 4766 Notes: 4767 A hyphen (-) must NOT be given at the beginning of the prefix name. 4768 The first character of all runtime options is AUTOMATICALLY the hyphen. 4769 4770 Level: advanced 4771 4772 .seealso: SNESGetOptionsPrefix() 4773 @*/ 4774 PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 4775 { 4776 PetscErrorCode ierr; 4777 4778 PetscFunctionBegin; 4779 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4780 ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 4781 if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 4782 if (snes->linesearch) { 4783 ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr); 4784 ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr); 4785 } 4786 ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 4787 PetscFunctionReturn(0); 4788 } 4789 4790 /*@C 4791 SNESGetOptionsPrefix - Sets the prefix used for searching for all 4792 SNES options in the database. 4793 4794 Not Collective 4795 4796 Input Parameter: 4797 . snes - the SNES context 4798 4799 Output Parameter: 4800 . prefix - pointer to the prefix string used 4801 4802 Notes: 4803 On the fortran side, the user should pass in a string 'prefix' of 4804 sufficient length to hold the prefix. 4805 4806 Level: advanced 4807 4808 .seealso: SNESAppendOptionsPrefix() 4809 @*/ 4810 PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 4811 { 4812 PetscErrorCode ierr; 4813 4814 PetscFunctionBegin; 4815 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4816 ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 4817 PetscFunctionReturn(0); 4818 } 4819 4820 4821 /*@C 4822 SNESRegister - Adds a method to the nonlinear solver package. 4823 4824 Not collective 4825 4826 Input Parameters: 4827 + name_solver - name of a new user-defined solver 4828 - routine_create - routine to create method context 4829 4830 Notes: 4831 SNESRegister() may be called multiple times to add several user-defined solvers. 4832 4833 Sample usage: 4834 .vb 4835 SNESRegister("my_solver",MySolverCreate); 4836 .ve 4837 4838 Then, your solver can be chosen with the procedural interface via 4839 $ SNESSetType(snes,"my_solver") 4840 or at runtime via the option 4841 $ -snes_type my_solver 4842 4843 Level: advanced 4844 4845 Note: If your function is not being put into a shared library then use SNESRegister() instead 4846 4847 .seealso: SNESRegisterAll(), SNESRegisterDestroy() 4848 4849 Level: advanced 4850 @*/ 4851 PetscErrorCode SNESRegister(const char sname[],PetscErrorCode (*function)(SNES)) 4852 { 4853 PetscErrorCode ierr; 4854 4855 PetscFunctionBegin; 4856 ierr = SNESInitializePackage();CHKERRQ(ierr); 4857 ierr = PetscFunctionListAdd(&SNESList,sname,function);CHKERRQ(ierr); 4858 PetscFunctionReturn(0); 4859 } 4860 4861 PetscErrorCode SNESTestLocalMin(SNES snes) 4862 { 4863 PetscErrorCode ierr; 4864 PetscInt N,i,j; 4865 Vec u,uh,fh; 4866 PetscScalar value; 4867 PetscReal norm; 4868 4869 PetscFunctionBegin; 4870 ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 4871 ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 4872 ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 4873 4874 /* currently only works for sequential */ 4875 ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");CHKERRQ(ierr); 4876 ierr = VecGetSize(u,&N);CHKERRQ(ierr); 4877 for (i=0; i<N; i++) { 4878 ierr = VecCopy(u,uh);CHKERRQ(ierr); 4879 ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 4880 for (j=-10; j<11; j++) { 4881 value = PetscSign(j)*PetscExpReal(PetscAbs(j)-10.0); 4882 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 4883 ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 4884 ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 4885 ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 4886 value = -value; 4887 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 4888 } 4889 } 4890 ierr = VecDestroy(&uh);CHKERRQ(ierr); 4891 ierr = VecDestroy(&fh);CHKERRQ(ierr); 4892 PetscFunctionReturn(0); 4893 } 4894 4895 /*@ 4896 SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 4897 computing relative tolerance for linear solvers within an inexact 4898 Newton method. 4899 4900 Logically Collective on SNES 4901 4902 Input Parameters: 4903 + snes - SNES context 4904 - flag - PETSC_TRUE or PETSC_FALSE 4905 4906 Options Database: 4907 + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 4908 . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 4909 . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 4910 . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 4911 . -snes_ksp_ew_gamma <gamma> - Sets gamma 4912 . -snes_ksp_ew_alpha <alpha> - Sets alpha 4913 . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 4914 - -snes_ksp_ew_threshold <threshold> - Sets threshold 4915 4916 Notes: 4917 Currently, the default is to use a constant relative tolerance for 4918 the inner linear solvers. Alternatively, one can use the 4919 Eisenstat-Walker method, where the relative convergence tolerance 4920 is reset at each Newton iteration according progress of the nonlinear 4921 solver. 4922 4923 Level: advanced 4924 4925 Reference: 4926 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 4927 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 4928 4929 .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 4930 @*/ 4931 PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 4932 { 4933 PetscFunctionBegin; 4934 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4935 PetscValidLogicalCollectiveBool(snes,flag,2); 4936 snes->ksp_ewconv = flag; 4937 PetscFunctionReturn(0); 4938 } 4939 4940 /*@ 4941 SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 4942 for computing relative tolerance for linear solvers within an 4943 inexact Newton method. 4944 4945 Not Collective 4946 4947 Input Parameter: 4948 . snes - SNES context 4949 4950 Output Parameter: 4951 . flag - PETSC_TRUE or PETSC_FALSE 4952 4953 Notes: 4954 Currently, the default is to use a constant relative tolerance for 4955 the inner linear solvers. Alternatively, one can use the 4956 Eisenstat-Walker method, where the relative convergence tolerance 4957 is reset at each Newton iteration according progress of the nonlinear 4958 solver. 4959 4960 Level: advanced 4961 4962 Reference: 4963 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 4964 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 4965 4966 .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 4967 @*/ 4968 PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 4969 { 4970 PetscFunctionBegin; 4971 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4972 PetscValidPointer(flag,2); 4973 *flag = snes->ksp_ewconv; 4974 PetscFunctionReturn(0); 4975 } 4976 4977 /*@ 4978 SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 4979 convergence criteria for the linear solvers within an inexact 4980 Newton method. 4981 4982 Logically Collective on SNES 4983 4984 Input Parameters: 4985 + snes - SNES context 4986 . version - version 1, 2 (default is 2) or 3 4987 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 4988 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 4989 . gamma - multiplicative factor for version 2 rtol computation 4990 (0 <= gamma2 <= 1) 4991 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 4992 . alpha2 - power for safeguard 4993 - threshold - threshold for imposing safeguard (0 < threshold < 1) 4994 4995 Note: 4996 Version 3 was contributed by Luis Chacon, June 2006. 4997 4998 Use PETSC_DEFAULT to retain the default for any of the parameters. 4999 5000 Level: advanced 5001 5002 Reference: 5003 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 5004 inexact Newton method", Utah State University Math. Stat. Dept. Res. 5005 Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 5006 5007 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 5008 @*/ 5009 PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 5010 { 5011 SNESKSPEW *kctx; 5012 5013 PetscFunctionBegin; 5014 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5015 kctx = (SNESKSPEW*)snes->kspconvctx; 5016 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 5017 PetscValidLogicalCollectiveInt(snes,version,2); 5018 PetscValidLogicalCollectiveReal(snes,rtol_0,3); 5019 PetscValidLogicalCollectiveReal(snes,rtol_max,4); 5020 PetscValidLogicalCollectiveReal(snes,gamma,5); 5021 PetscValidLogicalCollectiveReal(snes,alpha,6); 5022 PetscValidLogicalCollectiveReal(snes,alpha2,7); 5023 PetscValidLogicalCollectiveReal(snes,threshold,8); 5024 5025 if (version != PETSC_DEFAULT) kctx->version = version; 5026 if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 5027 if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 5028 if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 5029 if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 5030 if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 5031 if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 5032 5033 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); 5034 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); 5035 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); 5036 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); 5037 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); 5038 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); 5039 PetscFunctionReturn(0); 5040 } 5041 5042 /*@ 5043 SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 5044 convergence criteria for the linear solvers within an inexact 5045 Newton method. 5046 5047 Not Collective 5048 5049 Input Parameters: 5050 snes - SNES context 5051 5052 Output Parameters: 5053 + version - version 1, 2 (default is 2) or 3 5054 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 5055 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 5056 . gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1) 5057 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 5058 . alpha2 - power for safeguard 5059 - threshold - threshold for imposing safeguard (0 < threshold < 1) 5060 5061 Level: advanced 5062 5063 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 5064 @*/ 5065 PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 5066 { 5067 SNESKSPEW *kctx; 5068 5069 PetscFunctionBegin; 5070 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5071 kctx = (SNESKSPEW*)snes->kspconvctx; 5072 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 5073 if (version) *version = kctx->version; 5074 if (rtol_0) *rtol_0 = kctx->rtol_0; 5075 if (rtol_max) *rtol_max = kctx->rtol_max; 5076 if (gamma) *gamma = kctx->gamma; 5077 if (alpha) *alpha = kctx->alpha; 5078 if (alpha2) *alpha2 = kctx->alpha2; 5079 if (threshold) *threshold = kctx->threshold; 5080 PetscFunctionReturn(0); 5081 } 5082 5083 PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 5084 { 5085 PetscErrorCode ierr; 5086 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 5087 PetscReal rtol = PETSC_DEFAULT,stol; 5088 5089 PetscFunctionBegin; 5090 if (!snes->ksp_ewconv) PetscFunctionReturn(0); 5091 if (!snes->iter) { 5092 rtol = kctx->rtol_0; /* first time in, so use the original user rtol */ 5093 ierr = VecNorm(snes->vec_func,NORM_2,&kctx->norm_first);CHKERRQ(ierr); 5094 } 5095 else { 5096 if (kctx->version == 1) { 5097 rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 5098 if (rtol < 0.0) rtol = -rtol; 5099 stol = PetscPowReal(kctx->rtol_last,kctx->alpha2); 5100 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 5101 } else if (kctx->version == 2) { 5102 rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 5103 stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha); 5104 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 5105 } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */ 5106 rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 5107 /* safeguard: avoid sharp decrease of rtol */ 5108 stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha); 5109 stol = PetscMax(rtol,stol); 5110 rtol = PetscMin(kctx->rtol_0,stol); 5111 /* safeguard: avoid oversolving */ 5112 stol = kctx->gamma*(kctx->norm_first*snes->rtol)/snes->norm; 5113 stol = PetscMax(rtol,stol); 5114 rtol = PetscMin(kctx->rtol_0,stol); 5115 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 5116 } 5117 /* safeguard: avoid rtol greater than one */ 5118 rtol = PetscMin(rtol,kctx->rtol_max); 5119 ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 5120 ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%g\n",snes->iter,kctx->version,(double)rtol);CHKERRQ(ierr); 5121 PetscFunctionReturn(0); 5122 } 5123 5124 PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 5125 { 5126 PetscErrorCode ierr; 5127 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 5128 PCSide pcside; 5129 Vec lres; 5130 5131 PetscFunctionBegin; 5132 if (!snes->ksp_ewconv) PetscFunctionReturn(0); 5133 ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 5134 kctx->norm_last = snes->norm; 5135 if (kctx->version == 1) { 5136 PC pc; 5137 PetscBool isNone; 5138 5139 ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr); 5140 ierr = PetscObjectTypeCompare((PetscObject) pc, PCNONE, &isNone);CHKERRQ(ierr); 5141 ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 5142 if (pcside == PC_RIGHT || isNone) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 5143 /* KSP residual is true linear residual */ 5144 ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 5145 } else { 5146 /* KSP residual is preconditioned residual */ 5147 /* compute true linear residual norm */ 5148 ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 5149 ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 5150 ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 5151 ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 5152 ierr = VecDestroy(&lres);CHKERRQ(ierr); 5153 } 5154 } 5155 PetscFunctionReturn(0); 5156 } 5157 5158 /*@ 5159 SNESGetKSP - Returns the KSP context for a SNES solver. 5160 5161 Not Collective, but if SNES object is parallel, then KSP object is parallel 5162 5163 Input Parameter: 5164 . snes - the SNES context 5165 5166 Output Parameter: 5167 . ksp - the KSP context 5168 5169 Notes: 5170 The user can then directly manipulate the KSP context to set various 5171 options, etc. Likewise, the user can then extract and manipulate the 5172 PC contexts as well. 5173 5174 Level: beginner 5175 5176 .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 5177 @*/ 5178 PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 5179 { 5180 PetscErrorCode ierr; 5181 5182 PetscFunctionBegin; 5183 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5184 PetscValidPointer(ksp,2); 5185 5186 if (!snes->ksp) { 5187 PetscBool monitor = PETSC_FALSE; 5188 5189 ierr = KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp);CHKERRQ(ierr); 5190 ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 5191 ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->ksp);CHKERRQ(ierr); 5192 5193 ierr = KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPreSolve_SNESEW,snes);CHKERRQ(ierr); 5194 ierr = KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPostSolve_SNESEW,snes);CHKERRQ(ierr); 5195 5196 ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes",&monitor,NULL);CHKERRQ(ierr); 5197 if (monitor) { 5198 ierr = KSPMonitorSet(snes->ksp,KSPMonitorSNES,snes,NULL);CHKERRQ(ierr); 5199 } 5200 monitor = PETSC_FALSE; 5201 ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes_lg",&monitor,NULL);CHKERRQ(ierr); 5202 if (monitor) { 5203 PetscObject *objs; 5204 ierr = KSPMonitorSNESLGResidualNormCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,600,600,&objs);CHKERRQ(ierr); 5205 objs[0] = (PetscObject) snes; 5206 ierr = KSPMonitorSet(snes->ksp,(PetscErrorCode (*)(KSP,PetscInt,PetscReal,void*))KSPMonitorSNESLGResidualNorm,objs,(PetscErrorCode (*)(void**))KSPMonitorSNESLGResidualNormDestroy);CHKERRQ(ierr); 5207 } 5208 ierr = PetscObjectSetOptions((PetscObject)snes->ksp,((PetscObject)snes)->options);CHKERRQ(ierr); 5209 } 5210 *ksp = snes->ksp; 5211 PetscFunctionReturn(0); 5212 } 5213 5214 5215 #include <petsc/private/dmimpl.h> 5216 /*@ 5217 SNESSetDM - Sets the DM that may be used by some nonlinear solvers or their underlying preconditioners 5218 5219 Logically Collective on SNES 5220 5221 Input Parameters: 5222 + snes - the nonlinear solver context 5223 - dm - the dm, cannot be NULL 5224 5225 Notes: 5226 A DM can only be used for solving one problem at a time because information about the problem is stored on the DM, 5227 even when not using interfaces like DMSNESSetFunction(). Use DMClone() to get a distinct DM when solving different 5228 problems using the same function space. 5229 5230 Level: intermediate 5231 5232 .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 5233 @*/ 5234 PetscErrorCode SNESSetDM(SNES snes,DM dm) 5235 { 5236 PetscErrorCode ierr; 5237 KSP ksp; 5238 DMSNES sdm; 5239 5240 PetscFunctionBegin; 5241 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5242 PetscValidHeaderSpecific(dm,DM_CLASSID,2); 5243 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 5244 if (snes->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */ 5245 if (snes->dm->dmsnes && !dm->dmsnes) { 5246 ierr = DMCopyDMSNES(snes->dm,dm);CHKERRQ(ierr); 5247 ierr = DMGetDMSNES(snes->dm,&sdm);CHKERRQ(ierr); 5248 if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */ 5249 } 5250 ierr = DMCoarsenHookRemove(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr); 5251 ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 5252 } 5253 snes->dm = dm; 5254 snes->dmAuto = PETSC_FALSE; 5255 5256 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 5257 ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 5258 ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 5259 if (snes->npc) { 5260 ierr = SNESSetDM(snes->npc, snes->dm);CHKERRQ(ierr); 5261 ierr = SNESSetNPCSide(snes,snes->npcside);CHKERRQ(ierr); 5262 } 5263 PetscFunctionReturn(0); 5264 } 5265 5266 /*@ 5267 SNESGetDM - Gets the DM that may be used by some preconditioners 5268 5269 Not Collective but DM obtained is parallel on SNES 5270 5271 Input Parameter: 5272 . snes - the preconditioner context 5273 5274 Output Parameter: 5275 . dm - the dm 5276 5277 Level: intermediate 5278 5279 .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 5280 @*/ 5281 PetscErrorCode SNESGetDM(SNES snes,DM *dm) 5282 { 5283 PetscErrorCode ierr; 5284 5285 PetscFunctionBegin; 5286 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5287 if (!snes->dm) { 5288 ierr = DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm);CHKERRQ(ierr); 5289 snes->dmAuto = PETSC_TRUE; 5290 } 5291 *dm = snes->dm; 5292 PetscFunctionReturn(0); 5293 } 5294 5295 /*@ 5296 SNESSetNPC - Sets the nonlinear preconditioner to be used. 5297 5298 Collective on SNES 5299 5300 Input Parameters: 5301 + snes - iterative context obtained from SNESCreate() 5302 - pc - the preconditioner object 5303 5304 Notes: 5305 Use SNESGetNPC() to retrieve the preconditioner context (for example, 5306 to configure it using the API). 5307 5308 Level: developer 5309 5310 .seealso: SNESGetNPC(), SNESHasNPC() 5311 @*/ 5312 PetscErrorCode SNESSetNPC(SNES snes, SNES pc) 5313 { 5314 PetscErrorCode ierr; 5315 5316 PetscFunctionBegin; 5317 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5318 PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 5319 PetscCheckSameComm(snes, 1, pc, 2); 5320 ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 5321 ierr = SNESDestroy(&snes->npc);CHKERRQ(ierr); 5322 snes->npc = pc; 5323 ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->npc);CHKERRQ(ierr); 5324 PetscFunctionReturn(0); 5325 } 5326 5327 /*@ 5328 SNESGetNPC - Creates a nonlinear preconditioning solver (SNES) to be used to precondition the nonlinear solver. 5329 5330 Not Collective; but any changes to the obtained SNES object must be applied collectively 5331 5332 Input Parameter: 5333 . snes - iterative context obtained from SNESCreate() 5334 5335 Output Parameter: 5336 . pc - preconditioner context 5337 5338 Notes: 5339 If a SNES was previously set with SNESSetNPC() then that SNES is returned. 5340 5341 The (preconditioner) SNES returned automatically inherits the same nonlinear function and Jacobian supplied to the original 5342 SNES during SNESSetUp() 5343 5344 Level: developer 5345 5346 .seealso: SNESSetNPC(), SNESHasNPC(), SNES, SNESCreate() 5347 @*/ 5348 PetscErrorCode SNESGetNPC(SNES snes, SNES *pc) 5349 { 5350 PetscErrorCode ierr; 5351 const char *optionsprefix; 5352 5353 PetscFunctionBegin; 5354 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5355 PetscValidPointer(pc, 2); 5356 if (!snes->npc) { 5357 ierr = SNESCreate(PetscObjectComm((PetscObject)snes),&snes->npc);CHKERRQ(ierr); 5358 ierr = PetscObjectIncrementTabLevel((PetscObject)snes->npc,(PetscObject)snes,1);CHKERRQ(ierr); 5359 ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->npc);CHKERRQ(ierr); 5360 ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr); 5361 ierr = SNESSetOptionsPrefix(snes->npc,optionsprefix);CHKERRQ(ierr); 5362 ierr = SNESAppendOptionsPrefix(snes->npc,"npc_");CHKERRQ(ierr); 5363 ierr = SNESSetCountersReset(snes->npc,PETSC_FALSE);CHKERRQ(ierr); 5364 } 5365 *pc = snes->npc; 5366 PetscFunctionReturn(0); 5367 } 5368 5369 /*@ 5370 SNESHasNPC - Returns whether a nonlinear preconditioner exists 5371 5372 Not Collective 5373 5374 Input Parameter: 5375 . snes - iterative context obtained from SNESCreate() 5376 5377 Output Parameter: 5378 . has_npc - whether the SNES has an NPC or not 5379 5380 Level: developer 5381 5382 .seealso: SNESSetNPC(), SNESGetNPC() 5383 @*/ 5384 PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc) 5385 { 5386 PetscFunctionBegin; 5387 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5388 *has_npc = (PetscBool) (snes->npc ? PETSC_TRUE : PETSC_FALSE); 5389 PetscFunctionReturn(0); 5390 } 5391 5392 /*@ 5393 SNESSetNPCSide - Sets the preconditioning side. 5394 5395 Logically Collective on SNES 5396 5397 Input Parameter: 5398 . snes - iterative context obtained from SNESCreate() 5399 5400 Output Parameter: 5401 . side - the preconditioning side, where side is one of 5402 .vb 5403 PC_LEFT - left preconditioning 5404 PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5405 .ve 5406 5407 Options Database Keys: 5408 . -snes_pc_side <right,left> 5409 5410 Notes: 5411 SNESNRICHARDSON and SNESNCG only support left preconditioning. 5412 5413 Level: intermediate 5414 5415 .seealso: SNESGetNPCSide(), KSPSetPCSide() 5416 @*/ 5417 PetscErrorCode SNESSetNPCSide(SNES snes,PCSide side) 5418 { 5419 PetscFunctionBegin; 5420 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5421 PetscValidLogicalCollectiveEnum(snes,side,2); 5422 snes->npcside= side; 5423 PetscFunctionReturn(0); 5424 } 5425 5426 /*@ 5427 SNESGetNPCSide - Gets the preconditioning side. 5428 5429 Not Collective 5430 5431 Input Parameter: 5432 . snes - iterative context obtained from SNESCreate() 5433 5434 Output Parameter: 5435 . side - the preconditioning side, where side is one of 5436 .vb 5437 PC_LEFT - left preconditioning 5438 PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5439 .ve 5440 5441 Level: intermediate 5442 5443 .seealso: SNESSetNPCSide(), KSPGetPCSide() 5444 @*/ 5445 PetscErrorCode SNESGetNPCSide(SNES snes,PCSide *side) 5446 { 5447 PetscFunctionBegin; 5448 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5449 PetscValidPointer(side,2); 5450 *side = snes->npcside; 5451 PetscFunctionReturn(0); 5452 } 5453 5454 /*@ 5455 SNESSetLineSearch - Sets the linesearch on the SNES instance. 5456 5457 Collective on SNES 5458 5459 Input Parameters: 5460 + snes - iterative context obtained from SNESCreate() 5461 - linesearch - the linesearch object 5462 5463 Notes: 5464 Use SNESGetLineSearch() to retrieve the preconditioner context (for example, 5465 to configure it using the API). 5466 5467 Level: developer 5468 5469 .seealso: SNESGetLineSearch() 5470 @*/ 5471 PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch) 5472 { 5473 PetscErrorCode ierr; 5474 5475 PetscFunctionBegin; 5476 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5477 PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 5478 PetscCheckSameComm(snes, 1, linesearch, 2); 5479 ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 5480 ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 5481 5482 snes->linesearch = linesearch; 5483 5484 ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr); 5485 PetscFunctionReturn(0); 5486 } 5487 5488 /*@ 5489 SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch() 5490 or creates a default line search instance associated with the SNES and returns it. 5491 5492 Not Collective 5493 5494 Input Parameter: 5495 . snes - iterative context obtained from SNESCreate() 5496 5497 Output Parameter: 5498 . linesearch - linesearch context 5499 5500 Level: beginner 5501 5502 .seealso: SNESSetLineSearch(), SNESLineSearchCreate() 5503 @*/ 5504 PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch) 5505 { 5506 PetscErrorCode ierr; 5507 const char *optionsprefix; 5508 5509 PetscFunctionBegin; 5510 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5511 PetscValidPointer(linesearch, 2); 5512 if (!snes->linesearch) { 5513 ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 5514 ierr = SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch);CHKERRQ(ierr); 5515 ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 5516 ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr); 5517 ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 5518 ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr); 5519 } 5520 *linesearch = snes->linesearch; 5521 PetscFunctionReturn(0); 5522 } 5523