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