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