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