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