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