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