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