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