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