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