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