1 #define PETSCSNES_DLL 2 3 #include "include/private/snesimpl.h" /*I "petscsnes.h" I*/ 4 5 PetscTruth SNESRegisterAllCalled = PETSC_FALSE; 6 PetscFList SNESList = PETSC_NULL; 7 8 /* Logging support */ 9 PetscCookie PETSCSNES_DLLEXPORT SNES_COOKIE = 0; 10 PetscEvent SNES_Solve = 0, SNES_LineSearch = 0, SNES_FunctionEval = 0, SNES_JacobianEval = 0; 11 12 #undef __FUNCT__ 13 #define __FUNCT__ "SNESView" 14 /*@C 15 SNESView - Prints the SNES data structure. 16 17 Collective on SNES 18 19 Input Parameters: 20 + SNES - the SNES context 21 - viewer - visualization context 22 23 Options Database Key: 24 . -snes_view - Calls SNESView() at end of SNESSolve() 25 26 Notes: 27 The available visualization contexts include 28 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 29 - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 30 output where only the first processor opens 31 the file. All other processors send their 32 data to the first processor to print. 33 34 The user can open an alternative visualization context with 35 PetscViewerASCIIOpen() - output to a specified file. 36 37 Level: beginner 38 39 .keywords: SNES, view 40 41 .seealso: PetscViewerASCIIOpen() 42 @*/ 43 PetscErrorCode PETSCSNES_DLLEXPORT SNESView(SNES snes,PetscViewer viewer) 44 { 45 SNES_KSP_EW_ConvCtx *kctx; 46 PetscErrorCode ierr; 47 KSP ksp; 48 SNESType type; 49 PetscTruth iascii,isstring; 50 51 PetscFunctionBegin; 52 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 53 if (!viewer) { 54 ierr = PetscViewerASCIIGetStdout(snes->comm,&viewer);CHKERRQ(ierr); 55 } 56 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,2); 57 PetscCheckSameComm(snes,1,viewer,2); 58 59 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 60 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);CHKERRQ(ierr); 61 if (iascii) { 62 if (snes->prefix) { 63 ierr = PetscViewerASCIIPrintf(viewer,"SNES Object:(%s)\n",snes->prefix);CHKERRQ(ierr); 64 } else { 65 ierr = PetscViewerASCIIPrintf(viewer,"SNES Object:\n");CHKERRQ(ierr); 66 } 67 ierr = SNESGetType(snes,&type);CHKERRQ(ierr); 68 if (type) { 69 ierr = PetscViewerASCIIPrintf(viewer," type: %s\n",type);CHKERRQ(ierr); 70 } else { 71 ierr = PetscViewerASCIIPrintf(viewer," type: not set yet\n");CHKERRQ(ierr); 72 } 73 if (snes->ops->view) { 74 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 75 ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 76 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 77 } 78 ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr); 79 ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%G, absolute=%G, solution=%G\n", 80 snes->rtol,snes->abstol,snes->xtol);CHKERRQ(ierr); 81 ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr); 82 ierr = PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr); 83 if (snes->ksp_ewconv) { 84 kctx = (SNES_KSP_EW_ConvCtx *)snes->kspconvctx; 85 if (kctx) { 86 ierr = PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr); 87 ierr = PetscViewerASCIIPrintf(viewer," rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr); 88 ierr = PetscViewerASCIIPrintf(viewer," gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr); 89 } 90 } 91 } else if (isstring) { 92 ierr = SNESGetType(snes,&type);CHKERRQ(ierr); 93 ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr); 94 } 95 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 96 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 97 ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 98 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 99 PetscFunctionReturn(0); 100 } 101 102 /* 103 We retain a list of functions that also take SNES command 104 line options. These are called at the end SNESSetFromOptions() 105 */ 106 #define MAXSETFROMOPTIONS 5 107 static PetscInt numberofsetfromoptions; 108 static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 109 110 #undef __FUNCT__ 111 #define __FUNCT__ "SNESAddOptionsChecker" 112 /*@C 113 SNESAddOptionsChecker - Adds an additional function to check for SNES options. 114 115 Not Collective 116 117 Input Parameter: 118 . snescheck - function that checks for options 119 120 Level: developer 121 122 .seealso: SNESSetFromOptions() 123 @*/ 124 PetscErrorCode PETSCSNES_DLLEXPORT SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 125 { 126 PetscFunctionBegin; 127 if (numberofsetfromoptions >= MAXSETFROMOPTIONS) { 128 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS); 129 } 130 othersetfromoptions[numberofsetfromoptions++] = snescheck; 131 PetscFunctionReturn(0); 132 } 133 134 #undef __FUNCT__ 135 #define __FUNCT__ "SNESSetFromOptions" 136 /*@ 137 SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 138 139 Collective on SNES 140 141 Input Parameter: 142 . snes - the SNES context 143 144 Options Database Keys: 145 + -snes_type <type> - ls, tr, umls, umtr, test 146 . -snes_stol - convergence tolerance in terms of the norm 147 of the change in the solution between steps 148 . -snes_atol <abstol> - absolute tolerance of residual norm 149 . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 150 . -snes_max_it <max_it> - maximum number of iterations 151 . -snes_max_funcs <max_funcs> - maximum number of function evaluations 152 . -snes_max_fail <max_fail> - maximum number of failures 153 . -snes_trtol <trtol> - trust region tolerance 154 . -snes_no_convergence_test - skip convergence test in nonlinear 155 solver; hence iterations will continue until max_it 156 or some other criterion is reached. Saves expense 157 of convergence test 158 . -snes_monitor <optional filename> - prints residual norm at each iteration. if no 159 filename given prints to stdout 160 . -snes_monitor_solution - plots solution at each iteration 161 . -snes_monitor_residual - plots residual (not its norm) at each iteration 162 . -snes_monitor_solution_update - plots update to solution at each iteration 163 . -snes_monitor_draw - plots residual norm at each iteration 164 . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 165 . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 166 - -snes_converged_reason - print the reason for convergence/divergence after each solve 167 168 Options Database for Eisenstat-Walker method: 169 + -snes_ksp_ew_conv - use Eisenstat-Walker method for determining linear system convergence 170 . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 171 . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 172 . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 173 . -snes_ksp_ew_gamma <gamma> - Sets gamma 174 . -snes_ksp_ew_alpha <alpha> - Sets alpha 175 . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 176 - -snes_ksp_ew_threshold <threshold> - Sets threshold 177 178 Notes: 179 To see all options, run your program with the -help option or consult 180 the users manual. 181 182 Level: beginner 183 184 .keywords: SNES, nonlinear, set, options, database 185 186 .seealso: SNESSetOptionsPrefix() 187 @*/ 188 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetFromOptions(SNES snes) 189 { 190 KSP ksp; 191 SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx *)snes->kspconvctx; 192 PetscTruth flg; 193 PetscErrorCode ierr; 194 PetscInt i; 195 const char *deft; 196 char type[256], monfilename[PETSC_MAX_PATH_LEN]; 197 PetscViewerASCIIMonitor monviewer; 198 199 PetscFunctionBegin; 200 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 201 202 ierr = PetscOptionsBegin(snes->comm,snes->prefix,"Nonlinear solver (SNES) options","SNES");CHKERRQ(ierr); 203 if (snes->type_name) { 204 deft = snes->type_name; 205 } else { 206 deft = SNESLS; 207 } 208 209 if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 210 ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 211 if (flg) { 212 ierr = SNESSetType(snes,type);CHKERRQ(ierr); 213 } else if (!snes->type_name) { 214 ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 215 } 216 ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr); 217 218 ierr = PetscOptionsReal("-snes_stol","Stop if step length less then","SNESSetTolerances",snes->xtol,&snes->xtol,0);CHKERRQ(ierr); 219 ierr = PetscOptionsReal("-snes_atol","Stop if function norm less then","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr); 220 221 ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less then","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr); 222 ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr); 223 ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr); 224 ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr); 225 ierr = PetscOptionsName("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",&flg);CHKERRQ(ierr); 226 if (flg) { 227 snes->printreason = PETSC_TRUE; 228 } 229 230 ierr = PetscOptionsTruth("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNES_KSP_SetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 231 ierr = PetscOptionsTruth("-snes_ksp_ew_conv","Use Eisentat-Walker linear system convergence test","SNES_KSP_SetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 232 233 ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNES_KSP_SetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr); 234 ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNES_KSP_SetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr); 235 ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNES_KSP_SetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr); 236 ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNES_KSP_SetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr); 237 ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNES_KSP_SetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr); 238 ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNES_KSP_SetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr); 239 ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNES_KSP_SetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr); 240 241 ierr = PetscOptionsName("-snes_no_convergence_test","Don't test for convergence","None",&flg);CHKERRQ(ierr); 242 if (flg) {snes->ops->converged = 0;} 243 ierr = PetscOptionsName("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",&flg);CHKERRQ(ierr); 244 if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 245 246 ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 247 if (flg) { 248 ierr = PetscViewerASCIIMonitorCreate(snes->comm,monfilename,0,&monviewer);CHKERRQ(ierr); 249 ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);CHKERRQ(ierr); 250 } 251 252 ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 253 if (flg) { 254 ierr = PetscViewerASCIIMonitorCreate(snes->comm,monfilename,0,&monviewer);CHKERRQ(ierr); 255 ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 256 } 257 258 ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 259 if (flg) { 260 ierr = PetscViewerASCIIMonitorCreate(snes->comm,monfilename,0,&monviewer);CHKERRQ(ierr); 261 ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);CHKERRQ(ierr); 262 } 263 264 ierr = PetscOptionsName("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",&flg);CHKERRQ(ierr); 265 if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 266 ierr = PetscOptionsName("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",&flg);CHKERRQ(ierr); 267 if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 268 ierr = PetscOptionsName("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",&flg);CHKERRQ(ierr); 269 if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 270 ierr = PetscOptionsName("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",&flg);CHKERRQ(ierr); 271 if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 272 273 ierr = PetscOptionsName("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",&flg);CHKERRQ(ierr); 274 if (flg) { 275 ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);CHKERRQ(ierr); 276 ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 277 } 278 279 for(i = 0; i < numberofsetfromoptions; i++) { 280 ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 281 } 282 283 if (snes->ops->setfromoptions) { 284 ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 285 } 286 ierr = PetscOptionsEnd();CHKERRQ(ierr); 287 288 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 289 ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); 290 291 PetscFunctionReturn(0); 292 } 293 294 295 #undef __FUNCT__ 296 #define __FUNCT__ "SNESSetApplicationContext" 297 /*@ 298 SNESSetApplicationContext - Sets the optional user-defined context for 299 the nonlinear solvers. 300 301 Collective on SNES 302 303 Input Parameters: 304 + snes - the SNES context 305 - usrP - optional user context 306 307 Level: intermediate 308 309 .keywords: SNES, nonlinear, set, application, context 310 311 .seealso: SNESGetApplicationContext() 312 @*/ 313 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetApplicationContext(SNES snes,void *usrP) 314 { 315 PetscFunctionBegin; 316 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 317 snes->user = usrP; 318 PetscFunctionReturn(0); 319 } 320 321 #undef __FUNCT__ 322 #define __FUNCT__ "SNESGetApplicationContext" 323 /*@C 324 SNESGetApplicationContext - Gets the user-defined context for the 325 nonlinear solvers. 326 327 Not Collective 328 329 Input Parameter: 330 . snes - SNES context 331 332 Output Parameter: 333 . usrP - user context 334 335 Level: intermediate 336 337 .keywords: SNES, nonlinear, get, application, context 338 339 .seealso: SNESSetApplicationContext() 340 @*/ 341 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetApplicationContext(SNES snes,void **usrP) 342 { 343 PetscFunctionBegin; 344 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 345 *usrP = snes->user; 346 PetscFunctionReturn(0); 347 } 348 349 #undef __FUNCT__ 350 #define __FUNCT__ "SNESGetIterationNumber" 351 /*@ 352 SNESGetIterationNumber - Gets the number of nonlinear iterations completed 353 at this time. 354 355 Not Collective 356 357 Input Parameter: 358 . snes - SNES context 359 360 Output Parameter: 361 . iter - iteration number 362 363 Notes: 364 For example, during the computation of iteration 2 this would return 1. 365 366 This is useful for using lagged Jacobians (where one does not recompute the 367 Jacobian at each SNES iteration). For example, the code 368 .vb 369 ierr = SNESGetIterationNumber(snes,&it); 370 if (!(it % 2)) { 371 [compute Jacobian here] 372 } 373 .ve 374 can be used in your ComputeJacobian() function to cause the Jacobian to be 375 recomputed every second SNES iteration. 376 377 Level: intermediate 378 379 .keywords: SNES, nonlinear, get, iteration, number, 380 381 .seealso: SNESGetFunctionNorm(), SNESGetNumberLinearIterations() 382 @*/ 383 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetIterationNumber(SNES snes,PetscInt* iter) 384 { 385 PetscFunctionBegin; 386 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 387 PetscValidIntPointer(iter,2); 388 *iter = snes->iter; 389 PetscFunctionReturn(0); 390 } 391 392 #undef __FUNCT__ 393 #define __FUNCT__ "SNESGetFunctionNorm" 394 /*@ 395 SNESGetFunctionNorm - Gets the norm of the current function that was set 396 with SNESSSetFunction(). 397 398 Collective on SNES 399 400 Input Parameter: 401 . snes - SNES context 402 403 Output Parameter: 404 . fnorm - 2-norm of function 405 406 Level: intermediate 407 408 .keywords: SNES, nonlinear, get, function, norm 409 410 .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetNumberLinearIterations() 411 @*/ 412 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 413 { 414 PetscFunctionBegin; 415 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 416 PetscValidScalarPointer(fnorm,2); 417 *fnorm = snes->norm; 418 PetscFunctionReturn(0); 419 } 420 421 #undef __FUNCT__ 422 #define __FUNCT__ "SNESGetNumberUnsuccessfulSteps" 423 /*@ 424 SNESGetNumberUnsuccessfulSteps - Gets the number of unsuccessful steps 425 attempted by the nonlinear solver. 426 427 Not Collective 428 429 Input Parameter: 430 . snes - SNES context 431 432 Output Parameter: 433 . nfails - number of unsuccessful steps attempted 434 435 Notes: 436 This counter is reset to zero for each successive call to SNESSolve(). 437 438 Level: intermediate 439 440 .keywords: SNES, nonlinear, get, number, unsuccessful, steps 441 @*/ 442 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetNumberUnsuccessfulSteps(SNES snes,PetscInt* nfails) 443 { 444 PetscFunctionBegin; 445 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 446 PetscValidIntPointer(nfails,2); 447 *nfails = snes->numFailures; 448 PetscFunctionReturn(0); 449 } 450 451 #undef __FUNCT__ 452 #define __FUNCT__ "SNESSetMaximumUnsuccessfulSteps" 453 /*@ 454 SNESSetMaximumUnsuccessfulSteps - Sets the maximum number of unsuccessful steps 455 attempted by the nonlinear solver before it gives up. 456 457 Not Collective 458 459 Input Parameters: 460 + snes - SNES context 461 - maxFails - maximum of unsuccessful steps 462 463 Level: intermediate 464 465 .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 466 @*/ 467 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetMaximumUnsuccessfulSteps(SNES snes, PetscInt maxFails) 468 { 469 PetscFunctionBegin; 470 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 471 snes->maxFailures = maxFails; 472 PetscFunctionReturn(0); 473 } 474 475 #undef __FUNCT__ 476 #define __FUNCT__ "SNESGetMaximumUnsuccessfulSteps" 477 /*@ 478 SNESGetMaximumUnsuccessfulSteps - Gets the maximum number of unsuccessful steps 479 attempted by the nonlinear solver before it gives up. 480 481 Not Collective 482 483 Input Parameter: 484 . snes - SNES context 485 486 Output Parameter: 487 . maxFails - maximum of unsuccessful steps 488 489 Level: intermediate 490 491 .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 492 @*/ 493 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetMaximumUnsuccessfulSteps(SNES snes, PetscInt *maxFails) 494 { 495 PetscFunctionBegin; 496 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 497 PetscValidIntPointer(maxFails,2); 498 *maxFails = snes->maxFailures; 499 PetscFunctionReturn(0); 500 } 501 502 #undef __FUNCT__ 503 #define __FUNCT__ "SNESGetLinearSolveFailures" 504 /*@ 505 SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 506 linear solvers. 507 508 Not Collective 509 510 Input Parameter: 511 . snes - SNES context 512 513 Output Parameter: 514 . nfails - number of failed solves 515 516 Notes: 517 This counter is reset to zero for each successive call to SNESSolve(). 518 519 Level: intermediate 520 521 .keywords: SNES, nonlinear, get, number, unsuccessful, steps 522 @*/ 523 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 524 { 525 PetscFunctionBegin; 526 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 527 PetscValidIntPointer(nfails,2); 528 *nfails = snes->numLinearSolveFailures; 529 PetscFunctionReturn(0); 530 } 531 532 #undef __FUNCT__ 533 #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 534 /*@ 535 SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 536 allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 537 538 Collective on SNES 539 540 Input Parameters: 541 + snes - SNES context 542 - maxFails - maximum allowed linear solve failures 543 544 Level: intermediate 545 546 Notes: By default this is 1; that is SNES returns on the first failed linear solve 547 548 .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 549 550 .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 551 @*/ 552 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 553 { 554 PetscFunctionBegin; 555 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 556 snes->maxLinearSolveFailures = maxFails; 557 PetscFunctionReturn(0); 558 } 559 560 #undef __FUNCT__ 561 #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 562 /*@ 563 SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 564 are allowed before SNES terminates 565 566 Not Collective 567 568 Input Parameter: 569 . snes - SNES context 570 571 Output Parameter: 572 . maxFails - maximum of unsuccessful solves allowed 573 574 Level: intermediate 575 576 Notes: By default this is 1; that is SNES returns on the first failed linear solve 577 578 .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 579 580 .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 581 @*/ 582 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 583 { 584 PetscFunctionBegin; 585 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 586 PetscValidIntPointer(maxFails,2); 587 *maxFails = snes->maxLinearSolveFailures; 588 PetscFunctionReturn(0); 589 } 590 591 #undef __FUNCT__ 592 #define __FUNCT__ "SNESGetNumberLinearIterations" 593 /*@ 594 SNESGetNumberLinearIterations - Gets the total number of linear iterations 595 used by the nonlinear solver. 596 597 Not Collective 598 599 Input Parameter: 600 . snes - SNES context 601 602 Output Parameter: 603 . lits - number of linear iterations 604 605 Notes: 606 This counter is reset to zero for each successive call to SNESSolve(). 607 608 Level: intermediate 609 610 .keywords: SNES, nonlinear, get, number, linear, iterations 611 612 .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm() 613 @*/ 614 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetNumberLinearIterations(SNES snes,PetscInt* lits) 615 { 616 PetscFunctionBegin; 617 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 618 PetscValidIntPointer(lits,2); 619 *lits = snes->linear_its; 620 PetscFunctionReturn(0); 621 } 622 623 #undef __FUNCT__ 624 #define __FUNCT__ "SNESGetKSP" 625 /*@ 626 SNESGetKSP - Returns the KSP context for a SNES solver. 627 628 Not Collective, but if SNES object is parallel, then KSP object is parallel 629 630 Input Parameter: 631 . snes - the SNES context 632 633 Output Parameter: 634 . ksp - the KSP context 635 636 Notes: 637 The user can then directly manipulate the KSP context to set various 638 options, etc. Likewise, the user can then extract and manipulate the 639 PC contexts as well. 640 641 Level: beginner 642 643 .keywords: SNES, nonlinear, get, KSP, context 644 645 .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 646 @*/ 647 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetKSP(SNES snes,KSP *ksp) 648 { 649 PetscFunctionBegin; 650 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 651 PetscValidPointer(ksp,2); 652 *ksp = snes->ksp; 653 PetscFunctionReturn(0); 654 } 655 656 #undef __FUNCT__ 657 #define __FUNCT__ "SNESSetKSP" 658 /*@ 659 SNESSetKSP - Sets a KSP context for the SNES object to use 660 661 Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 662 663 Input Parameters: 664 + snes - the SNES context 665 - ksp - the KSP context 666 667 Notes: 668 The SNES object already has its KSP object, you can obtain with SNESGetKSP() 669 so this routine is rarely needed. 670 671 The KSP object that is already in the SNES object has its reference count 672 decreased by one. 673 674 Level: developer 675 676 .keywords: SNES, nonlinear, get, KSP, context 677 678 .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 679 @*/ 680 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetKSP(SNES snes,KSP ksp) 681 { 682 PetscErrorCode ierr; 683 684 PetscFunctionBegin; 685 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 686 PetscValidHeaderSpecific(ksp,KSP_COOKIE,2); 687 PetscCheckSameComm(snes,1,ksp,2); 688 ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 689 if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 690 snes->ksp = ksp; 691 PetscFunctionReturn(0); 692 } 693 694 #undef __FUNCT__ 695 #define __FUNCT__ "SNESPublish_Petsc" 696 static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 697 { 698 PetscFunctionBegin; 699 PetscFunctionReturn(0); 700 } 701 702 /* -----------------------------------------------------------*/ 703 #undef __FUNCT__ 704 #define __FUNCT__ "SNESCreate" 705 /*@ 706 SNESCreate - Creates a nonlinear solver context. 707 708 Collective on MPI_Comm 709 710 Input Parameters: 711 . comm - MPI communicator 712 713 Output Parameter: 714 . outsnes - the new SNES context 715 716 Options Database Keys: 717 + -snes_mf - Activates default matrix-free Jacobian-vector products, 718 and no preconditioning matrix 719 . -snes_mf_operator - Activates default matrix-free Jacobian-vector 720 products, and a user-provided preconditioning matrix 721 as set by SNESSetJacobian() 722 - -snes_fd - Uses (slow!) finite differences to compute Jacobian 723 724 Level: beginner 725 726 .keywords: SNES, nonlinear, create, context 727 728 .seealso: SNESSolve(), SNESDestroy(), SNES 729 @*/ 730 PetscErrorCode PETSCSNES_DLLEXPORT SNESCreate(MPI_Comm comm,SNES *outsnes) 731 { 732 PetscErrorCode ierr; 733 SNES snes; 734 SNES_KSP_EW_ConvCtx *kctx; 735 736 PetscFunctionBegin; 737 PetscValidPointer(outsnes,2); 738 *outsnes = PETSC_NULL; 739 #ifndef PETSC_USE_DYNAMIC_LIBRARIES 740 ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 741 #endif 742 743 ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_COOKIE,0,"SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 744 snes->bops->publish = SNESPublish_Petsc; 745 snes->max_its = 50; 746 snes->max_funcs = 10000; 747 snes->norm = 0.0; 748 snes->rtol = 1.e-8; 749 snes->ttol = 0.0; 750 snes->abstol = 1.e-50; 751 snes->xtol = 1.e-8; 752 snes->deltatol = 1.e-12; 753 snes->nfuncs = 0; 754 snes->numFailures = 0; 755 snes->maxFailures = 1; 756 snes->linear_its = 0; 757 snes->numbermonitors = 0; 758 snes->data = 0; 759 snes->ops->view = 0; 760 snes->setupcalled = PETSC_FALSE; 761 snes->ksp_ewconv = PETSC_FALSE; 762 snes->vwork = 0; 763 snes->nwork = 0; 764 snes->conv_hist_len = 0; 765 snes->conv_hist_max = 0; 766 snes->conv_hist = PETSC_NULL; 767 snes->conv_hist_its = PETSC_NULL; 768 snes->conv_hist_reset = PETSC_TRUE; 769 snes->reason = SNES_CONVERGED_ITERATING; 770 771 snes->numLinearSolveFailures = 0; 772 snes->maxLinearSolveFailures = 1; 773 774 /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 775 ierr = PetscNew(SNES_KSP_EW_ConvCtx,&kctx);CHKERRQ(ierr); 776 ierr = PetscLogObjectMemory(snes,sizeof(SNES_KSP_EW_ConvCtx));CHKERRQ(ierr); 777 snes->kspconvctx = (void*)kctx; 778 kctx->version = 2; 779 kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 780 this was too large for some test cases */ 781 kctx->rtol_last = 0; 782 kctx->rtol_max = .9; 783 kctx->gamma = 1.0; 784 kctx->alpha = .5*(1.0 + sqrt(5.0)); 785 kctx->alpha2 = kctx->alpha; 786 kctx->threshold = .1; 787 kctx->lresid_last = 0; 788 kctx->norm_last = 0; 789 790 ierr = KSPCreate(comm,&snes->ksp);CHKERRQ(ierr); 791 ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 792 793 *outsnes = snes; 794 ierr = PetscPublishAll(snes);CHKERRQ(ierr); 795 PetscFunctionReturn(0); 796 } 797 798 #undef __FUNCT__ 799 #define __FUNCT__ "SNESSetFunction" 800 /*@C 801 SNESSetFunction - Sets the function evaluation routine and function 802 vector for use by the SNES routines in solving systems of nonlinear 803 equations. 804 805 Collective on SNES 806 807 Input Parameters: 808 + snes - the SNES context 809 . r - vector to store function value 810 . func - function evaluation routine 811 - ctx - [optional] user-defined context for private data for the 812 function evaluation routine (may be PETSC_NULL) 813 814 Calling sequence of func: 815 $ func (SNES snes,Vec x,Vec f,void *ctx); 816 817 . f - function vector 818 - ctx - optional user-defined function context 819 820 Notes: 821 The Newton-like methods typically solve linear systems of the form 822 $ f'(x) x = -f(x), 823 where f'(x) denotes the Jacobian matrix and f(x) is the function. 824 825 Level: beginner 826 827 .keywords: SNES, nonlinear, set, function 828 829 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 830 @*/ 831 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 832 { 833 PetscFunctionBegin; 834 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 835 PetscValidHeaderSpecific(r,VEC_COOKIE,2); 836 PetscCheckSameComm(snes,1,r,2); 837 838 snes->ops->computefunction = func; 839 snes->vec_func = snes->vec_func_always = r; 840 snes->funP = ctx; 841 PetscFunctionReturn(0); 842 } 843 844 /* --------------------------------------------------------------- */ 845 #undef __FUNCT__ 846 #define __FUNCT__ "SNESSetRhs" 847 /*@C 848 SNESSetRhs - Sets the vector for solving F(x) = rhs. If rhs is not set 849 it assumes a zero right hand side. 850 851 Collective on SNES 852 853 Input Parameters: 854 + snes - the SNES context 855 - rhs - the right hand side vector or PETSC_NULL for a zero right hand side 856 857 Level: intermediate 858 859 .keywords: SNES, nonlinear, set, function, right hand side 860 861 .seealso: SNESGetRhs(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 862 @*/ 863 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetRhs(SNES snes,Vec rhs) 864 { 865 PetscErrorCode ierr; 866 867 PetscFunctionBegin; 868 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 869 if (rhs) { 870 PetscValidHeaderSpecific(rhs,VEC_COOKIE,2); 871 PetscCheckSameComm(snes,1,rhs,2); 872 ierr = PetscObjectReference((PetscObject)rhs);CHKERRQ(ierr); 873 } 874 if (snes->afine) { 875 ierr = VecDestroy(snes->afine);CHKERRQ(ierr); 876 } 877 snes->afine = rhs; 878 PetscFunctionReturn(0); 879 } 880 881 #undef __FUNCT__ 882 #define __FUNCT__ "SNESGetRhs" 883 /*@C 884 SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 885 it assumes a zero right hand side. 886 887 Collective on SNES 888 889 Input Parameter: 890 . snes - the SNES context 891 892 Output Parameter: 893 . rhs - the right hand side vector or PETSC_NULL for a zero right hand side 894 895 Level: intermediate 896 897 .keywords: SNES, nonlinear, get, function, right hand side 898 899 .seealso: SNESSetRhs(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 900 @*/ 901 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetRhs(SNES snes,Vec *rhs) 902 { 903 PetscFunctionBegin; 904 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 905 PetscValidPointer(rhs,2); 906 *rhs = snes->afine; 907 PetscFunctionReturn(0); 908 } 909 910 #undef __FUNCT__ 911 #define __FUNCT__ "SNESComputeFunction" 912 /*@ 913 SNESComputeFunction - Calls the function that has been set with 914 SNESSetFunction(). 915 916 Collective on SNES 917 918 Input Parameters: 919 + snes - the SNES context 920 - x - input vector 921 922 Output Parameter: 923 . y - function vector, as set by SNESSetFunction() 924 925 Notes: 926 SNESComputeFunction() is typically used within nonlinear solvers 927 implementations, so most users would not generally call this routine 928 themselves. 929 930 Level: developer 931 932 .keywords: SNES, nonlinear, compute, function 933 934 .seealso: SNESSetFunction(), SNESGetFunction() 935 @*/ 936 PetscErrorCode PETSCSNES_DLLEXPORT SNESComputeFunction(SNES snes,Vec x,Vec y) 937 { 938 PetscErrorCode ierr; 939 940 PetscFunctionBegin; 941 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 942 PetscValidHeaderSpecific(x,VEC_COOKIE,2); 943 PetscValidHeaderSpecific(y,VEC_COOKIE,3); 944 PetscCheckSameComm(snes,1,x,2); 945 PetscCheckSameComm(snes,1,y,3); 946 947 ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 948 if (snes->ops->computefunction) { 949 PetscStackPush("SNES user function"); 950 CHKMEMQ; 951 ierr = (*snes->ops->computefunction)(snes,x,y,snes->funP); 952 CHKMEMQ; 953 PetscStackPop; 954 if (PetscExceptionValue(ierr)) { 955 PetscErrorCode pierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(pierr); 956 } 957 CHKERRQ(ierr); 958 } else if (snes->afine) { 959 ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 960 } else { 961 SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() before SNESComputeFunction(), likely called from SNESSolve()."); 962 } 963 if (snes->afine) { 964 ierr = VecAXPY(y,-1.0,snes->afine);CHKERRQ(ierr); 965 } 966 snes->nfuncs++; 967 ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 968 PetscFunctionReturn(0); 969 } 970 971 #undef __FUNCT__ 972 #define __FUNCT__ "SNESComputeJacobian" 973 /*@ 974 SNESComputeJacobian - Computes the Jacobian matrix that has been 975 set with SNESSetJacobian(). 976 977 Collective on SNES and Mat 978 979 Input Parameters: 980 + snes - the SNES context 981 - x - input vector 982 983 Output Parameters: 984 + A - Jacobian matrix 985 . B - optional preconditioning matrix 986 - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 987 988 Notes: 989 Most users should not need to explicitly call this routine, as it 990 is used internally within the nonlinear solvers. 991 992 See KSPSetOperators() for important information about setting the 993 flag parameter. 994 995 Level: developer 996 997 .keywords: SNES, compute, Jacobian, matrix 998 999 .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure 1000 @*/ 1001 PetscErrorCode PETSCSNES_DLLEXPORT SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 1002 { 1003 PetscErrorCode ierr; 1004 1005 PetscFunctionBegin; 1006 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1007 PetscValidHeaderSpecific(X,VEC_COOKIE,2); 1008 PetscValidPointer(flg,5); 1009 PetscCheckSameComm(snes,1,X,2); 1010 if (!snes->ops->computejacobian) PetscFunctionReturn(0); 1011 ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1012 *flg = DIFFERENT_NONZERO_PATTERN; 1013 PetscStackPush("SNES user Jacobian function"); 1014 CHKMEMQ; 1015 ierr = (*snes->ops->computejacobian)(snes,X,A,B,flg,snes->jacP);CHKERRQ(ierr); 1016 CHKMEMQ; 1017 PetscStackPop; 1018 ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1019 /* make sure user returned a correct Jacobian and preconditioner */ 1020 /* PetscValidHeaderSpecific(*A,MAT_COOKIE,3); 1021 PetscValidHeaderSpecific(*B,MAT_COOKIE,4); */ 1022 PetscFunctionReturn(0); 1023 } 1024 1025 #undef __FUNCT__ 1026 #define __FUNCT__ "SNESSetJacobian" 1027 /*@C 1028 SNESSetJacobian - Sets the function to compute Jacobian as well as the 1029 location to store the matrix. 1030 1031 Collective on SNES and Mat 1032 1033 Input Parameters: 1034 + snes - the SNES context 1035 . A - Jacobian matrix 1036 . B - preconditioner matrix (usually same as the Jacobian) 1037 . func - Jacobian evaluation routine 1038 - ctx - [optional] user-defined context for private data for the 1039 Jacobian evaluation routine (may be PETSC_NULL) 1040 1041 Calling sequence of func: 1042 $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 1043 1044 + x - input vector 1045 . A - Jacobian matrix 1046 . B - preconditioner matrix, usually the same as A 1047 . flag - flag indicating information about the preconditioner matrix 1048 structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 1049 - ctx - [optional] user-defined Jacobian context 1050 1051 Notes: 1052 See KSPSetOperators() for important information about setting the flag 1053 output parameter in the routine func(). Be sure to read this information! 1054 1055 The routine func() takes Mat * as the matrix arguments rather than Mat. 1056 This allows the Jacobian evaluation routine to replace A and/or B with a 1057 completely new new matrix structure (not just different matrix elements) 1058 when appropriate, for instance, if the nonzero structure is changing 1059 throughout the global iterations. 1060 1061 Level: beginner 1062 1063 .keywords: SNES, nonlinear, set, Jacobian, matrix 1064 1065 .seealso: KSPSetOperators(), SNESSetFunction(), MatSNESMFComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 1066 @*/ 1067 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 1068 { 1069 PetscErrorCode ierr; 1070 1071 PetscFunctionBegin; 1072 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1073 if (A) PetscValidHeaderSpecific(A,MAT_COOKIE,2); 1074 if (B) PetscValidHeaderSpecific(B,MAT_COOKIE,3); 1075 if (A) PetscCheckSameComm(snes,1,A,2); 1076 if (B) PetscCheckSameComm(snes,1,B,2); 1077 if (func) snes->ops->computejacobian = func; 1078 if (ctx) snes->jacP = ctx; 1079 if (A) { 1080 ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 1081 if (snes->jacobian) {ierr = MatDestroy(snes->jacobian);CHKERRQ(ierr);} 1082 snes->jacobian = A; 1083 } 1084 if (B) { 1085 ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 1086 if (snes->jacobian_pre) {ierr = MatDestroy(snes->jacobian_pre);CHKERRQ(ierr);} 1087 snes->jacobian_pre = B; 1088 } 1089 PetscFunctionReturn(0); 1090 } 1091 1092 #undef __FUNCT__ 1093 #define __FUNCT__ "SNESGetJacobian" 1094 /*@C 1095 SNESGetJacobian - Returns the Jacobian matrix and optionally the user 1096 provided context for evaluating the Jacobian. 1097 1098 Not Collective, but Mat object will be parallel if SNES object is 1099 1100 Input Parameter: 1101 . snes - the nonlinear solver context 1102 1103 Output Parameters: 1104 + A - location to stash Jacobian matrix (or PETSC_NULL) 1105 . B - location to stash preconditioner matrix (or PETSC_NULL) 1106 . func - location to put Jacobian function (or PETSC_NULL) 1107 - ctx - location to stash Jacobian ctx (or PETSC_NULL) 1108 1109 Level: advanced 1110 1111 .seealso: SNESSetJacobian(), SNESComputeJacobian() 1112 @*/ 1113 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 1114 { 1115 PetscFunctionBegin; 1116 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1117 if (A) *A = snes->jacobian; 1118 if (B) *B = snes->jacobian_pre; 1119 if (func) *func = snes->ops->computejacobian; 1120 if (ctx) *ctx = snes->jacP; 1121 PetscFunctionReturn(0); 1122 } 1123 1124 /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 1125 EXTERN PetscErrorCode PETSCSNES_DLLEXPORT SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 1126 1127 #undef __FUNCT__ 1128 #define __FUNCT__ "SNESSetUp" 1129 /*@ 1130 SNESSetUp - Sets up the internal data structures for the later use 1131 of a nonlinear solver. 1132 1133 Collective on SNES 1134 1135 Input Parameters: 1136 . snes - the SNES context 1137 1138 Notes: 1139 For basic use of the SNES solvers the user need not explicitly call 1140 SNESSetUp(), since these actions will automatically occur during 1141 the call to SNESSolve(). However, if one wishes to control this 1142 phase separately, SNESSetUp() should be called after SNESCreate() 1143 and optional routines of the form SNESSetXXX(), but before SNESSolve(). 1144 1145 Level: advanced 1146 1147 .keywords: SNES, nonlinear, setup 1148 1149 .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 1150 @*/ 1151 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetUp(SNES snes) 1152 { 1153 PetscErrorCode ierr; 1154 PetscTruth flg; 1155 1156 PetscFunctionBegin; 1157 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1158 if (snes->setupcalled) PetscFunctionReturn(0); 1159 1160 ierr = PetscOptionsHasName(snes->prefix,"-snes_mf_operator",&flg);CHKERRQ(ierr); 1161 /* 1162 This version replaces the user provided Jacobian matrix with a 1163 matrix-free version but still employs the user-provided preconditioner matrix 1164 */ 1165 if (flg) { 1166 Mat J; 1167 ierr = MatCreateSNESMF(snes,snes->vec_sol,&J);CHKERRQ(ierr); 1168 ierr = MatSNESMFSetFromOptions(J);CHKERRQ(ierr); 1169 ierr = PetscInfo(snes,"Setting default matrix-free operator routines\n");CHKERRQ(ierr); 1170 ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 1171 ierr = MatDestroy(J);CHKERRQ(ierr); 1172 } 1173 1174 #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_MAT_SINGLE) && !defined(PETSC_USE_LONG_DOUBLE) && !defined(PETSC_USE_INT) 1175 ierr = PetscOptionsHasName(snes->prefix,"-snes_mf_operator2",&flg);CHKERRQ(ierr); 1176 if (flg) { 1177 Mat J; 1178 ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_sol,&J);CHKERRQ(ierr); 1179 ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 1180 ierr = MatDestroy(J);CHKERRQ(ierr); 1181 } 1182 #endif 1183 1184 ierr = PetscOptionsHasName(snes->prefix,"-snes_mf",&flg);CHKERRQ(ierr); 1185 /* 1186 This version replaces both the user-provided Jacobian and the user- 1187 provided preconditioner matrix with the default matrix free version. 1188 */ 1189 if (flg) { 1190 Mat J; 1191 KSP ksp; 1192 PC pc; 1193 1194 ierr = MatCreateSNESMF(snes,snes->vec_sol,&J);CHKERRQ(ierr); 1195 ierr = MatSNESMFSetFromOptions(J);CHKERRQ(ierr); 1196 ierr = PetscInfo(snes,"Setting default matrix-free operator and preconditioner routines;\nThat is no preconditioner is being used.\n");CHKERRQ(ierr); 1197 ierr = SNESSetJacobian(snes,J,J,MatSNESMFComputeJacobian,snes->funP);CHKERRQ(ierr); 1198 ierr = MatDestroy(J);CHKERRQ(ierr); 1199 1200 /* force no preconditioner */ 1201 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 1202 ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 1203 ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&flg);CHKERRQ(ierr); 1204 if (!flg) { 1205 ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 1206 } 1207 } 1208 1209 if (!snes->vec_func && !snes->afine) { 1210 SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first"); 1211 } 1212 if (!snes->ops->computefunction && !snes->afine) { 1213 SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first"); 1214 } 1215 if (!snes->jacobian) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetJacobian() first \n or use -snes_mf option"); 1216 if (snes->vec_func == snes->vec_sol) { 1217 SETERRQ(PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 1218 } 1219 1220 if (!snes->type_name) { 1221 ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 1222 } 1223 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: 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 if (!snes->setupcalled) { 1855 ierr = SNESSetUp(snes);CHKERRQ(ierr); 1856 } 1857 if (snes->conv_hist_reset) snes->conv_hist_len = 0; 1858 ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 1859 snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 1860 1861 ierr = PetscExceptionTry1((*(snes)->ops->solve)(snes),PETSC_ERR_ARG_DOMAIN); 1862 if (PetscExceptionValue(ierr)) { 1863 /* this means that a caller above me has also tryed this exception so I don't handle it here, pass it up */ 1864 PetscErrorCode pierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(pierr); 1865 } else if (PetscExceptionCaught(ierr,PETSC_ERR_ARG_DOMAIN)) { 1866 /* translate exception into SNES not converged reason */ 1867 snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 1868 ierr = 0; 1869 } 1870 CHKERRQ(ierr); 1871 1872 ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 1873 ierr = PetscOptionsGetString(snes->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 1874 if (flg && !PetscPreLoadingOn) { 1875 ierr = PetscViewerASCIIOpen(snes->comm,filename,&viewer);CHKERRQ(ierr); 1876 ierr = SNESView(snes,viewer);CHKERRQ(ierr); 1877 ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr); 1878 } 1879 1880 ierr = PetscOptionsHasName(snes->prefix,"-snes_test_local_min",&flg);CHKERRQ(ierr); 1881 if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 1882 if (snes->printreason) { 1883 if (snes->reason > 0) { 1884 ierr = PetscPrintf(snes->comm,"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 1885 } else { 1886 ierr = PetscPrintf(snes->comm,"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 1887 } 1888 } 1889 1890 PetscFunctionReturn(0); 1891 } 1892 1893 /* --------- Internal routines for SNES Package --------- */ 1894 1895 #undef __FUNCT__ 1896 #define __FUNCT__ "SNESSetType" 1897 /*@C 1898 SNESSetType - Sets the method for the nonlinear solver. 1899 1900 Collective on SNES 1901 1902 Input Parameters: 1903 + snes - the SNES context 1904 - type - a known method 1905 1906 Options Database Key: 1907 . -snes_type <type> - Sets the method; use -help for a list 1908 of available methods (for instance, ls or tr) 1909 1910 Notes: 1911 See "petsc/include/petscsnes.h" for available methods (for instance) 1912 + SNESLS - Newton's method with line search 1913 (systems of nonlinear equations) 1914 . SNESTR - Newton's method with trust region 1915 (systems of nonlinear equations) 1916 1917 Normally, it is best to use the SNESSetFromOptions() command and then 1918 set the SNES solver type from the options database rather than by using 1919 this routine. Using the options database provides the user with 1920 maximum flexibility in evaluating the many nonlinear solvers. 1921 The SNESSetType() routine is provided for those situations where it 1922 is necessary to set the nonlinear solver independently of the command 1923 line or options database. This might be the case, for example, when 1924 the choice of solver changes during the execution of the program, 1925 and the user's application is taking responsibility for choosing the 1926 appropriate method. 1927 1928 Level: intermediate 1929 1930 .keywords: SNES, set, type 1931 1932 .seealso: SNESType, SNESCreate() 1933 1934 @*/ 1935 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetType(SNES snes,SNESType type) 1936 { 1937 PetscErrorCode ierr,(*r)(SNES); 1938 PetscTruth match; 1939 1940 PetscFunctionBegin; 1941 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1942 PetscValidCharPointer(type,2); 1943 1944 ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 1945 if (match) PetscFunctionReturn(0); 1946 1947 if (snes->setupcalled) { 1948 snes->setupcalled = PETSC_FALSE; 1949 ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 1950 snes->data = 0; 1951 } 1952 1953 /* Get the function pointers for the iterative method requested */ 1954 if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 1955 ierr = PetscFListFind(snes->comm,SNESList,type,(void (**)(void)) &r);CHKERRQ(ierr); 1956 if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 1957 ierr = PetscFree(snes->data);CHKERRQ(ierr); 1958 snes->data = 0; 1959 ierr = (*r)(snes);CHKERRQ(ierr); 1960 ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 1961 PetscFunctionReturn(0); 1962 } 1963 1964 1965 /* --------------------------------------------------------------------- */ 1966 #undef __FUNCT__ 1967 #define __FUNCT__ "SNESRegisterDestroy" 1968 /*@ 1969 SNESRegisterDestroy - Frees the list of nonlinear solvers that were 1970 registered by SNESRegisterDynamic(). 1971 1972 Not Collective 1973 1974 Level: advanced 1975 1976 .keywords: SNES, nonlinear, register, destroy 1977 1978 .seealso: SNESRegisterAll(), SNESRegisterAll() 1979 @*/ 1980 PetscErrorCode PETSCSNES_DLLEXPORT SNESRegisterDestroy(void) 1981 { 1982 PetscErrorCode ierr; 1983 1984 PetscFunctionBegin; 1985 if (SNESList) { 1986 ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 1987 SNESList = 0; 1988 } 1989 SNESRegisterAllCalled = PETSC_FALSE; 1990 PetscFunctionReturn(0); 1991 } 1992 1993 #undef __FUNCT__ 1994 #define __FUNCT__ "SNESGetType" 1995 /*@C 1996 SNESGetType - Gets the SNES method type and name (as a string). 1997 1998 Not Collective 1999 2000 Input Parameter: 2001 . snes - nonlinear solver context 2002 2003 Output Parameter: 2004 . type - SNES method (a character string) 2005 2006 Level: intermediate 2007 2008 .keywords: SNES, nonlinear, get, type, name 2009 @*/ 2010 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetType(SNES snes,SNESType *type) 2011 { 2012 PetscFunctionBegin; 2013 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2014 PetscValidPointer(type,2); 2015 *type = snes->type_name; 2016 PetscFunctionReturn(0); 2017 } 2018 2019 #undef __FUNCT__ 2020 #define __FUNCT__ "SNESGetSolution" 2021 /*@ 2022 SNESGetSolution - Returns the vector where the approximate solution is 2023 stored. 2024 2025 Not Collective, but Vec is parallel if SNES is parallel 2026 2027 Input Parameter: 2028 . snes - the SNES context 2029 2030 Output Parameter: 2031 . x - the solution 2032 2033 Level: intermediate 2034 2035 .keywords: SNES, nonlinear, get, solution 2036 2037 .seealso: SNESSetSolution(), SNESGetFunction(), SNESGetSolutionUpdate() 2038 @*/ 2039 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetSolution(SNES snes,Vec *x) 2040 { 2041 PetscFunctionBegin; 2042 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2043 PetscValidPointer(x,2); 2044 *x = snes->vec_sol_always; 2045 PetscFunctionReturn(0); 2046 } 2047 2048 #undef __FUNCT__ 2049 #define __FUNCT__ "SNESSetSolution" 2050 /*@ 2051 SNESSetSolution - Sets the vector where the approximate solution is stored. 2052 2053 Not Collective, but Vec is parallel if SNES is parallel 2054 2055 Input Parameters: 2056 + snes - the SNES context 2057 - x - the solution 2058 2059 Output Parameter: 2060 2061 Level: intermediate 2062 2063 Notes: this is not normally used, rather one simply calls SNESSolve() with 2064 the appropriate solution vector. 2065 2066 .keywords: SNES, nonlinear, set, solution 2067 2068 .seealso: SNESGetSolution(), SNESGetFunction(), SNESGetSolutionUpdate() 2069 @*/ 2070 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetSolution(SNES snes,Vec x) 2071 { 2072 PetscFunctionBegin; 2073 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2074 PetscValidHeaderSpecific(x,VEC_COOKIE,2); 2075 PetscCheckSameComm(snes,1,x,2); 2076 snes->vec_sol_always = x; 2077 PetscFunctionReturn(0); 2078 } 2079 2080 #undef __FUNCT__ 2081 #define __FUNCT__ "SNESGetSolutionUpdate" 2082 /*@ 2083 SNESGetSolutionUpdate - Returns the vector where the solution update is 2084 stored. 2085 2086 Not Collective, but Vec is parallel if SNES is parallel 2087 2088 Input Parameter: 2089 . snes - the SNES context 2090 2091 Output Parameter: 2092 . x - the solution update 2093 2094 Level: advanced 2095 2096 .keywords: SNES, nonlinear, get, solution, update 2097 2098 .seealso: SNESGetSolution(), SNESGetFunction 2099 @*/ 2100 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetSolutionUpdate(SNES snes,Vec *x) 2101 { 2102 PetscFunctionBegin; 2103 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2104 PetscValidPointer(x,2); 2105 *x = snes->vec_sol_update_always; 2106 PetscFunctionReturn(0); 2107 } 2108 2109 #undef __FUNCT__ 2110 #define __FUNCT__ "SNESGetFunction" 2111 /*@C 2112 SNESGetFunction - Returns the vector where the function is stored. 2113 2114 Not Collective, but Vec is parallel if SNES is parallel 2115 2116 Input Parameter: 2117 . snes - the SNES context 2118 2119 Output Parameter: 2120 + r - the function (or PETSC_NULL) 2121 . func - the function (or PETSC_NULL) 2122 - ctx - the function context (or PETSC_NULL) 2123 2124 Level: advanced 2125 2126 .keywords: SNES, nonlinear, get, function 2127 2128 .seealso: SNESSetFunction(), SNESGetSolution() 2129 @*/ 2130 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 2131 { 2132 PetscFunctionBegin; 2133 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2134 if (r) *r = snes->vec_func_always; 2135 if (func) *func = snes->ops->computefunction; 2136 if (ctx) *ctx = snes->funP; 2137 PetscFunctionReturn(0); 2138 } 2139 2140 #undef __FUNCT__ 2141 #define __FUNCT__ "SNESSetOptionsPrefix" 2142 /*@C 2143 SNESSetOptionsPrefix - Sets the prefix used for searching for all 2144 SNES options in the database. 2145 2146 Collective on SNES 2147 2148 Input Parameter: 2149 + snes - the SNES context 2150 - prefix - the prefix to prepend to all option names 2151 2152 Notes: 2153 A hyphen (-) must NOT be given at the beginning of the prefix name. 2154 The first character of all runtime options is AUTOMATICALLY the hyphen. 2155 2156 Level: advanced 2157 2158 .keywords: SNES, set, options, prefix, database 2159 2160 .seealso: SNESSetFromOptions() 2161 @*/ 2162 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetOptionsPrefix(SNES snes,const char prefix[]) 2163 { 2164 PetscErrorCode ierr; 2165 2166 PetscFunctionBegin; 2167 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2168 ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2169 ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 2170 PetscFunctionReturn(0); 2171 } 2172 2173 #undef __FUNCT__ 2174 #define __FUNCT__ "SNESAppendOptionsPrefix" 2175 /*@C 2176 SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 2177 SNES options in the database. 2178 2179 Collective on SNES 2180 2181 Input Parameters: 2182 + snes - the SNES context 2183 - prefix - the prefix to prepend to all option names 2184 2185 Notes: 2186 A hyphen (-) must NOT be given at the beginning of the prefix name. 2187 The first character of all runtime options is AUTOMATICALLY the hyphen. 2188 2189 Level: advanced 2190 2191 .keywords: SNES, append, options, prefix, database 2192 2193 .seealso: SNESGetOptionsPrefix() 2194 @*/ 2195 PetscErrorCode PETSCSNES_DLLEXPORT SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 2196 { 2197 PetscErrorCode ierr; 2198 2199 PetscFunctionBegin; 2200 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2201 ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2202 ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 2203 PetscFunctionReturn(0); 2204 } 2205 2206 #undef __FUNCT__ 2207 #define __FUNCT__ "SNESGetOptionsPrefix" 2208 /*@C 2209 SNESGetOptionsPrefix - Sets the prefix used for searching for all 2210 SNES options in the database. 2211 2212 Not Collective 2213 2214 Input Parameter: 2215 . snes - the SNES context 2216 2217 Output Parameter: 2218 . prefix - pointer to the prefix string used 2219 2220 Notes: On the fortran side, the user should pass in a string 'prifix' of 2221 sufficient length to hold the prefix. 2222 2223 Level: advanced 2224 2225 .keywords: SNES, get, options, prefix, database 2226 2227 .seealso: SNESAppendOptionsPrefix() 2228 @*/ 2229 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 2230 { 2231 PetscErrorCode ierr; 2232 2233 PetscFunctionBegin; 2234 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2235 ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2236 PetscFunctionReturn(0); 2237 } 2238 2239 2240 #undef __FUNCT__ 2241 #define __FUNCT__ "SNESRegister" 2242 /*@C 2243 SNESRegister - See SNESRegisterDynamic() 2244 2245 Level: advanced 2246 @*/ 2247 PetscErrorCode PETSCSNES_DLLEXPORT SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 2248 { 2249 char fullname[PETSC_MAX_PATH_LEN]; 2250 PetscErrorCode ierr; 2251 2252 PetscFunctionBegin; 2253 ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 2254 ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 2255 PetscFunctionReturn(0); 2256 } 2257 2258 #undef __FUNCT__ 2259 #define __FUNCT__ "SNESTestLocalMin" 2260 PetscErrorCode PETSCSNES_DLLEXPORT SNESTestLocalMin(SNES snes) 2261 { 2262 PetscErrorCode ierr; 2263 PetscInt N,i,j; 2264 Vec u,uh,fh; 2265 PetscScalar value; 2266 PetscReal norm; 2267 2268 PetscFunctionBegin; 2269 ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 2270 ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 2271 ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 2272 2273 /* currently only works for sequential */ 2274 ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 2275 ierr = VecGetSize(u,&N);CHKERRQ(ierr); 2276 for (i=0; i<N; i++) { 2277 ierr = VecCopy(u,uh);CHKERRQ(ierr); 2278 ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 2279 for (j=-10; j<11; j++) { 2280 value = PetscSign(j)*exp(PetscAbs(j)-10.0); 2281 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 2282 ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 2283 ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 2284 ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 2285 value = -value; 2286 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 2287 } 2288 } 2289 ierr = VecDestroy(uh);CHKERRQ(ierr); 2290 ierr = VecDestroy(fh);CHKERRQ(ierr); 2291 PetscFunctionReturn(0); 2292 } 2293 2294 #undef __FUNCT__ 2295 #define __FUNCT__ "SNES_KSP_SetUseEW" 2296 /*@ 2297 SNES_KSP_SetUseEW - Sets SNES use Eisenstat-Walker method for 2298 computing relative tolerance for linear solvers within an inexact 2299 Newton method. 2300 2301 Collective on SNES 2302 2303 Input Parameters: 2304 + snes - SNES context 2305 - flag - PETSC_TRUE or PETSC_FALSE 2306 2307 Notes: 2308 Currently, the default is to use a constant relative tolerance for 2309 the inner linear solvers. Alternatively, one can use the 2310 Eisenstat-Walker method, where the relative convergence tolerance 2311 is reset at each Newton iteration according progress of the nonlinear 2312 solver. 2313 2314 Level: advanced 2315 2316 Reference: 2317 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 2318 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 2319 2320 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 2321 2322 .seealso: SNES_KSP_GetUseEW(), SNES_KSP_GetParametersEW(), SNES_KSP_SetParametersEW() 2323 @*/ 2324 PetscErrorCode PETSCSNES_DLLEXPORT SNES_KSP_SetUseEW(SNES snes,PetscTruth flag) 2325 { 2326 PetscFunctionBegin; 2327 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2328 snes->ksp_ewconv = flag; 2329 PetscFunctionReturn(0); 2330 } 2331 2332 #undef __FUNCT__ 2333 #define __FUNCT__ "SNES_KSP_GetUseEW" 2334 /*@ 2335 SNES_KSP_GetUseEW - Gets if SNES is using Eisenstat-Walker method 2336 for computing relative tolerance for linear solvers within an 2337 inexact Newton method. 2338 2339 Not Collective 2340 2341 Input Parameter: 2342 . snes - SNES context 2343 2344 Output Parameter: 2345 . flag - PETSC_TRUE or PETSC_FALSE 2346 2347 Notes: 2348 Currently, the default is to use a constant relative tolerance for 2349 the inner linear solvers. Alternatively, one can use the 2350 Eisenstat-Walker method, where the relative convergence tolerance 2351 is reset at each Newton iteration according progress of the nonlinear 2352 solver. 2353 2354 Level: advanced 2355 2356 Reference: 2357 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 2358 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 2359 2360 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 2361 2362 .seealso: SNES_KSP_SetUseEW(), SNES_KSP_GetParametersEW(), SNES_KSP_SetParametersEW() 2363 @*/ 2364 PetscErrorCode PETSCSNES_DLLEXPORT SNES_KSP_GetUseEW(SNES snes, PetscTruth *flag) 2365 { 2366 PetscFunctionBegin; 2367 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2368 PetscValidPointer(flag,2); 2369 *flag = snes->ksp_ewconv; 2370 PetscFunctionReturn(0); 2371 } 2372 2373 #undef __FUNCT__ 2374 #define __FUNCT__ "SNES_KSP_SetParametersEW" 2375 /*@ 2376 SNES_KSP_SetParametersEW - Sets parameters for Eisenstat-Walker 2377 convergence criteria for the linear solvers within an inexact 2378 Newton method. 2379 2380 Collective on SNES 2381 2382 Input Parameters: 2383 + snes - SNES context 2384 . version - version 1, 2 (default is 2) or 3 2385 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 2386 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 2387 . gamma - multiplicative factor for version 2 rtol computation 2388 (0 <= gamma2 <= 1) 2389 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 2390 . alpha2 - power for safeguard 2391 - threshold - threshold for imposing safeguard (0 < threshold < 1) 2392 2393 Note: 2394 Version 3 was contributed by Luis Chacon, June 2006. 2395 2396 Use PETSC_DEFAULT to retain the default for any of the parameters. 2397 2398 Level: advanced 2399 2400 Reference: 2401 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 2402 inexact Newton method", Utah State University Math. Stat. Dept. Res. 2403 Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 2404 2405 .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 2406 2407 .seealso: SNES_KSP_SetUseEW(), SNES_KSP_GetUseEW(), SNES_KSP_GetParametersEW() 2408 @*/ 2409 PetscErrorCode PETSCSNES_DLLEXPORT SNES_KSP_SetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 2410 PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 2411 { 2412 SNES_KSP_EW_ConvCtx *kctx; 2413 PetscFunctionBegin; 2414 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2415 kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 2416 if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 2417 2418 if (version != PETSC_DEFAULT) kctx->version = version; 2419 if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 2420 if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 2421 if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 2422 if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 2423 if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 2424 if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 2425 2426 if (kctx->version < 1 || kctx->version > 3) { 2427 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 2428 } 2429 if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 2430 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 2431 } 2432 if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 2433 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 2434 } 2435 if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 2436 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 2437 } 2438 if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 2439 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 2440 } 2441 if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 2442 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 2443 } 2444 PetscFunctionReturn(0); 2445 } 2446 2447 #undef __FUNCT__ 2448 #define __FUNCT__ "SNES_KSP_GetParametersEW" 2449 /*@ 2450 SNES_KSP_GetParametersEW - Gets parameters for Eisenstat-Walker 2451 convergence criteria for the linear solvers within an inexact 2452 Newton method. 2453 2454 Not Collective 2455 2456 Input Parameters: 2457 snes - SNES context 2458 2459 Output Parameters: 2460 + version - version 1, 2 (default is 2) or 3 2461 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 2462 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 2463 . gamma - multiplicative factor for version 2 rtol computation 2464 (0 <= gamma2 <= 1) 2465 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 2466 . alpha2 - power for safeguard 2467 - threshold - threshold for imposing safeguard (0 < threshold < 1) 2468 2469 Level: advanced 2470 2471 .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 2472 2473 .seealso: SNES_KSP_SetUseEW(), SNES_KSP_GetUseEW(), SNES_KSP_SetParametersEW() 2474 @*/ 2475 PetscErrorCode PETSCSNES_DLLEXPORT SNES_KSP_GetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 2476 PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 2477 { 2478 SNES_KSP_EW_ConvCtx *kctx; 2479 PetscFunctionBegin; 2480 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2481 kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 2482 if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 2483 if(version) *version = kctx->version; 2484 if(rtol_0) *rtol_0 = kctx->rtol_0; 2485 if(rtol_max) *rtol_max = kctx->rtol_max; 2486 if(gamma) *gamma = kctx->gamma; 2487 if(alpha) *alpha = kctx->alpha; 2488 if(alpha2) *alpha2 = kctx->alpha2; 2489 if(threshold) *threshold = kctx->threshold; 2490 PetscFunctionReturn(0); 2491 } 2492 2493 #undef __FUNCT__ 2494 #define __FUNCT__ "SNES_KSP_EW_PreSolve" 2495 static PetscErrorCode SNES_KSP_EW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 2496 { 2497 PetscErrorCode ierr; 2498 SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 2499 PetscReal rtol=PETSC_DEFAULT,stol; 2500 2501 PetscFunctionBegin; 2502 if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 2503 if (!snes->iter) { /* first time in, so use the original user rtol */ 2504 rtol = kctx->rtol_0; 2505 } else { 2506 if (kctx->version == 1) { 2507 rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 2508 if (rtol < 0.0) rtol = -rtol; 2509 stol = pow(kctx->rtol_last,kctx->alpha2); 2510 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 2511 } else if (kctx->version == 2) { 2512 rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 2513 stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 2514 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 2515 } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 2516 rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 2517 /* safeguard: avoid sharp decrease of rtol */ 2518 stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 2519 stol = PetscMax(rtol,stol); 2520 rtol = PetscMin(kctx->rtol_0,stol); 2521 /* safeguard: avoid oversolving */ 2522 stol = kctx->gamma*(snes->ttol)/snes->norm; 2523 stol = PetscMax(rtol,stol); 2524 rtol = PetscMin(kctx->rtol_0,stol); 2525 } else SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 2526 } 2527 /* safeguard: avoid rtol greater than one */ 2528 rtol = PetscMin(rtol,kctx->rtol_max); 2529 ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 2530 ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 2531 PetscFunctionReturn(0); 2532 } 2533 2534 #undef __FUNCT__ 2535 #define __FUNCT__ "SNES_KSP_EW_PostSolve" 2536 static PetscErrorCode SNES_KSP_EW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 2537 { 2538 PetscErrorCode ierr; 2539 SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx*)snes->kspconvctx; 2540 PCSide pcside; 2541 Vec lres; 2542 2543 PetscFunctionBegin; 2544 if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 2545 ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 2546 ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 2547 if (kctx->version == 1) { 2548 ierr = KSPGetPreconditionerSide(ksp,&pcside);CHKERRQ(ierr); 2549 if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 2550 /* KSP residual is true linear residual */ 2551 ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 2552 } else { 2553 /* KSP residual is preconditioned residual */ 2554 /* compute true linear residual norm */ 2555 ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 2556 ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 2557 ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 2558 ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 2559 ierr = VecDestroy(lres);CHKERRQ(ierr); 2560 } 2561 } 2562 PetscFunctionReturn(0); 2563 } 2564 2565 #undef __FUNCT__ 2566 #define __FUNCT__ "SNES_KSPSolve" 2567 PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 2568 { 2569 PetscErrorCode ierr; 2570 2571 PetscFunctionBegin; 2572 if (snes->ksp_ewconv) { ierr = SNES_KSP_EW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 2573 ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 2574 if (snes->ksp_ewconv) { ierr = SNES_KSP_EW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 2575 PetscFunctionReturn(0); 2576 } 2577