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