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