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