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