1 #define PETSCSNES_DLL 2 3 #include "include/private/snesimpl.h" /*I "petscsnes.h" I*/ 4 5 PetscTruth SNESRegisterAllCalled = PETSC_FALSE; 6 PetscFList SNESList = PETSC_NULL; 7 8 /* Logging support */ 9 PetscCookie PETSCSNES_DLLEXPORT SNES_COOKIE = 0; 10 PetscEvent SNES_Solve = 0, SNES_LineSearch = 0, SNES_FunctionEval = 0, SNES_JacobianEval = 0; 11 12 #undef __FUNCT__ 13 #define __FUNCT__ "SNESView" 14 /*@C 15 SNESView - Prints the SNES data structure. 16 17 Collective on SNES 18 19 Input Parameters: 20 + SNES - the SNES context 21 - viewer - visualization context 22 23 Options Database Key: 24 . -snes_view - Calls SNESView() at end of SNESSolve() 25 26 Notes: 27 The available visualization contexts include 28 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 29 - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 30 output where only the first processor opens 31 the file. All other processors send their 32 data to the first processor to print. 33 34 The user can open an alternative visualization context with 35 PetscViewerASCIIOpen() - output to a specified file. 36 37 Level: beginner 38 39 .keywords: SNES, view 40 41 .seealso: PetscViewerASCIIOpen() 42 @*/ 43 PetscErrorCode PETSCSNES_DLLEXPORT SNESView(SNES snes,PetscViewer viewer) 44 { 45 SNES_KSP_EW_ConvCtx *kctx; 46 PetscErrorCode ierr; 47 KSP ksp; 48 SNESType type; 49 PetscTruth iascii,isstring; 50 51 PetscFunctionBegin; 52 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 53 if (!viewer) { 54 ierr = PetscViewerASCIIGetStdout(snes->comm,&viewer);CHKERRQ(ierr); 55 } 56 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,2); 57 PetscCheckSameComm(snes,1,viewer,2); 58 59 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 60 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);CHKERRQ(ierr); 61 if (iascii) { 62 if (snes->prefix) { 63 ierr = PetscViewerASCIIPrintf(viewer,"SNES Object:(%s)\n",snes->prefix);CHKERRQ(ierr); 64 } else { 65 ierr = PetscViewerASCIIPrintf(viewer,"SNES Object:\n");CHKERRQ(ierr); 66 } 67 ierr = SNESGetType(snes,&type);CHKERRQ(ierr); 68 if (type) { 69 ierr = PetscViewerASCIIPrintf(viewer," type: %s\n",type);CHKERRQ(ierr); 70 } else { 71 ierr = PetscViewerASCIIPrintf(viewer," type: not set yet\n");CHKERRQ(ierr); 72 } 73 if (snes->ops->view) { 74 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 75 ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 76 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 77 } 78 ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr); 79 ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%G, absolute=%G, solution=%G\n", 80 snes->rtol,snes->abstol,snes->xtol);CHKERRQ(ierr); 81 ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr); 82 ierr = PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr); 83 if (snes->ksp_ewconv) { 84 kctx = (SNES_KSP_EW_ConvCtx *)snes->kspconvctx; 85 if (kctx) { 86 ierr = PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr); 87 ierr = PetscViewerASCIIPrintf(viewer," rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr); 88 ierr = PetscViewerASCIIPrintf(viewer," gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr); 89 } 90 } 91 } else if (isstring) { 92 ierr = SNESGetType(snes,&type);CHKERRQ(ierr); 93 ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr); 94 } 95 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 96 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 97 ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 98 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 99 PetscFunctionReturn(0); 100 } 101 102 /* 103 We retain a list of functions that also take SNES command 104 line options. These are called at the end SNESSetFromOptions() 105 */ 106 #define MAXSETFROMOPTIONS 5 107 static PetscInt numberofsetfromoptions; 108 static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 109 110 #undef __FUNCT__ 111 #define __FUNCT__ "SNESAddOptionsChecker" 112 /*@C 113 SNESAddOptionsChecker - Adds an additional function to check for SNES options. 114 115 Not Collective 116 117 Input Parameter: 118 . snescheck - function that checks for options 119 120 Level: developer 121 122 .seealso: SNESSetFromOptions() 123 @*/ 124 PetscErrorCode PETSCSNES_DLLEXPORT SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 125 { 126 PetscFunctionBegin; 127 if (numberofsetfromoptions >= MAXSETFROMOPTIONS) { 128 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS); 129 } 130 othersetfromoptions[numberofsetfromoptions++] = snescheck; 131 PetscFunctionReturn(0); 132 } 133 134 #undef __FUNCT__ 135 #define __FUNCT__ "SNESSetFromOptions" 136 /*@ 137 SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 138 139 Collective on SNES 140 141 Input Parameter: 142 . snes - the SNES context 143 144 Options Database Keys: 145 + -snes_type <type> - ls, tr, umls, umtr, test 146 . -snes_stol - convergence tolerance in terms of the norm 147 of the change in the solution between steps 148 . -snes_atol <abstol> - absolute tolerance of residual norm 149 . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 150 . -snes_max_it <max_it> - maximum number of iterations 151 . -snes_max_funcs <max_funcs> - maximum number of function evaluations 152 . -snes_max_fail <max_fail> - maximum number of failures 153 . -snes_trtol <trtol> - trust region tolerance 154 . -snes_no_convergence_test - skip convergence test in nonlinear 155 solver; hence iterations will continue until max_it 156 or some other criterion is reached. Saves expense 157 of convergence test 158 . -snes_monitor <optional filename> - prints residual norm at each iteration. if no 159 filename given prints to stdout 160 . -snes_monitor_solution - plots solution at each iteration 161 . -snes_monitor_residual - plots residual (not its norm) at each iteration 162 . -snes_monitor_solution_update - plots update to solution at each iteration 163 . -snes_monitor_draw - plots residual norm at each iteration 164 . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 165 . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 166 - -snes_converged_reason - print the reason for convergence/divergence after each solve 167 168 Options Database for Eisenstat-Walker method: 169 + -snes_ksp_ew_conv - use Eisenstat-Walker method for determining linear system convergence 170 . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 171 . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 172 . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 173 . -snes_ksp_ew_gamma <gamma> - Sets gamma 174 . -snes_ksp_ew_alpha <alpha> - Sets alpha 175 . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 176 - -snes_ksp_ew_threshold <threshold> - Sets threshold 177 178 Notes: 179 To see all options, run your program with the -help option or consult 180 the users manual. 181 182 Level: beginner 183 184 .keywords: SNES, nonlinear, set, options, database 185 186 .seealso: SNESSetOptionsPrefix() 187 @*/ 188 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetFromOptions(SNES snes) 189 { 190 KSP ksp; 191 SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx *)snes->kspconvctx; 192 PetscTruth flg; 193 PetscErrorCode ierr; 194 PetscInt i; 195 const char *deft; 196 char type[256], monfilename[PETSC_MAX_PATH_LEN]; 197 PetscViewerASCIIMonitor monviewer; 198 199 PetscFunctionBegin; 200 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 201 202 ierr = PetscOptionsBegin(snes->comm,snes->prefix,"Nonlinear solver (SNES) options","SNES");CHKERRQ(ierr); 203 if (snes->type_name) { 204 deft = snes->type_name; 205 } else { 206 deft = SNESLS; 207 } 208 209 if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 210 ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 211 if (flg) { 212 ierr = SNESSetType(snes,type);CHKERRQ(ierr); 213 } else if (!snes->type_name) { 214 ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 215 } 216 ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr); 217 218 ierr = PetscOptionsReal("-snes_stol","Stop if step length less then","SNESSetTolerances",snes->xtol,&snes->xtol,0);CHKERRQ(ierr); 219 ierr = PetscOptionsReal("-snes_atol","Stop if function norm less then","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr); 220 221 ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less then","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr); 222 ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr); 223 ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr); 224 ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr); 225 ierr = PetscOptionsName("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",&flg);CHKERRQ(ierr); 226 if (flg) { 227 snes->printreason = PETSC_TRUE; 228 } 229 230 ierr = PetscOptionsTruth("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNES_KSP_SetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 231 ierr = PetscOptionsTruth("-snes_ksp_ew_conv","Use Eisentat-Walker linear system convergence test","SNES_KSP_SetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 232 233 ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNES_KSP_SetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr); 234 ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNES_KSP_SetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr); 235 ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNES_KSP_SetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr); 236 ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNES_KSP_SetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr); 237 ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNES_KSP_SetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr); 238 ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNES_KSP_SetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr); 239 ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNES_KSP_SetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr); 240 241 ierr = PetscOptionsName("-snes_no_convergence_test","Don't test for convergence","None",&flg);CHKERRQ(ierr); 242 if (flg) {snes->ops->converged = 0;} 243 ierr = PetscOptionsName("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",&flg);CHKERRQ(ierr); 244 if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 245 246 ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 247 if (flg) { 248 ierr = PetscViewerASCIIMonitorCreate(snes->comm,monfilename,0,&monviewer);CHKERRQ(ierr); 249 ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);CHKERRQ(ierr); 250 } 251 252 ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 253 if (flg) { 254 ierr = PetscViewerASCIIMonitorCreate(snes->comm,monfilename,0,&monviewer);CHKERRQ(ierr); 255 ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 256 } 257 258 ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 259 if (flg) { 260 ierr = PetscViewerASCIIMonitorCreate(snes->comm,monfilename,0,&monviewer);CHKERRQ(ierr); 261 ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);CHKERRQ(ierr); 262 } 263 264 ierr = PetscOptionsName("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",&flg);CHKERRQ(ierr); 265 if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 266 ierr = PetscOptionsName("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",&flg);CHKERRQ(ierr); 267 if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 268 ierr = PetscOptionsName("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",&flg);CHKERRQ(ierr); 269 if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 270 ierr = PetscOptionsName("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",&flg);CHKERRQ(ierr); 271 if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 272 273 ierr = PetscOptionsName("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",&flg);CHKERRQ(ierr); 274 if (flg) { 275 ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);CHKERRQ(ierr); 276 ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 277 } 278 279 for(i = 0; i < numberofsetfromoptions; i++) { 280 ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 281 } 282 283 if (snes->ops->setfromoptions) { 284 ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 285 } 286 ierr = PetscOptionsEnd();CHKERRQ(ierr); 287 288 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 289 ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); 290 291 PetscFunctionReturn(0); 292 } 293 294 295 #undef __FUNCT__ 296 #define __FUNCT__ "SNESSetApplicationContext" 297 /*@ 298 SNESSetApplicationContext - Sets the optional user-defined context for 299 the nonlinear solvers. 300 301 Collective on SNES 302 303 Input Parameters: 304 + snes - the SNES context 305 - usrP - optional user context 306 307 Level: intermediate 308 309 .keywords: SNES, nonlinear, set, application, context 310 311 .seealso: SNESGetApplicationContext() 312 @*/ 313 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetApplicationContext(SNES snes,void *usrP) 314 { 315 PetscFunctionBegin; 316 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 317 snes->user = usrP; 318 PetscFunctionReturn(0); 319 } 320 321 #undef __FUNCT__ 322 #define __FUNCT__ "SNESGetApplicationContext" 323 /*@C 324 SNESGetApplicationContext - Gets the user-defined context for the 325 nonlinear solvers. 326 327 Not Collective 328 329 Input Parameter: 330 . snes - SNES context 331 332 Output Parameter: 333 . usrP - user context 334 335 Level: intermediate 336 337 .keywords: SNES, nonlinear, get, application, context 338 339 .seealso: SNESSetApplicationContext() 340 @*/ 341 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetApplicationContext(SNES snes,void **usrP) 342 { 343 PetscFunctionBegin; 344 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 345 *usrP = snes->user; 346 PetscFunctionReturn(0); 347 } 348 349 #undef __FUNCT__ 350 #define __FUNCT__ "SNESGetIterationNumber" 351 /*@ 352 SNESGetIterationNumber - Gets the number of nonlinear iterations completed 353 at this time. 354 355 Not Collective 356 357 Input Parameter: 358 . snes - SNES context 359 360 Output Parameter: 361 . iter - iteration number 362 363 Notes: 364 For example, during the computation of iteration 2 this would return 1. 365 366 This is useful for using lagged Jacobians (where one does not recompute the 367 Jacobian at each SNES iteration). For example, the code 368 .vb 369 ierr = SNESGetIterationNumber(snes,&it); 370 if (!(it % 2)) { 371 [compute Jacobian here] 372 } 373 .ve 374 can be used in your ComputeJacobian() function to cause the Jacobian to be 375 recomputed every second SNES iteration. 376 377 Level: intermediate 378 379 .keywords: SNES, nonlinear, get, iteration, number, 380 381 .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 382 @*/ 383 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetIterationNumber(SNES snes,PetscInt* iter) 384 { 385 PetscFunctionBegin; 386 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 387 PetscValidIntPointer(iter,2); 388 *iter = snes->iter; 389 PetscFunctionReturn(0); 390 } 391 392 #undef __FUNCT__ 393 #define __FUNCT__ "SNESGetFunctionNorm" 394 /*@ 395 SNESGetFunctionNorm - Gets the norm of the current function that was set 396 with SNESSSetFunction(). 397 398 Collective on SNES 399 400 Input Parameter: 401 . snes - SNES context 402 403 Output Parameter: 404 . fnorm - 2-norm of function 405 406 Level: intermediate 407 408 .keywords: SNES, nonlinear, get, function, norm 409 410 .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 411 @*/ 412 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 413 { 414 PetscFunctionBegin; 415 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 416 PetscValidScalarPointer(fnorm,2); 417 *fnorm = snes->norm; 418 PetscFunctionReturn(0); 419 } 420 421 #undef __FUNCT__ 422 #define __FUNCT__ "SNESGetNonlinearStepFailures" 423 /*@ 424 SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 425 attempted by the nonlinear solver. 426 427 Not Collective 428 429 Input Parameter: 430 . snes - SNES context 431 432 Output Parameter: 433 . nfails - number of unsuccessful steps attempted 434 435 Notes: 436 This counter is reset to zero for each successive call to SNESSolve(). 437 438 Level: intermediate 439 440 .keywords: SNES, nonlinear, get, number, unsuccessful, steps 441 @*/ 442 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 443 { 444 PetscFunctionBegin; 445 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 446 PetscValidIntPointer(nfails,2); 447 *nfails = snes->numFailures; 448 PetscFunctionReturn(0); 449 } 450 451 #undef __FUNCT__ 452 #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 453 /*@ 454 SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 455 attempted by the nonlinear solver before it gives up. 456 457 Not Collective 458 459 Input Parameters: 460 + snes - SNES context 461 - maxFails - maximum of unsuccessful steps 462 463 Level: intermediate 464 465 .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 466 @*/ 467 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 468 { 469 PetscFunctionBegin; 470 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 471 snes->maxFailures = maxFails; 472 PetscFunctionReturn(0); 473 } 474 475 #undef __FUNCT__ 476 #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 477 /*@ 478 SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 479 attempted by the nonlinear solver before it gives up. 480 481 Not Collective 482 483 Input Parameter: 484 . snes - SNES context 485 486 Output Parameter: 487 . maxFails - maximum of unsuccessful steps 488 489 Level: intermediate 490 491 .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 492 @*/ 493 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 494 { 495 PetscFunctionBegin; 496 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 497 PetscValidIntPointer(maxFails,2); 498 *maxFails = snes->maxFailures; 499 PetscFunctionReturn(0); 500 } 501 502 #undef __FUNCT__ 503 #define __FUNCT__ "SNESGetLinearSolveFailures" 504 /*@ 505 SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 506 linear solvers. 507 508 Not Collective 509 510 Input Parameter: 511 . snes - SNES context 512 513 Output Parameter: 514 . nfails - number of failed solves 515 516 Notes: 517 This counter is reset to zero for each successive call to SNESSolve(). 518 519 Level: intermediate 520 521 .keywords: SNES, nonlinear, get, number, unsuccessful, steps 522 @*/ 523 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 524 { 525 PetscFunctionBegin; 526 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 527 PetscValidIntPointer(nfails,2); 528 *nfails = snes->numLinearSolveFailures; 529 PetscFunctionReturn(0); 530 } 531 532 #undef __FUNCT__ 533 #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 534 /*@ 535 SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 536 allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 537 538 Collective on SNES 539 540 Input Parameters: 541 + snes - SNES context 542 - maxFails - maximum allowed linear solve failures 543 544 Level: intermediate 545 546 Notes: By default this is 1; that is SNES returns on the first failed linear solve 547 548 .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 549 550 .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 551 @*/ 552 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 553 { 554 PetscFunctionBegin; 555 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 556 snes->maxLinearSolveFailures = maxFails; 557 PetscFunctionReturn(0); 558 } 559 560 #undef __FUNCT__ 561 #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 562 /*@ 563 SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 564 are allowed before SNES terminates 565 566 Not Collective 567 568 Input Parameter: 569 . snes - SNES context 570 571 Output Parameter: 572 . maxFails - maximum of unsuccessful solves allowed 573 574 Level: intermediate 575 576 Notes: By default this is 1; that is SNES returns on the first failed linear solve 577 578 .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 579 580 .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 581 @*/ 582 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 583 { 584 PetscFunctionBegin; 585 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 586 PetscValidIntPointer(maxFails,2); 587 *maxFails = snes->maxLinearSolveFailures; 588 PetscFunctionReturn(0); 589 } 590 591 #undef __FUNCT__ 592 #define __FUNCT__ "SNESGetLinearSolveIterations" 593 /*@ 594 SNESGetLinearSolveIterations - Gets the total number of linear iterations 595 used by the nonlinear solver. 596 597 Not Collective 598 599 Input Parameter: 600 . snes - SNES context 601 602 Output Parameter: 603 . lits - number of linear iterations 604 605 Notes: 606 This counter is reset to zero for each successive call to SNESSolve(). 607 608 Level: intermediate 609 610 .keywords: SNES, nonlinear, get, number, linear, iterations 611 612 .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm() 613 @*/ 614 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 615 { 616 PetscFunctionBegin; 617 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 618 PetscValidIntPointer(lits,2); 619 *lits = snes->linear_its; 620 PetscFunctionReturn(0); 621 } 622 623 #undef __FUNCT__ 624 #define __FUNCT__ "SNESGetKSP" 625 /*@ 626 SNESGetKSP - Returns the KSP context for a SNES solver. 627 628 Not Collective, but if SNES object is parallel, then KSP object is parallel 629 630 Input Parameter: 631 . snes - the SNES context 632 633 Output Parameter: 634 . ksp - the KSP context 635 636 Notes: 637 The user can then directly manipulate the KSP context to set various 638 options, etc. Likewise, the user can then extract and manipulate the 639 PC contexts as well. 640 641 Level: beginner 642 643 .keywords: SNES, nonlinear, get, KSP, context 644 645 .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 646 @*/ 647 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetKSP(SNES snes,KSP *ksp) 648 { 649 PetscFunctionBegin; 650 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 651 PetscValidPointer(ksp,2); 652 *ksp = snes->ksp; 653 PetscFunctionReturn(0); 654 } 655 656 #undef __FUNCT__ 657 #define __FUNCT__ "SNESSetKSP" 658 /*@ 659 SNESSetKSP - Sets a KSP context for the SNES object to use 660 661 Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 662 663 Input Parameters: 664 + snes - the SNES context 665 - ksp - the KSP context 666 667 Notes: 668 The SNES object already has its KSP object, you can obtain with SNESGetKSP() 669 so this routine is rarely needed. 670 671 The KSP object that is already in the SNES object has its reference count 672 decreased by one. 673 674 Level: developer 675 676 .keywords: SNES, nonlinear, get, KSP, context 677 678 .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 679 @*/ 680 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetKSP(SNES snes,KSP ksp) 681 { 682 PetscErrorCode ierr; 683 684 PetscFunctionBegin; 685 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 686 PetscValidHeaderSpecific(ksp,KSP_COOKIE,2); 687 PetscCheckSameComm(snes,1,ksp,2); 688 ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 689 if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 690 snes->ksp = ksp; 691 PetscFunctionReturn(0); 692 } 693 694 #undef __FUNCT__ 695 #define __FUNCT__ "SNESPublish_Petsc" 696 static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 697 { 698 PetscFunctionBegin; 699 PetscFunctionReturn(0); 700 } 701 702 /* -----------------------------------------------------------*/ 703 #undef __FUNCT__ 704 #define __FUNCT__ "SNESCreate" 705 /*@ 706 SNESCreate - Creates a nonlinear solver context. 707 708 Collective on MPI_Comm 709 710 Input Parameters: 711 . comm - MPI communicator 712 713 Output Parameter: 714 . outsnes - the new SNES context 715 716 Options Database Keys: 717 + -snes_mf - Activates default matrix-free Jacobian-vector products, 718 and no preconditioning matrix 719 . -snes_mf_operator - Activates default matrix-free Jacobian-vector 720 products, and a user-provided preconditioning matrix 721 as set by SNESSetJacobian() 722 - -snes_fd - Uses (slow!) finite differences to compute Jacobian 723 724 Level: beginner 725 726 .keywords: SNES, nonlinear, create, context 727 728 .seealso: SNESSolve(), SNESDestroy(), SNES 729 @*/ 730 PetscErrorCode PETSCSNES_DLLEXPORT SNESCreate(MPI_Comm comm,SNES *outsnes) 731 { 732 PetscErrorCode ierr; 733 SNES snes; 734 SNES_KSP_EW_ConvCtx *kctx; 735 736 PetscFunctionBegin; 737 PetscValidPointer(outsnes,2); 738 *outsnes = PETSC_NULL; 739 #ifndef PETSC_USE_DYNAMIC_LIBRARIES 740 ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 741 #endif 742 743 ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_COOKIE,0,"SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 744 snes->bops->publish = SNESPublish_Petsc; 745 snes->max_its = 50; 746 snes->max_funcs = 10000; 747 snes->norm = 0.0; 748 snes->rtol = 1.e-8; 749 snes->ttol = 0.0; 750 snes->abstol = 1.e-50; 751 snes->xtol = 1.e-8; 752 snes->deltatol = 1.e-12; 753 snes->nfuncs = 0; 754 snes->numFailures = 0; 755 snes->maxFailures = 1; 756 snes->linear_its = 0; 757 snes->numbermonitors = 0; 758 snes->data = 0; 759 snes->setupcalled = PETSC_FALSE; 760 snes->ksp_ewconv = PETSC_FALSE; 761 snes->vwork = 0; 762 snes->nwork = 0; 763 snes->conv_hist_len = 0; 764 snes->conv_hist_max = 0; 765 snes->conv_hist = PETSC_NULL; 766 snes->conv_hist_its = PETSC_NULL; 767 snes->conv_hist_reset = PETSC_TRUE; 768 snes->reason = SNES_CONVERGED_ITERATING; 769 770 snes->numLinearSolveFailures = 0; 771 snes->maxLinearSolveFailures = 1; 772 773 /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 774 ierr = PetscNew(SNES_KSP_EW_ConvCtx,&kctx);CHKERRQ(ierr); 775 ierr = PetscLogObjectMemory(snes,sizeof(SNES_KSP_EW_ConvCtx));CHKERRQ(ierr); 776 snes->kspconvctx = (void*)kctx; 777 kctx->version = 2; 778 kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 779 this was too large for some test cases */ 780 kctx->rtol_last = 0; 781 kctx->rtol_max = .9; 782 kctx->gamma = 1.0; 783 kctx->alpha = .5*(1.0 + sqrt(5.0)); 784 kctx->alpha2 = kctx->alpha; 785 kctx->threshold = .1; 786 kctx->lresid_last = 0; 787 kctx->norm_last = 0; 788 789 ierr = KSPCreate(comm,&snes->ksp);CHKERRQ(ierr); 790 ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 791 792 *outsnes = snes; 793 ierr = PetscPublishAll(snes);CHKERRQ(ierr); 794 PetscFunctionReturn(0); 795 } 796 797 #undef __FUNCT__ 798 #define __FUNCT__ "SNESSetFunction" 799 /*@C 800 SNESSetFunction - Sets the function evaluation routine and function 801 vector for use by the SNES routines in solving systems of nonlinear 802 equations. 803 804 Collective on SNES 805 806 Input Parameters: 807 + snes - the SNES context 808 . r - vector to store function value 809 . func - function evaluation routine 810 - ctx - [optional] user-defined context for private data for the 811 function evaluation routine (may be PETSC_NULL) 812 813 Calling sequence of func: 814 $ func (SNES snes,Vec x,Vec f,void *ctx); 815 816 . f - function vector 817 - ctx - optional user-defined function context 818 819 Notes: 820 The Newton-like methods typically solve linear systems of the form 821 $ f'(x) x = -f(x), 822 where f'(x) denotes the Jacobian matrix and f(x) is the function. 823 824 Level: beginner 825 826 .keywords: SNES, nonlinear, set, function 827 828 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 829 @*/ 830 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 831 { 832 PetscFunctionBegin; 833 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 834 PetscValidHeaderSpecific(r,VEC_COOKIE,2); 835 PetscCheckSameComm(snes,1,r,2); 836 837 snes->ops->computefunction = func; 838 snes->vec_func = snes->vec_func_always = r; 839 snes->funP = ctx; 840 PetscFunctionReturn(0); 841 } 842 843 /* --------------------------------------------------------------- */ 844 #undef __FUNCT__ 845 #define __FUNCT__ "SNESSetRhs" 846 /*@C 847 SNESSetRhs - Sets the vector for solving F(x) = rhs. If rhs is not set 848 it assumes a zero right hand side. 849 850 Collective on SNES 851 852 Input Parameters: 853 + snes - the SNES context 854 - rhs - the right hand side vector or PETSC_NULL for a zero right hand side 855 856 Level: intermediate 857 858 .keywords: SNES, nonlinear, set, function, right hand side 859 860 .seealso: SNESGetRhs(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 861 @*/ 862 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetRhs(SNES snes,Vec rhs) 863 { 864 PetscErrorCode ierr; 865 866 PetscFunctionBegin; 867 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 868 if (rhs) { 869 PetscValidHeaderSpecific(rhs,VEC_COOKIE,2); 870 PetscCheckSameComm(snes,1,rhs,2); 871 ierr = PetscObjectReference((PetscObject)rhs);CHKERRQ(ierr); 872 } 873 if (snes->afine) { 874 ierr = VecDestroy(snes->afine);CHKERRQ(ierr); 875 } 876 snes->afine = rhs; 877 PetscFunctionReturn(0); 878 } 879 880 #undef __FUNCT__ 881 #define __FUNCT__ "SNESGetRhs" 882 /*@C 883 SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 884 it assumes a zero right hand side. 885 886 Collective on SNES 887 888 Input Parameter: 889 . snes - the SNES context 890 891 Output Parameter: 892 . rhs - the right hand side vector or PETSC_NULL for a zero right hand side 893 894 Level: intermediate 895 896 .keywords: SNES, nonlinear, get, function, right hand side 897 898 .seealso: SNESSetRhs(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 899 @*/ 900 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetRhs(SNES snes,Vec *rhs) 901 { 902 PetscFunctionBegin; 903 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 904 PetscValidPointer(rhs,2); 905 *rhs = snes->afine; 906 PetscFunctionReturn(0); 907 } 908 909 #undef __FUNCT__ 910 #define __FUNCT__ "SNESComputeFunction" 911 /*@ 912 SNESComputeFunction - Calls the function that has been set with 913 SNESSetFunction(). 914 915 Collective on SNES 916 917 Input Parameters: 918 + snes - the SNES context 919 - x - input vector 920 921 Output Parameter: 922 . y - function vector, as set by SNESSetFunction() 923 924 Notes: 925 SNESComputeFunction() is typically used within nonlinear solvers 926 implementations, so most users would not generally call this routine 927 themselves. 928 929 Level: developer 930 931 .keywords: SNES, nonlinear, compute, function 932 933 .seealso: SNESSetFunction(), SNESGetFunction() 934 @*/ 935 PetscErrorCode PETSCSNES_DLLEXPORT SNESComputeFunction(SNES snes,Vec x,Vec y) 936 { 937 PetscErrorCode ierr; 938 939 PetscFunctionBegin; 940 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 941 PetscValidHeaderSpecific(x,VEC_COOKIE,2); 942 PetscValidHeaderSpecific(y,VEC_COOKIE,3); 943 PetscCheckSameComm(snes,1,x,2); 944 PetscCheckSameComm(snes,1,y,3); 945 946 ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 947 if (snes->ops->computefunction) { 948 PetscStackPush("SNES user function"); 949 CHKMEMQ; 950 ierr = (*snes->ops->computefunction)(snes,x,y,snes->funP); 951 CHKMEMQ; 952 PetscStackPop; 953 if (PetscExceptionValue(ierr)) { 954 PetscErrorCode pierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(pierr); 955 } 956 CHKERRQ(ierr); 957 } else if (snes->afine) { 958 ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 959 } else { 960 SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() before SNESComputeFunction(), likely called from SNESSolve()."); 961 } 962 if (snes->afine) { 963 ierr = VecAXPY(y,-1.0,snes->afine);CHKERRQ(ierr); 964 } 965 snes->nfuncs++; 966 ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 967 PetscFunctionReturn(0); 968 } 969 970 #undef __FUNCT__ 971 #define __FUNCT__ "SNESComputeJacobian" 972 /*@ 973 SNESComputeJacobian - Computes the Jacobian matrix that has been 974 set with SNESSetJacobian(). 975 976 Collective on SNES and Mat 977 978 Input Parameters: 979 + snes - the SNES context 980 - x - input vector 981 982 Output Parameters: 983 + A - Jacobian matrix 984 . B - optional preconditioning matrix 985 - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 986 987 Notes: 988 Most users should not need to explicitly call this routine, as it 989 is used internally within the nonlinear solvers. 990 991 See KSPSetOperators() for important information about setting the 992 flag parameter. 993 994 Level: developer 995 996 .keywords: SNES, compute, Jacobian, matrix 997 998 .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure 999 @*/ 1000 PetscErrorCode PETSCSNES_DLLEXPORT SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 1001 { 1002 PetscErrorCode ierr; 1003 1004 PetscFunctionBegin; 1005 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1006 PetscValidHeaderSpecific(X,VEC_COOKIE,2); 1007 PetscValidPointer(flg,5); 1008 PetscCheckSameComm(snes,1,X,2); 1009 if (!snes->ops->computejacobian) PetscFunctionReturn(0); 1010 ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1011 *flg = DIFFERENT_NONZERO_PATTERN; 1012 PetscStackPush("SNES user Jacobian function"); 1013 CHKMEMQ; 1014 ierr = (*snes->ops->computejacobian)(snes,X,A,B,flg,snes->jacP);CHKERRQ(ierr); 1015 CHKMEMQ; 1016 PetscStackPop; 1017 ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1018 /* make sure user returned a correct Jacobian and preconditioner */ 1019 /* PetscValidHeaderSpecific(*A,MAT_COOKIE,3); 1020 PetscValidHeaderSpecific(*B,MAT_COOKIE,4); */ 1021 PetscFunctionReturn(0); 1022 } 1023 1024 #undef __FUNCT__ 1025 #define __FUNCT__ "SNESSetJacobian" 1026 /*@C 1027 SNESSetJacobian - Sets the function to compute Jacobian as well as the 1028 location to store the matrix. 1029 1030 Collective on SNES and Mat 1031 1032 Input Parameters: 1033 + snes - the SNES context 1034 . A - Jacobian matrix 1035 . B - preconditioner matrix (usually same as the Jacobian) 1036 . func - Jacobian evaluation routine 1037 - ctx - [optional] user-defined context for private data for the 1038 Jacobian evaluation routine (may be PETSC_NULL) 1039 1040 Calling sequence of func: 1041 $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 1042 1043 + x - input vector 1044 . A - Jacobian matrix 1045 . B - preconditioner matrix, usually the same as A 1046 . flag - flag indicating information about the preconditioner matrix 1047 structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 1048 - ctx - [optional] user-defined Jacobian context 1049 1050 Notes: 1051 See KSPSetOperators() for important information about setting the flag 1052 output parameter in the routine func(). Be sure to read this information! 1053 1054 The routine func() takes Mat * as the matrix arguments rather than Mat. 1055 This allows the Jacobian evaluation routine to replace A and/or B with a 1056 completely new new matrix structure (not just different matrix elements) 1057 when appropriate, for instance, if the nonzero structure is changing 1058 throughout the global iterations. 1059 1060 Level: beginner 1061 1062 .keywords: SNES, nonlinear, set, Jacobian, matrix 1063 1064 .seealso: KSPSetOperators(), SNESSetFunction(), MatSNESMFComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 1065 @*/ 1066 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 1067 { 1068 PetscErrorCode ierr; 1069 1070 PetscFunctionBegin; 1071 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1072 if (A) PetscValidHeaderSpecific(A,MAT_COOKIE,2); 1073 if (B) PetscValidHeaderSpecific(B,MAT_COOKIE,3); 1074 if (A) PetscCheckSameComm(snes,1,A,2); 1075 if (B) PetscCheckSameComm(snes,1,B,2); 1076 if (func) snes->ops->computejacobian = func; 1077 if (ctx) snes->jacP = ctx; 1078 if (A) { 1079 ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 1080 if (snes->jacobian) {ierr = MatDestroy(snes->jacobian);CHKERRQ(ierr);} 1081 snes->jacobian = A; 1082 } 1083 if (B) { 1084 ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 1085 if (snes->jacobian_pre) {ierr = MatDestroy(snes->jacobian_pre);CHKERRQ(ierr);} 1086 snes->jacobian_pre = B; 1087 } 1088 PetscFunctionReturn(0); 1089 } 1090 1091 #undef __FUNCT__ 1092 #define __FUNCT__ "SNESGetJacobian" 1093 /*@C 1094 SNESGetJacobian - Returns the Jacobian matrix and optionally the user 1095 provided context for evaluating the Jacobian. 1096 1097 Not Collective, but Mat object will be parallel if SNES object is 1098 1099 Input Parameter: 1100 . snes - the nonlinear solver context 1101 1102 Output Parameters: 1103 + A - location to stash Jacobian matrix (or PETSC_NULL) 1104 . B - location to stash preconditioner matrix (or PETSC_NULL) 1105 . func - location to put Jacobian function (or PETSC_NULL) 1106 - ctx - location to stash Jacobian ctx (or PETSC_NULL) 1107 1108 Level: advanced 1109 1110 .seealso: SNESSetJacobian(), SNESComputeJacobian() 1111 @*/ 1112 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 1113 { 1114 PetscFunctionBegin; 1115 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1116 if (A) *A = snes->jacobian; 1117 if (B) *B = snes->jacobian_pre; 1118 if (func) *func = snes->ops->computejacobian; 1119 if (ctx) *ctx = snes->jacP; 1120 PetscFunctionReturn(0); 1121 } 1122 1123 /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 1124 EXTERN PetscErrorCode PETSCSNES_DLLEXPORT SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 1125 1126 #undef __FUNCT__ 1127 #define __FUNCT__ "SNESSetUp" 1128 /*@ 1129 SNESSetUp - Sets up the internal data structures for the later use 1130 of a nonlinear solver. 1131 1132 Collective on SNES 1133 1134 Input Parameters: 1135 . snes - the SNES context 1136 1137 Notes: 1138 For basic use of the SNES solvers the user need not explicitly call 1139 SNESSetUp(), since these actions will automatically occur during 1140 the call to SNESSolve(). However, if one wishes to control this 1141 phase separately, SNESSetUp() should be called after SNESCreate() 1142 and optional routines of the form SNESSetXXX(), but before SNESSolve(). 1143 1144 Level: advanced 1145 1146 .keywords: SNES, nonlinear, setup 1147 1148 .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 1149 @*/ 1150 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetUp(SNES snes) 1151 { 1152 PetscErrorCode ierr; 1153 PetscTruth flg; 1154 1155 PetscFunctionBegin; 1156 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1157 if (snes->setupcalled) PetscFunctionReturn(0); 1158 1159 ierr = PetscOptionsHasName(snes->prefix,"-snes_mf_operator",&flg);CHKERRQ(ierr); 1160 /* 1161 This version replaces the user provided Jacobian matrix with a 1162 matrix-free version but still employs the user-provided preconditioner matrix 1163 */ 1164 if (flg) { 1165 Mat J; 1166 ierr = MatCreateSNESMF(snes,snes->vec_sol,&J);CHKERRQ(ierr); 1167 ierr = MatSNESMFSetFromOptions(J);CHKERRQ(ierr); 1168 ierr = PetscInfo(snes,"Setting default matrix-free operator routines\n");CHKERRQ(ierr); 1169 ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 1170 ierr = MatDestroy(J);CHKERRQ(ierr); 1171 } 1172 1173 #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_MAT_SINGLE) && !defined(PETSC_USE_LONG_DOUBLE) && !defined(PETSC_USE_INT) 1174 ierr = PetscOptionsHasName(snes->prefix,"-snes_mf_operator2",&flg);CHKERRQ(ierr); 1175 if (flg) { 1176 Mat J; 1177 ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_sol,&J);CHKERRQ(ierr); 1178 ierr = PetscInfo(snes,"Setting default matrix-free operator routines (version 2)\n");CHKERRQ(ierr); 1179 ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 1180 ierr = MatDestroy(J);CHKERRQ(ierr); 1181 } 1182 #endif 1183 1184 ierr = PetscOptionsHasName(snes->prefix,"-snes_mf",&flg);CHKERRQ(ierr); 1185 /* 1186 This version replaces both the user-provided Jacobian and the user- 1187 provided preconditioner matrix with the default matrix free version. 1188 */ 1189 if (flg) { 1190 Mat J; 1191 KSP ksp; 1192 PC pc; 1193 /* create and set matrix-free operator */ 1194 ierr = MatCreateSNESMF(snes,snes->vec_sol,&J);CHKERRQ(ierr); 1195 ierr = MatSNESMFSetFromOptions(J);CHKERRQ(ierr); 1196 ierr = PetscInfo(snes,"Setting default matrix-free operator routines\n");CHKERRQ(ierr); 1197 ierr = SNESSetJacobian(snes,J,J,MatSNESMFComputeJacobian,snes->funP);CHKERRQ(ierr); 1198 ierr = MatDestroy(J);CHKERRQ(ierr); 1199 /* force no preconditioner */ 1200 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 1201 ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 1202 ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&flg);CHKERRQ(ierr); 1203 if (!flg) { 1204 ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines;\nThat is no preconditioner is being used\n");CHKERRQ(ierr); 1205 ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 1206 } 1207 } 1208 1209 if (!snes->vec_func && !snes->afine) { 1210 SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first"); 1211 } 1212 if (!snes->ops->computefunction && !snes->afine) { 1213 SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first"); 1214 } 1215 if (!snes->jacobian) { 1216 SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetJacobian() first \n or use -snes_mf option"); 1217 } 1218 if (snes->vec_func == snes->vec_sol) { 1219 SETERRQ(PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 1220 } 1221 1222 if (!snes->type_name) { 1223 ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 1224 } 1225 if (snes->ops->setup) { 1226 ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 1227 } 1228 snes->setupcalled = PETSC_TRUE; 1229 PetscFunctionReturn(0); 1230 } 1231 1232 #undef __FUNCT__ 1233 #define __FUNCT__ "SNESDestroy" 1234 /*@ 1235 SNESDestroy - Destroys the nonlinear solver context that was created 1236 with SNESCreate(). 1237 1238 Collective on SNES 1239 1240 Input Parameter: 1241 . snes - the SNES context 1242 1243 Level: beginner 1244 1245 .keywords: SNES, nonlinear, destroy 1246 1247 .seealso: SNESCreate(), SNESSolve() 1248 @*/ 1249 PetscErrorCode PETSCSNES_DLLEXPORT SNESDestroy(SNES snes) 1250 { 1251 PetscErrorCode ierr; 1252 1253 PetscFunctionBegin; 1254 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1255 if (--snes->refct > 0) PetscFunctionReturn(0); 1256 1257 /* if memory was published with AMS then destroy it */ 1258 ierr = PetscObjectDepublish(snes);CHKERRQ(ierr); 1259 1260 if (snes->ops->destroy) {ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);} 1261 ierr = PetscFree(snes->kspconvctx);CHKERRQ(ierr); 1262 if (snes->jacobian) {ierr = MatDestroy(snes->jacobian);CHKERRQ(ierr);} 1263 if (snes->jacobian_pre) {ierr = MatDestroy(snes->jacobian_pre);CHKERRQ(ierr);} 1264 if (snes->afine) {ierr = VecDestroy(snes->afine);CHKERRQ(ierr);} 1265 ierr = KSPDestroy(snes->ksp);CHKERRQ(ierr); 1266 if (snes->vwork) {ierr = VecDestroyVecs(snes->vwork,snes->nvwork);CHKERRQ(ierr);} 1267 ierr = SNESMonitorCancel(snes);CHKERRQ(ierr); 1268 ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 1269 PetscFunctionReturn(0); 1270 } 1271 1272 /* ----------- Routines to set solver parameters ---------- */ 1273 1274 #undef __FUNCT__ 1275 #define __FUNCT__ "SNESSetTolerances" 1276 /*@ 1277 SNESSetTolerances - Sets various parameters used in convergence tests. 1278 1279 Collective on SNES 1280 1281 Input Parameters: 1282 + snes - the SNES context 1283 . abstol - absolute convergence tolerance 1284 . rtol - relative convergence tolerance 1285 . stol - convergence tolerance in terms of the norm 1286 of the change in the solution between steps 1287 . maxit - maximum number of iterations 1288 - maxf - maximum number of function evaluations 1289 1290 Options Database Keys: 1291 + -snes_atol <abstol> - Sets abstol 1292 . -snes_rtol <rtol> - Sets rtol 1293 . -snes_stol <stol> - Sets stol 1294 . -snes_max_it <maxit> - Sets maxit 1295 - -snes_max_funcs <maxf> - Sets maxf 1296 1297 Notes: 1298 The default maximum number of iterations is 50. 1299 The default maximum number of function evaluations is 1000. 1300 1301 Level: intermediate 1302 1303 .keywords: SNES, nonlinear, set, convergence, tolerances 1304 1305 .seealso: SNESSetTrustRegionTolerance() 1306 @*/ 1307 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 1308 { 1309 PetscFunctionBegin; 1310 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1311 if (abstol != PETSC_DEFAULT) snes->abstol = abstol; 1312 if (rtol != PETSC_DEFAULT) snes->rtol = rtol; 1313 if (stol != PETSC_DEFAULT) snes->xtol = stol; 1314 if (maxit != PETSC_DEFAULT) snes->max_its = maxit; 1315 if (maxf != PETSC_DEFAULT) snes->max_funcs = maxf; 1316 PetscFunctionReturn(0); 1317 } 1318 1319 #undef __FUNCT__ 1320 #define __FUNCT__ "SNESGetTolerances" 1321 /*@ 1322 SNESGetTolerances - Gets various parameters used in convergence tests. 1323 1324 Not Collective 1325 1326 Input Parameters: 1327 + snes - the SNES context 1328 . abstol - absolute convergence tolerance 1329 . rtol - relative convergence tolerance 1330 . stol - convergence tolerance in terms of the norm 1331 of the change in the solution between steps 1332 . maxit - maximum number of iterations 1333 - maxf - maximum number of function evaluations 1334 1335 Notes: 1336 The user can specify PETSC_NULL for any parameter that is not needed. 1337 1338 Level: intermediate 1339 1340 .keywords: SNES, nonlinear, get, convergence, tolerances 1341 1342 .seealso: SNESSetTolerances() 1343 @*/ 1344 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetTolerances(SNES snes,PetscReal *abstol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 1345 { 1346 PetscFunctionBegin; 1347 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1348 if (abstol) *abstol = snes->abstol; 1349 if (rtol) *rtol = snes->rtol; 1350 if (stol) *stol = snes->xtol; 1351 if (maxit) *maxit = snes->max_its; 1352 if (maxf) *maxf = snes->max_funcs; 1353 PetscFunctionReturn(0); 1354 } 1355 1356 #undef __FUNCT__ 1357 #define __FUNCT__ "SNESSetTrustRegionTolerance" 1358 /*@ 1359 SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 1360 1361 Collective on SNES 1362 1363 Input Parameters: 1364 + snes - the SNES context 1365 - tol - tolerance 1366 1367 Options Database Key: 1368 . -snes_trtol <tol> - Sets tol 1369 1370 Level: intermediate 1371 1372 .keywords: SNES, nonlinear, set, trust region, tolerance 1373 1374 .seealso: SNESSetTolerances() 1375 @*/ 1376 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 1377 { 1378 PetscFunctionBegin; 1379 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1380 snes->deltatol = tol; 1381 PetscFunctionReturn(0); 1382 } 1383 1384 /* 1385 Duplicate the lg monitors for SNES from KSP; for some reason with 1386 dynamic libraries things don't work under Sun4 if we just use 1387 macros instead of functions 1388 */ 1389 #undef __FUNCT__ 1390 #define __FUNCT__ "SNESMonitorLG" 1391 PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 1392 { 1393 PetscErrorCode ierr; 1394 1395 PetscFunctionBegin; 1396 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1397 ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 1398 PetscFunctionReturn(0); 1399 } 1400 1401 #undef __FUNCT__ 1402 #define __FUNCT__ "SNESMonitorLGCreate" 1403 PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 1404 { 1405 PetscErrorCode ierr; 1406 1407 PetscFunctionBegin; 1408 ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 1409 PetscFunctionReturn(0); 1410 } 1411 1412 #undef __FUNCT__ 1413 #define __FUNCT__ "SNESMonitorLGDestroy" 1414 PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorLGDestroy(PetscDrawLG draw) 1415 { 1416 PetscErrorCode ierr; 1417 1418 PetscFunctionBegin; 1419 ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 1420 PetscFunctionReturn(0); 1421 } 1422 1423 /* ------------ Routines to set performance monitoring options ----------- */ 1424 1425 #undef __FUNCT__ 1426 #define __FUNCT__ "SNESMonitorSet" 1427 /*@C 1428 SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 1429 iteration of the nonlinear solver to display the iteration's 1430 progress. 1431 1432 Collective on SNES 1433 1434 Input Parameters: 1435 + snes - the SNES context 1436 . func - monitoring routine 1437 . mctx - [optional] user-defined context for private data for the 1438 monitor routine (use PETSC_NULL if no context is desired) 1439 - monitordestroy - [optional] routine that frees monitor context 1440 (may be PETSC_NULL) 1441 1442 Calling sequence of func: 1443 $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 1444 1445 + snes - the SNES context 1446 . its - iteration number 1447 . norm - 2-norm function value (may be estimated) 1448 - mctx - [optional] monitoring context 1449 1450 Options Database Keys: 1451 + -snes_monitor - sets SNESMonitorDefault() 1452 . -snes_monitor_draw - sets line graph monitor, 1453 uses SNESMonitorLGCreate() 1454 _ -snes_monitor_cancel - cancels all monitors that have 1455 been hardwired into a code by 1456 calls to SNESMonitorSet(), but 1457 does not cancel those set via 1458 the options database. 1459 1460 Notes: 1461 Several different monitoring routines may be set by calling 1462 SNESMonitorSet() multiple times; all will be called in the 1463 order in which they were set. 1464 1465 Level: intermediate 1466 1467 .keywords: SNES, nonlinear, set, monitor 1468 1469 .seealso: SNESMonitorDefault(), SNESMonitorCancel() 1470 @*/ 1471 PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void*)) 1472 { 1473 PetscInt i; 1474 1475 PetscFunctionBegin; 1476 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1477 if (snes->numbermonitors >= MAXSNESMONITORS) { 1478 SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 1479 } 1480 for (i=0; i<snes->numbermonitors;i++) { 1481 if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) PetscFunctionReturn(0); 1482 1483 /* check if both default monitors that share common ASCII viewer */ 1484 if (monitor == snes->monitor[i] && monitor == SNESMonitorDefault) { 1485 if (mctx && snes->monitorcontext[i]) { 1486 PetscErrorCode ierr; 1487 PetscViewerASCIIMonitor viewer1 = (PetscViewerASCIIMonitor) mctx; 1488 PetscViewerASCIIMonitor viewer2 = (PetscViewerASCIIMonitor) snes->monitorcontext[i]; 1489 if (viewer1->viewer == viewer2->viewer) { 1490 ierr = (*monitordestroy)(mctx);CHKERRQ(ierr); 1491 PetscFunctionReturn(0); 1492 } 1493 } 1494 } 1495 } 1496 snes->monitor[snes->numbermonitors] = monitor; 1497 snes->monitordestroy[snes->numbermonitors] = monitordestroy; 1498 snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 1499 PetscFunctionReturn(0); 1500 } 1501 1502 #undef __FUNCT__ 1503 #define __FUNCT__ "SNESMonitorCancel" 1504 /*@C 1505 SNESMonitorCancel - Clears all the monitor functions for a SNES object. 1506 1507 Collective on SNES 1508 1509 Input Parameters: 1510 . snes - the SNES context 1511 1512 Options Database Key: 1513 . -snes_monitor_cancel - cancels all monitors that have been hardwired 1514 into a code by calls to SNESMonitorSet(), but does not cancel those 1515 set via the options database 1516 1517 Notes: 1518 There is no way to clear one specific monitor from a SNES object. 1519 1520 Level: intermediate 1521 1522 .keywords: SNES, nonlinear, set, monitor 1523 1524 .seealso: SNESMonitorDefault(), SNESMonitorSet() 1525 @*/ 1526 PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorCancel(SNES snes) 1527 { 1528 PetscErrorCode ierr; 1529 PetscInt i; 1530 1531 PetscFunctionBegin; 1532 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1533 for (i=0; i<snes->numbermonitors; i++) { 1534 if (snes->monitordestroy[i]) { 1535 ierr = (*snes->monitordestroy[i])(snes->monitorcontext[i]);CHKERRQ(ierr); 1536 } 1537 } 1538 snes->numbermonitors = 0; 1539 PetscFunctionReturn(0); 1540 } 1541 1542 #undef __FUNCT__ 1543 #define __FUNCT__ "SNESSetConvergenceTest" 1544 /*@C 1545 SNESSetConvergenceTest - Sets the function that is to be used 1546 to test for convergence of the nonlinear iterative solution. 1547 1548 Collective on SNES 1549 1550 Input Parameters: 1551 + snes - the SNES context 1552 . func - routine to test for convergence 1553 - cctx - [optional] context for private data for the convergence routine 1554 (may be PETSC_NULL) 1555 1556 Calling sequence of func: 1557 $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 1558 1559 + snes - the SNES context 1560 . it - current iteration (0 is the first and is before any Newton step) 1561 . cctx - [optional] convergence context 1562 . reason - reason for convergence/divergence 1563 . xnorm - 2-norm of current iterate 1564 . gnorm - 2-norm of current step 1565 - f - 2-norm of function 1566 1567 Level: advanced 1568 1569 .keywords: SNES, nonlinear, set, convergence, test 1570 1571 .seealso: SNESDefaultConverged(), SNESSkipConverged(), SNESConverged_LS(), SNESConverged_TR() 1572 @*/ 1573 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx) 1574 { 1575 PetscFunctionBegin; 1576 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1577 (snes)->ops->converged = func; 1578 (snes)->cnvP = cctx; 1579 PetscFunctionReturn(0); 1580 } 1581 1582 #undef __FUNCT__ 1583 #define __FUNCT__ "SNESGetConvergedReason" 1584 /*@ 1585 SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 1586 1587 Not Collective 1588 1589 Input Parameter: 1590 . snes - the SNES context 1591 1592 Output Parameter: 1593 . reason - negative value indicates diverged, positive value converged, see petscsnes.h or the 1594 manual pages for the individual convergence tests for complete lists 1595 1596 Level: intermediate 1597 1598 Notes: Can only be called after the call the SNESSolve() is complete. 1599 1600 .keywords: SNES, nonlinear, set, convergence, test 1601 1602 .seealso: SNESSetConvergenceTest(), SNESConverged_LS(), SNESConverged_TR(), SNESConvergedReason 1603 @*/ 1604 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 1605 { 1606 PetscFunctionBegin; 1607 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1608 PetscValidPointer(reason,2); 1609 *reason = snes->reason; 1610 PetscFunctionReturn(0); 1611 } 1612 1613 #undef __FUNCT__ 1614 #define __FUNCT__ "SNESSetConvergenceHistory" 1615 /*@ 1616 SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 1617 1618 Collective on SNES 1619 1620 Input Parameters: 1621 + snes - iterative context obtained from SNESCreate() 1622 . a - array to hold history 1623 . its - integer array holds the number of linear iterations for each solve. 1624 . na - size of a and its 1625 - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 1626 else it continues storing new values for new nonlinear solves after the old ones 1627 1628 Notes: 1629 If set, this array will contain the function norms computed 1630 at each step. 1631 1632 This routine is useful, e.g., when running a code for purposes 1633 of accurate performance monitoring, when no I/O should be done 1634 during the section of code that is being timed. 1635 1636 Level: intermediate 1637 1638 .keywords: SNES, set, convergence, history 1639 1640 .seealso: SNESGetConvergenceHistory() 1641 1642 @*/ 1643 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscTruth reset) 1644 { 1645 PetscFunctionBegin; 1646 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1647 if (na) PetscValidScalarPointer(a,2); 1648 if (its) PetscValidIntPointer(its,3); 1649 snes->conv_hist = a; 1650 snes->conv_hist_its = its; 1651 snes->conv_hist_max = na; 1652 snes->conv_hist_reset = reset; 1653 PetscFunctionReturn(0); 1654 } 1655 1656 #undef __FUNCT__ 1657 #define __FUNCT__ "SNESGetConvergenceHistory" 1658 /*@C 1659 SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 1660 1661 Collective on SNES 1662 1663 Input Parameter: 1664 . snes - iterative context obtained from SNESCreate() 1665 1666 Output Parameters: 1667 . a - array to hold history 1668 . its - integer array holds the number of linear iterations (or 1669 negative if not converged) for each solve. 1670 - na - size of a and its 1671 1672 Notes: 1673 The calling sequence for this routine in Fortran is 1674 $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 1675 1676 This routine is useful, e.g., when running a code for purposes 1677 of accurate performance monitoring, when no I/O should be done 1678 during the section of code that is being timed. 1679 1680 Level: intermediate 1681 1682 .keywords: SNES, get, convergence, history 1683 1684 .seealso: SNESSetConvergencHistory() 1685 1686 @*/ 1687 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 1688 { 1689 PetscFunctionBegin; 1690 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1691 if (a) *a = snes->conv_hist; 1692 if (its) *its = snes->conv_hist_its; 1693 if (na) *na = snes->conv_hist_len; 1694 PetscFunctionReturn(0); 1695 } 1696 1697 #undef __FUNCT__ 1698 #define __FUNCT__ "SNESSetUpdate" 1699 /*@C 1700 SNESSetUpdate - Sets the general-purpose update function called 1701 at the beginning o every iteration of the nonlinear solve. Specifically 1702 it is called just before the Jacobian is "evaluated". 1703 1704 Collective on SNES 1705 1706 Input Parameters: 1707 . snes - The nonlinear solver context 1708 . func - The function 1709 1710 Calling sequence of func: 1711 . func (SNES snes, PetscInt step); 1712 1713 . step - The current step of the iteration 1714 1715 Level: intermediate 1716 1717 .keywords: SNES, update 1718 1719 .seealso SNESDefaultUpdate(), SNESSetRhsBC(), SNESSetSolutionBC() 1720 @*/ 1721 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 1722 { 1723 PetscFunctionBegin; 1724 PetscValidHeaderSpecific(snes, SNES_COOKIE,1); 1725 snes->ops->update = func; 1726 PetscFunctionReturn(0); 1727 } 1728 1729 #undef __FUNCT__ 1730 #define __FUNCT__ "SNESDefaultUpdate" 1731 /*@ 1732 SNESDefaultUpdate - The default update function which does nothing. 1733 1734 Not collective 1735 1736 Input Parameters: 1737 . snes - The nonlinear solver context 1738 . step - The current step of the iteration 1739 1740 Level: intermediate 1741 1742 .keywords: SNES, update 1743 .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 1744 @*/ 1745 PetscErrorCode PETSCSNES_DLLEXPORT SNESDefaultUpdate(SNES snes, PetscInt step) 1746 { 1747 PetscFunctionBegin; 1748 PetscFunctionReturn(0); 1749 } 1750 1751 #undef __FUNCT__ 1752 #define __FUNCT__ "SNESScaleStep_Private" 1753 /* 1754 SNESScaleStep_Private - Scales a step so that its length is less than the 1755 positive parameter delta. 1756 1757 Input Parameters: 1758 + snes - the SNES context 1759 . y - approximate solution of linear system 1760 . fnorm - 2-norm of current function 1761 - delta - trust region size 1762 1763 Output Parameters: 1764 + gpnorm - predicted function norm at the new point, assuming local 1765 linearization. The value is zero if the step lies within the trust 1766 region, and exceeds zero otherwise. 1767 - ynorm - 2-norm of the step 1768 1769 Note: 1770 For non-trust region methods such as SNESLS, the parameter delta 1771 is set to be the maximum allowable step size. 1772 1773 .keywords: SNES, nonlinear, scale, step 1774 */ 1775 PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 1776 { 1777 PetscReal nrm; 1778 PetscScalar cnorm; 1779 PetscErrorCode ierr; 1780 1781 PetscFunctionBegin; 1782 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1783 PetscValidHeaderSpecific(y,VEC_COOKIE,2); 1784 PetscCheckSameComm(snes,1,y,2); 1785 1786 ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 1787 if (nrm > *delta) { 1788 nrm = *delta/nrm; 1789 *gpnorm = (1.0 - nrm)*(*fnorm); 1790 cnorm = nrm; 1791 ierr = VecScale(y,cnorm);CHKERRQ(ierr); 1792 *ynorm = *delta; 1793 } else { 1794 *gpnorm = 0.0; 1795 *ynorm = nrm; 1796 } 1797 PetscFunctionReturn(0); 1798 } 1799 1800 #undef __FUNCT__ 1801 #define __FUNCT__ "SNESSolve" 1802 /*@C 1803 SNESSolve - Solves a nonlinear system F(x) = b. 1804 Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 1805 1806 Collective on SNES 1807 1808 Input Parameters: 1809 + snes - the SNES context 1810 . b - the constant part of the equation, or PETSC_NULL to use zero. 1811 - x - the solution vector, or PETSC_NULL if it was set with SNESSetSolution() 1812 1813 Notes: 1814 The user should initialize the vector,x, with the initial guess 1815 for the nonlinear solve prior to calling SNESSolve. In particular, 1816 to employ an initial guess of zero, the user should explicitly set 1817 this vector to zero by calling VecSet(). 1818 1819 Level: beginner 1820 1821 .keywords: SNES, nonlinear, solve 1822 1823 .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetRhs(), SNESSetSolution() 1824 @*/ 1825 PetscErrorCode PETSCSNES_DLLEXPORT SNESSolve(SNES snes,Vec b,Vec x) 1826 { 1827 PetscErrorCode ierr; 1828 PetscTruth flg; 1829 char filename[PETSC_MAX_PATH_LEN]; 1830 PetscViewer viewer; 1831 1832 PetscFunctionBegin; 1833 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1834 if (!snes->ops->solve) SETERRQ(PETSC_ERR_ORDER,"SNESSetType() or SNESSetFromOptions() must be called before SNESSolve()"); 1835 1836 if (b) { 1837 ierr = SNESSetRhs(snes, b); CHKERRQ(ierr); 1838 if (!snes->vec_func) { 1839 Vec r; 1840 1841 ierr = VecDuplicate(b, &r); CHKERRQ(ierr); 1842 ierr = SNESSetFunction(snes, r, PETSC_NULL, PETSC_NULL); CHKERRQ(ierr); 1843 } 1844 } 1845 if (x) { 1846 PetscValidHeaderSpecific(x,VEC_COOKIE,3); 1847 PetscCheckSameComm(snes,1,x,3); 1848 } else { 1849 ierr = SNESGetSolution(snes, &x); CHKERRQ(ierr); 1850 if (!x) { 1851 ierr = VecDuplicate(snes->vec_func_always, &x); CHKERRQ(ierr); 1852 } 1853 } 1854 snes->vec_sol = snes->vec_sol_always = x; 1855 1856 ierr = SNESSetUp(snes);CHKERRQ(ierr); 1857 1858 if (snes->conv_hist_reset) snes->conv_hist_len = 0; 1859 snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 1860 1861 ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 1862 1863 ierr = PetscExceptionTry1((*(snes)->ops->solve)(snes),PETSC_ERR_ARG_DOMAIN); 1864 if (PetscExceptionValue(ierr)) { 1865 /* this means that a caller above me has also tryed this exception so I don't handle it here, pass it up */ 1866 PetscErrorCode pierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(pierr); 1867 } else if (PetscExceptionCaught(ierr,PETSC_ERR_ARG_DOMAIN)) { 1868 /* translate exception into SNES not converged reason */ 1869 snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 1870 ierr = 0; 1871 } 1872 CHKERRQ(ierr); 1873 if (!snes->reason) { 1874 SETERRQ(PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 1875 } 1876 if (!snes->ops->converged && snes->reason == SNES_DIVERGED_MAX_IT) { 1877 snes->reason = SNES_CONVERGED_ITS; 1878 } 1879 ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 1880 1881 ierr = PetscOptionsGetString(snes->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 1882 if (flg && !PetscPreLoadingOn) { 1883 ierr = PetscViewerASCIIOpen(snes->comm,filename,&viewer);CHKERRQ(ierr); 1884 ierr = SNESView(snes,viewer);CHKERRQ(ierr); 1885 ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr); 1886 } 1887 1888 ierr = PetscOptionsHasName(snes->prefix,"-snes_test_local_min",&flg);CHKERRQ(ierr); 1889 if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 1890 if (snes->printreason) { 1891 if (snes->reason > 0) { 1892 ierr = PetscPrintf(snes->comm,"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 1893 } else { 1894 ierr = PetscPrintf(snes->comm,"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 1895 } 1896 } 1897 1898 PetscFunctionReturn(0); 1899 } 1900 1901 /* --------- Internal routines for SNES Package --------- */ 1902 1903 #undef __FUNCT__ 1904 #define __FUNCT__ "SNESSetType" 1905 /*@C 1906 SNESSetType - Sets the method for the nonlinear solver. 1907 1908 Collective on SNES 1909 1910 Input Parameters: 1911 + snes - the SNES context 1912 - type - a known method 1913 1914 Options Database Key: 1915 . -snes_type <type> - Sets the method; use -help for a list 1916 of available methods (for instance, ls or tr) 1917 1918 Notes: 1919 See "petsc/include/petscsnes.h" for available methods (for instance) 1920 + SNESLS - Newton's method with line search 1921 (systems of nonlinear equations) 1922 . SNESTR - Newton's method with trust region 1923 (systems of nonlinear equations) 1924 1925 Normally, it is best to use the SNESSetFromOptions() command and then 1926 set the SNES solver type from the options database rather than by using 1927 this routine. Using the options database provides the user with 1928 maximum flexibility in evaluating the many nonlinear solvers. 1929 The SNESSetType() routine is provided for those situations where it 1930 is necessary to set the nonlinear solver independently of the command 1931 line or options database. This might be the case, for example, when 1932 the choice of solver changes during the execution of the program, 1933 and the user's application is taking responsibility for choosing the 1934 appropriate method. 1935 1936 Level: intermediate 1937 1938 .keywords: SNES, set, type 1939 1940 .seealso: SNESType, SNESCreate() 1941 1942 @*/ 1943 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetType(SNES snes,SNESType type) 1944 { 1945 PetscErrorCode ierr,(*r)(SNES); 1946 PetscTruth match; 1947 1948 PetscFunctionBegin; 1949 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1950 PetscValidCharPointer(type,2); 1951 1952 ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 1953 if (match) PetscFunctionReturn(0); 1954 /* Get the function pointers for the iterative method requested */ 1955 if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 1956 ierr = PetscFListFind(snes->comm,SNESList,type,(void (**)(void)) &r);CHKERRQ(ierr); 1957 if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 1958 /* Destroy the previous private SNES context */ 1959 if (snes->ops->destroy) { ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); } 1960 /* Reinitialize function pointers in SNESOps structure */ 1961 snes->ops->converged = 0; 1962 snes->ops->setup = 0; 1963 snes->ops->solve = 0; 1964 snes->ops->view = 0; 1965 snes->ops->setfromoptions = 0; 1966 snes->ops->destroy = 0; 1967 /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 1968 snes->setupcalled = PETSC_FALSE; 1969 ierr = (*r)(snes);CHKERRQ(ierr); 1970 ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 1971 PetscFunctionReturn(0); 1972 } 1973 1974 1975 /* --------------------------------------------------------------------- */ 1976 #undef __FUNCT__ 1977 #define __FUNCT__ "SNESRegisterDestroy" 1978 /*@ 1979 SNESRegisterDestroy - Frees the list of nonlinear solvers that were 1980 registered by SNESRegisterDynamic(). 1981 1982 Not Collective 1983 1984 Level: advanced 1985 1986 .keywords: SNES, nonlinear, register, destroy 1987 1988 .seealso: SNESRegisterAll(), SNESRegisterAll() 1989 @*/ 1990 PetscErrorCode PETSCSNES_DLLEXPORT SNESRegisterDestroy(void) 1991 { 1992 PetscErrorCode ierr; 1993 1994 PetscFunctionBegin; 1995 if (SNESList) { 1996 ierr = PetscFListDestroy(SNESList);CHKERRQ(ierr); 1997 SNESList = 0; 1998 } 1999 SNESRegisterAllCalled = PETSC_FALSE; 2000 PetscFunctionReturn(0); 2001 } 2002 2003 #undef __FUNCT__ 2004 #define __FUNCT__ "SNESGetType" 2005 /*@C 2006 SNESGetType - Gets the SNES method type and name (as a string). 2007 2008 Not Collective 2009 2010 Input Parameter: 2011 . snes - nonlinear solver context 2012 2013 Output Parameter: 2014 . type - SNES method (a character string) 2015 2016 Level: intermediate 2017 2018 .keywords: SNES, nonlinear, get, type, name 2019 @*/ 2020 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetType(SNES snes,SNESType *type) 2021 { 2022 PetscFunctionBegin; 2023 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2024 PetscValidPointer(type,2); 2025 *type = snes->type_name; 2026 PetscFunctionReturn(0); 2027 } 2028 2029 #undef __FUNCT__ 2030 #define __FUNCT__ "SNESGetSolution" 2031 /*@ 2032 SNESGetSolution - Returns the vector where the approximate solution is 2033 stored. 2034 2035 Not Collective, but Vec is parallel if SNES is parallel 2036 2037 Input Parameter: 2038 . snes - the SNES context 2039 2040 Output Parameter: 2041 . x - the solution 2042 2043 Level: intermediate 2044 2045 .keywords: SNES, nonlinear, get, solution 2046 2047 .seealso: SNESSetSolution(), SNESGetFunction(), SNESGetSolutionUpdate() 2048 @*/ 2049 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetSolution(SNES snes,Vec *x) 2050 { 2051 PetscFunctionBegin; 2052 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2053 PetscValidPointer(x,2); 2054 *x = snes->vec_sol_always; 2055 PetscFunctionReturn(0); 2056 } 2057 2058 #undef __FUNCT__ 2059 #define __FUNCT__ "SNESSetSolution" 2060 /*@ 2061 SNESSetSolution - Sets the vector where the approximate solution is stored. 2062 2063 Not Collective, but Vec is parallel if SNES is parallel 2064 2065 Input Parameters: 2066 + snes - the SNES context 2067 - x - the solution 2068 2069 Output Parameter: 2070 2071 Level: intermediate 2072 2073 Notes: this is not normally used, rather one simply calls SNESSolve() with 2074 the appropriate solution vector. 2075 2076 .keywords: SNES, nonlinear, set, solution 2077 2078 .seealso: SNESGetSolution(), SNESGetFunction(), SNESGetSolutionUpdate() 2079 @*/ 2080 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetSolution(SNES snes,Vec x) 2081 { 2082 PetscFunctionBegin; 2083 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2084 PetscValidHeaderSpecific(x,VEC_COOKIE,2); 2085 PetscCheckSameComm(snes,1,x,2); 2086 snes->vec_sol_always = x; 2087 PetscFunctionReturn(0); 2088 } 2089 2090 #undef __FUNCT__ 2091 #define __FUNCT__ "SNESGetSolutionUpdate" 2092 /*@ 2093 SNESGetSolutionUpdate - Returns the vector where the solution update is 2094 stored. 2095 2096 Not Collective, but Vec is parallel if SNES is parallel 2097 2098 Input Parameter: 2099 . snes - the SNES context 2100 2101 Output Parameter: 2102 . x - the solution update 2103 2104 Level: advanced 2105 2106 .keywords: SNES, nonlinear, get, solution, update 2107 2108 .seealso: SNESGetSolution(), SNESGetFunction 2109 @*/ 2110 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetSolutionUpdate(SNES snes,Vec *x) 2111 { 2112 PetscFunctionBegin; 2113 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2114 PetscValidPointer(x,2); 2115 *x = snes->vec_sol_update_always; 2116 PetscFunctionReturn(0); 2117 } 2118 2119 #undef __FUNCT__ 2120 #define __FUNCT__ "SNESGetFunction" 2121 /*@C 2122 SNESGetFunction - Returns the vector where the function is stored. 2123 2124 Not Collective, but Vec is parallel if SNES is parallel 2125 2126 Input Parameter: 2127 . snes - the SNES context 2128 2129 Output Parameter: 2130 + r - the function (or PETSC_NULL) 2131 . func - the function (or PETSC_NULL) 2132 - ctx - the function context (or PETSC_NULL) 2133 2134 Level: advanced 2135 2136 .keywords: SNES, nonlinear, get, function 2137 2138 .seealso: SNESSetFunction(), SNESGetSolution() 2139 @*/ 2140 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 2141 { 2142 PetscFunctionBegin; 2143 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2144 if (r) *r = snes->vec_func_always; 2145 if (func) *func = snes->ops->computefunction; 2146 if (ctx) *ctx = snes->funP; 2147 PetscFunctionReturn(0); 2148 } 2149 2150 #undef __FUNCT__ 2151 #define __FUNCT__ "SNESSetOptionsPrefix" 2152 /*@C 2153 SNESSetOptionsPrefix - Sets the prefix used for searching for all 2154 SNES options in the database. 2155 2156 Collective on SNES 2157 2158 Input Parameter: 2159 + snes - the SNES context 2160 - prefix - the prefix to prepend to all option names 2161 2162 Notes: 2163 A hyphen (-) must NOT be given at the beginning of the prefix name. 2164 The first character of all runtime options is AUTOMATICALLY the hyphen. 2165 2166 Level: advanced 2167 2168 .keywords: SNES, set, options, prefix, database 2169 2170 .seealso: SNESSetFromOptions() 2171 @*/ 2172 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetOptionsPrefix(SNES snes,const char prefix[]) 2173 { 2174 PetscErrorCode ierr; 2175 2176 PetscFunctionBegin; 2177 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2178 ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2179 ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 2180 PetscFunctionReturn(0); 2181 } 2182 2183 #undef __FUNCT__ 2184 #define __FUNCT__ "SNESAppendOptionsPrefix" 2185 /*@C 2186 SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 2187 SNES options in the database. 2188 2189 Collective on SNES 2190 2191 Input Parameters: 2192 + snes - the SNES context 2193 - prefix - the prefix to prepend to all option names 2194 2195 Notes: 2196 A hyphen (-) must NOT be given at the beginning of the prefix name. 2197 The first character of all runtime options is AUTOMATICALLY the hyphen. 2198 2199 Level: advanced 2200 2201 .keywords: SNES, append, options, prefix, database 2202 2203 .seealso: SNESGetOptionsPrefix() 2204 @*/ 2205 PetscErrorCode PETSCSNES_DLLEXPORT SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 2206 { 2207 PetscErrorCode ierr; 2208 2209 PetscFunctionBegin; 2210 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2211 ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2212 ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 2213 PetscFunctionReturn(0); 2214 } 2215 2216 #undef __FUNCT__ 2217 #define __FUNCT__ "SNESGetOptionsPrefix" 2218 /*@C 2219 SNESGetOptionsPrefix - Sets the prefix used for searching for all 2220 SNES options in the database. 2221 2222 Not Collective 2223 2224 Input Parameter: 2225 . snes - the SNES context 2226 2227 Output Parameter: 2228 . prefix - pointer to the prefix string used 2229 2230 Notes: On the fortran side, the user should pass in a string 'prifix' of 2231 sufficient length to hold the prefix. 2232 2233 Level: advanced 2234 2235 .keywords: SNES, get, options, prefix, database 2236 2237 .seealso: SNESAppendOptionsPrefix() 2238 @*/ 2239 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 2240 { 2241 PetscErrorCode ierr; 2242 2243 PetscFunctionBegin; 2244 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2245 ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2246 PetscFunctionReturn(0); 2247 } 2248 2249 2250 #undef __FUNCT__ 2251 #define __FUNCT__ "SNESRegister" 2252 /*@C 2253 SNESRegister - See SNESRegisterDynamic() 2254 2255 Level: advanced 2256 @*/ 2257 PetscErrorCode PETSCSNES_DLLEXPORT SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 2258 { 2259 char fullname[PETSC_MAX_PATH_LEN]; 2260 PetscErrorCode ierr; 2261 2262 PetscFunctionBegin; 2263 ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 2264 ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 2265 PetscFunctionReturn(0); 2266 } 2267 2268 #undef __FUNCT__ 2269 #define __FUNCT__ "SNESTestLocalMin" 2270 PetscErrorCode PETSCSNES_DLLEXPORT SNESTestLocalMin(SNES snes) 2271 { 2272 PetscErrorCode ierr; 2273 PetscInt N,i,j; 2274 Vec u,uh,fh; 2275 PetscScalar value; 2276 PetscReal norm; 2277 2278 PetscFunctionBegin; 2279 ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 2280 ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 2281 ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 2282 2283 /* currently only works for sequential */ 2284 ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 2285 ierr = VecGetSize(u,&N);CHKERRQ(ierr); 2286 for (i=0; i<N; i++) { 2287 ierr = VecCopy(u,uh);CHKERRQ(ierr); 2288 ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 2289 for (j=-10; j<11; j++) { 2290 value = PetscSign(j)*exp(PetscAbs(j)-10.0); 2291 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 2292 ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 2293 ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 2294 ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 2295 value = -value; 2296 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 2297 } 2298 } 2299 ierr = VecDestroy(uh);CHKERRQ(ierr); 2300 ierr = VecDestroy(fh);CHKERRQ(ierr); 2301 PetscFunctionReturn(0); 2302 } 2303 2304 #undef __FUNCT__ 2305 #define __FUNCT__ "SNES_KSP_SetUseEW" 2306 /*@ 2307 SNES_KSP_SetUseEW - Sets SNES use Eisenstat-Walker method for 2308 computing relative tolerance for linear solvers within an inexact 2309 Newton method. 2310 2311 Collective on SNES 2312 2313 Input Parameters: 2314 + snes - SNES context 2315 - flag - PETSC_TRUE or PETSC_FALSE 2316 2317 Notes: 2318 Currently, the default is to use a constant relative tolerance for 2319 the inner linear solvers. Alternatively, one can use the 2320 Eisenstat-Walker method, where the relative convergence tolerance 2321 is reset at each Newton iteration according progress of the nonlinear 2322 solver. 2323 2324 Level: advanced 2325 2326 Reference: 2327 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 2328 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 2329 2330 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 2331 2332 .seealso: SNES_KSP_GetUseEW(), SNES_KSP_GetParametersEW(), SNES_KSP_SetParametersEW() 2333 @*/ 2334 PetscErrorCode PETSCSNES_DLLEXPORT SNES_KSP_SetUseEW(SNES snes,PetscTruth flag) 2335 { 2336 PetscFunctionBegin; 2337 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2338 snes->ksp_ewconv = flag; 2339 PetscFunctionReturn(0); 2340 } 2341 2342 #undef __FUNCT__ 2343 #define __FUNCT__ "SNES_KSP_GetUseEW" 2344 /*@ 2345 SNES_KSP_GetUseEW - Gets if SNES is using Eisenstat-Walker method 2346 for computing relative tolerance for linear solvers within an 2347 inexact Newton method. 2348 2349 Not Collective 2350 2351 Input Parameter: 2352 . snes - SNES context 2353 2354 Output Parameter: 2355 . flag - PETSC_TRUE or PETSC_FALSE 2356 2357 Notes: 2358 Currently, the default is to use a constant relative tolerance for 2359 the inner linear solvers. Alternatively, one can use the 2360 Eisenstat-Walker method, where the relative convergence tolerance 2361 is reset at each Newton iteration according progress of the nonlinear 2362 solver. 2363 2364 Level: advanced 2365 2366 Reference: 2367 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 2368 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 2369 2370 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 2371 2372 .seealso: SNES_KSP_SetUseEW(), SNES_KSP_GetParametersEW(), SNES_KSP_SetParametersEW() 2373 @*/ 2374 PetscErrorCode PETSCSNES_DLLEXPORT SNES_KSP_GetUseEW(SNES snes, PetscTruth *flag) 2375 { 2376 PetscFunctionBegin; 2377 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2378 PetscValidPointer(flag,2); 2379 *flag = snes->ksp_ewconv; 2380 PetscFunctionReturn(0); 2381 } 2382 2383 #undef __FUNCT__ 2384 #define __FUNCT__ "SNES_KSP_SetParametersEW" 2385 /*@ 2386 SNES_KSP_SetParametersEW - Sets parameters for Eisenstat-Walker 2387 convergence criteria for the linear solvers within an inexact 2388 Newton method. 2389 2390 Collective on SNES 2391 2392 Input Parameters: 2393 + snes - SNES context 2394 . version - version 1, 2 (default is 2) or 3 2395 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 2396 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 2397 . gamma - multiplicative factor for version 2 rtol computation 2398 (0 <= gamma2 <= 1) 2399 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 2400 . alpha2 - power for safeguard 2401 - threshold - threshold for imposing safeguard (0 < threshold < 1) 2402 2403 Note: 2404 Version 3 was contributed by Luis Chacon, June 2006. 2405 2406 Use PETSC_DEFAULT to retain the default for any of the parameters. 2407 2408 Level: advanced 2409 2410 Reference: 2411 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 2412 inexact Newton method", Utah State University Math. Stat. Dept. Res. 2413 Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 2414 2415 .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 2416 2417 .seealso: SNES_KSP_SetUseEW(), SNES_KSP_GetUseEW(), SNES_KSP_GetParametersEW() 2418 @*/ 2419 PetscErrorCode PETSCSNES_DLLEXPORT SNES_KSP_SetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 2420 PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 2421 { 2422 SNES_KSP_EW_ConvCtx *kctx; 2423 PetscFunctionBegin; 2424 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2425 kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 2426 if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 2427 2428 if (version != PETSC_DEFAULT) kctx->version = version; 2429 if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 2430 if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 2431 if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 2432 if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 2433 if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 2434 if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 2435 2436 if (kctx->version < 1 || kctx->version > 3) { 2437 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 2438 } 2439 if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 2440 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 2441 } 2442 if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 2443 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 2444 } 2445 if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 2446 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 2447 } 2448 if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 2449 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 2450 } 2451 if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 2452 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 2453 } 2454 PetscFunctionReturn(0); 2455 } 2456 2457 #undef __FUNCT__ 2458 #define __FUNCT__ "SNES_KSP_GetParametersEW" 2459 /*@ 2460 SNES_KSP_GetParametersEW - Gets parameters for Eisenstat-Walker 2461 convergence criteria for the linear solvers within an inexact 2462 Newton method. 2463 2464 Not Collective 2465 2466 Input Parameters: 2467 snes - SNES context 2468 2469 Output Parameters: 2470 + version - version 1, 2 (default is 2) or 3 2471 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 2472 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 2473 . gamma - multiplicative factor for version 2 rtol computation 2474 (0 <= gamma2 <= 1) 2475 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 2476 . alpha2 - power for safeguard 2477 - threshold - threshold for imposing safeguard (0 < threshold < 1) 2478 2479 Level: advanced 2480 2481 .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 2482 2483 .seealso: SNES_KSP_SetUseEW(), SNES_KSP_GetUseEW(), SNES_KSP_SetParametersEW() 2484 @*/ 2485 PetscErrorCode PETSCSNES_DLLEXPORT SNES_KSP_GetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 2486 PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 2487 { 2488 SNES_KSP_EW_ConvCtx *kctx; 2489 PetscFunctionBegin; 2490 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2491 kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 2492 if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 2493 if(version) *version = kctx->version; 2494 if(rtol_0) *rtol_0 = kctx->rtol_0; 2495 if(rtol_max) *rtol_max = kctx->rtol_max; 2496 if(gamma) *gamma = kctx->gamma; 2497 if(alpha) *alpha = kctx->alpha; 2498 if(alpha2) *alpha2 = kctx->alpha2; 2499 if(threshold) *threshold = kctx->threshold; 2500 PetscFunctionReturn(0); 2501 } 2502 2503 #undef __FUNCT__ 2504 #define __FUNCT__ "SNES_KSP_EW_PreSolve" 2505 static PetscErrorCode SNES_KSP_EW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 2506 { 2507 PetscErrorCode ierr; 2508 SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 2509 PetscReal rtol=PETSC_DEFAULT,stol; 2510 2511 PetscFunctionBegin; 2512 if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 2513 if (!snes->iter) { /* first time in, so use the original user rtol */ 2514 rtol = kctx->rtol_0; 2515 } else { 2516 if (kctx->version == 1) { 2517 rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 2518 if (rtol < 0.0) rtol = -rtol; 2519 stol = pow(kctx->rtol_last,kctx->alpha2); 2520 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 2521 } else if (kctx->version == 2) { 2522 rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 2523 stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 2524 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 2525 } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 2526 rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 2527 /* safeguard: avoid sharp decrease of rtol */ 2528 stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 2529 stol = PetscMax(rtol,stol); 2530 rtol = PetscMin(kctx->rtol_0,stol); 2531 /* safeguard: avoid oversolving */ 2532 stol = kctx->gamma*(snes->ttol)/snes->norm; 2533 stol = PetscMax(rtol,stol); 2534 rtol = PetscMin(kctx->rtol_0,stol); 2535 } else SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 2536 } 2537 /* safeguard: avoid rtol greater than one */ 2538 rtol = PetscMin(rtol,kctx->rtol_max); 2539 ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 2540 ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 2541 PetscFunctionReturn(0); 2542 } 2543 2544 #undef __FUNCT__ 2545 #define __FUNCT__ "SNES_KSP_EW_PostSolve" 2546 static PetscErrorCode SNES_KSP_EW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 2547 { 2548 PetscErrorCode ierr; 2549 SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 2550 PCSide pcside; 2551 Vec lres; 2552 2553 PetscFunctionBegin; 2554 if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 2555 ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 2556 ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 2557 if (kctx->version == 1) { 2558 ierr = KSPGetPreconditionerSide(ksp,&pcside);CHKERRQ(ierr); 2559 if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 2560 /* KSP residual is true linear residual */ 2561 ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 2562 } else { 2563 /* KSP residual is preconditioned residual */ 2564 /* compute true linear residual norm */ 2565 ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 2566 ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 2567 ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 2568 ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 2569 ierr = VecDestroy(lres);CHKERRQ(ierr); 2570 } 2571 } 2572 PetscFunctionReturn(0); 2573 } 2574 2575 #undef __FUNCT__ 2576 #define __FUNCT__ "SNES_KSPSolve" 2577 PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 2578 { 2579 PetscErrorCode ierr; 2580 2581 PetscFunctionBegin; 2582 if (snes->ksp_ewconv) { ierr = SNES_KSP_EW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 2583 ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 2584 if (snes->ksp_ewconv) { ierr = SNES_KSP_EW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 2585 PetscFunctionReturn(0); 2586 } 2587