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