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