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