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