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