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