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