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