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