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