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 Fortran notes: Only a single monitor function can be set for each SNES object 1505 1506 Level: intermediate 1507 1508 .keywords: SNES, nonlinear, set, monitor 1509 1510 .seealso: SNESMonitorDefault(), SNESMonitorCancel() 1511 @*/ 1512 PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void*)) 1513 { 1514 PetscInt i; 1515 1516 PetscFunctionBegin; 1517 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1518 if (snes->numbermonitors >= MAXSNESMONITORS) { 1519 SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 1520 } 1521 for (i=0; i<snes->numbermonitors;i++) { 1522 if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) PetscFunctionReturn(0); 1523 1524 /* check if both default monitors that share common ASCII viewer */ 1525 if (monitor == snes->monitor[i] && monitor == SNESMonitorDefault) { 1526 if (mctx && snes->monitorcontext[i]) { 1527 PetscErrorCode ierr; 1528 PetscViewerASCIIMonitor viewer1 = (PetscViewerASCIIMonitor) mctx; 1529 PetscViewerASCIIMonitor viewer2 = (PetscViewerASCIIMonitor) snes->monitorcontext[i]; 1530 if (viewer1->viewer == viewer2->viewer) { 1531 ierr = (*monitordestroy)(mctx);CHKERRQ(ierr); 1532 PetscFunctionReturn(0); 1533 } 1534 } 1535 } 1536 } 1537 snes->monitor[snes->numbermonitors] = monitor; 1538 snes->monitordestroy[snes->numbermonitors] = monitordestroy; 1539 snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 1540 PetscFunctionReturn(0); 1541 } 1542 1543 #undef __FUNCT__ 1544 #define __FUNCT__ "SNESMonitorCancel" 1545 /*@C 1546 SNESMonitorCancel - Clears all the monitor functions for a SNES object. 1547 1548 Collective on SNES 1549 1550 Input Parameters: 1551 . snes - the SNES context 1552 1553 Options Database Key: 1554 . -snes_monitor_cancel - cancels all monitors that have been hardwired 1555 into a code by calls to SNESMonitorSet(), but does not cancel those 1556 set via the options database 1557 1558 Notes: 1559 There is no way to clear one specific monitor from a SNES object. 1560 1561 Level: intermediate 1562 1563 .keywords: SNES, nonlinear, set, monitor 1564 1565 .seealso: SNESMonitorDefault(), SNESMonitorSet() 1566 @*/ 1567 PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorCancel(SNES snes) 1568 { 1569 PetscErrorCode ierr; 1570 PetscInt i; 1571 1572 PetscFunctionBegin; 1573 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1574 for (i=0; i<snes->numbermonitors; i++) { 1575 if (snes->monitordestroy[i]) { 1576 ierr = (*snes->monitordestroy[i])(snes->monitorcontext[i]);CHKERRQ(ierr); 1577 } 1578 } 1579 snes->numbermonitors = 0; 1580 PetscFunctionReturn(0); 1581 } 1582 1583 #undef __FUNCT__ 1584 #define __FUNCT__ "SNESSetConvergenceTest" 1585 /*@C 1586 SNESSetConvergenceTest - Sets the function that is to be used 1587 to test for convergence of the nonlinear iterative solution. 1588 1589 Collective on SNES 1590 1591 Input Parameters: 1592 + snes - the SNES context 1593 . func - routine to test for convergence 1594 - cctx - [optional] context for private data for the convergence routine 1595 (may be PETSC_NULL) 1596 1597 Calling sequence of func: 1598 $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 1599 1600 + snes - the SNES context 1601 . it - current iteration (0 is the first and is before any Newton step) 1602 . cctx - [optional] convergence context 1603 . reason - reason for convergence/divergence 1604 . xnorm - 2-norm of current iterate 1605 . gnorm - 2-norm of current step 1606 - f - 2-norm of function 1607 1608 Level: advanced 1609 1610 .keywords: SNES, nonlinear, set, convergence, test 1611 1612 .seealso: SNESDefaultConverged(), SNESSkipConverged() 1613 @*/ 1614 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx) 1615 { 1616 PetscFunctionBegin; 1617 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1618 if (!func) func = SNESSkipConverged; 1619 snes->ops->converged = func; 1620 snes->cnvP = cctx; 1621 PetscFunctionReturn(0); 1622 } 1623 1624 #undef __FUNCT__ 1625 #define __FUNCT__ "SNESGetConvergedReason" 1626 /*@ 1627 SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 1628 1629 Not Collective 1630 1631 Input Parameter: 1632 . snes - the SNES context 1633 1634 Output Parameter: 1635 . reason - negative value indicates diverged, positive value converged, see petscsnes.h or the 1636 manual pages for the individual convergence tests for complete lists 1637 1638 Level: intermediate 1639 1640 Notes: Can only be called after the call the SNESSolve() is complete. 1641 1642 .keywords: SNES, nonlinear, set, convergence, test 1643 1644 .seealso: SNESSetConvergenceTest(), SNESConvergedReason 1645 @*/ 1646 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 1647 { 1648 PetscFunctionBegin; 1649 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1650 PetscValidPointer(reason,2); 1651 *reason = snes->reason; 1652 PetscFunctionReturn(0); 1653 } 1654 1655 #undef __FUNCT__ 1656 #define __FUNCT__ "SNESSetConvergenceHistory" 1657 /*@ 1658 SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 1659 1660 Collective on SNES 1661 1662 Input Parameters: 1663 + snes - iterative context obtained from SNESCreate() 1664 . a - array to hold history 1665 . its - integer array holds the number of linear iterations for each solve. 1666 . na - size of a and its 1667 - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 1668 else it continues storing new values for new nonlinear solves after the old ones 1669 1670 Notes: 1671 If set, this array will contain the function norms computed 1672 at each step. 1673 1674 This routine is useful, e.g., when running a code for purposes 1675 of accurate performance monitoring, when no I/O should be done 1676 during the section of code that is being timed. 1677 1678 Level: intermediate 1679 1680 .keywords: SNES, set, convergence, history 1681 1682 .seealso: SNESGetConvergenceHistory() 1683 1684 @*/ 1685 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscTruth reset) 1686 { 1687 PetscFunctionBegin; 1688 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1689 if (na) PetscValidScalarPointer(a,2); 1690 if (its) PetscValidIntPointer(its,3); 1691 snes->conv_hist = a; 1692 snes->conv_hist_its = its; 1693 snes->conv_hist_max = na; 1694 snes->conv_hist_reset = reset; 1695 PetscFunctionReturn(0); 1696 } 1697 1698 #undef __FUNCT__ 1699 #define __FUNCT__ "SNESGetConvergenceHistory" 1700 /*@C 1701 SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 1702 1703 Collective on SNES 1704 1705 Input Parameter: 1706 . snes - iterative context obtained from SNESCreate() 1707 1708 Output Parameters: 1709 . a - array to hold history 1710 . its - integer array holds the number of linear iterations (or 1711 negative if not converged) for each solve. 1712 - na - size of a and its 1713 1714 Notes: 1715 The calling sequence for this routine in Fortran is 1716 $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 1717 1718 This routine is useful, e.g., when running a code for purposes 1719 of accurate performance monitoring, when no I/O should be done 1720 during the section of code that is being timed. 1721 1722 Level: intermediate 1723 1724 .keywords: SNES, get, convergence, history 1725 1726 .seealso: SNESSetConvergencHistory() 1727 1728 @*/ 1729 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 1730 { 1731 PetscFunctionBegin; 1732 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1733 if (a) *a = snes->conv_hist; 1734 if (its) *its = snes->conv_hist_its; 1735 if (na) *na = snes->conv_hist_len; 1736 PetscFunctionReturn(0); 1737 } 1738 1739 #undef __FUNCT__ 1740 #define __FUNCT__ "SNESSetUpdate" 1741 /*@C 1742 SNESSetUpdate - Sets the general-purpose update function called 1743 at the beginning o every iteration of the nonlinear solve. Specifically 1744 it is called just before the Jacobian is "evaluated". 1745 1746 Collective on SNES 1747 1748 Input Parameters: 1749 . snes - The nonlinear solver context 1750 . func - The function 1751 1752 Calling sequence of func: 1753 . func (SNES snes, PetscInt step); 1754 1755 . step - The current step of the iteration 1756 1757 Level: intermediate 1758 1759 .keywords: SNES, update 1760 1761 .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 1762 @*/ 1763 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 1764 { 1765 PetscFunctionBegin; 1766 PetscValidHeaderSpecific(snes, SNES_COOKIE,1); 1767 snes->ops->update = func; 1768 PetscFunctionReturn(0); 1769 } 1770 1771 #undef __FUNCT__ 1772 #define __FUNCT__ "SNESDefaultUpdate" 1773 /*@ 1774 SNESDefaultUpdate - The default update function which does nothing. 1775 1776 Not collective 1777 1778 Input Parameters: 1779 . snes - The nonlinear solver context 1780 . step - The current step of the iteration 1781 1782 Level: intermediate 1783 1784 .keywords: SNES, update 1785 .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 1786 @*/ 1787 PetscErrorCode PETSCSNES_DLLEXPORT SNESDefaultUpdate(SNES snes, PetscInt step) 1788 { 1789 PetscFunctionBegin; 1790 PetscFunctionReturn(0); 1791 } 1792 1793 #undef __FUNCT__ 1794 #define __FUNCT__ "SNESScaleStep_Private" 1795 /* 1796 SNESScaleStep_Private - Scales a step so that its length is less than the 1797 positive parameter delta. 1798 1799 Input Parameters: 1800 + snes - the SNES context 1801 . y - approximate solution of linear system 1802 . fnorm - 2-norm of current function 1803 - delta - trust region size 1804 1805 Output Parameters: 1806 + gpnorm - predicted function norm at the new point, assuming local 1807 linearization. The value is zero if the step lies within the trust 1808 region, and exceeds zero otherwise. 1809 - ynorm - 2-norm of the step 1810 1811 Note: 1812 For non-trust region methods such as SNESLS, the parameter delta 1813 is set to be the maximum allowable step size. 1814 1815 .keywords: SNES, nonlinear, scale, step 1816 */ 1817 PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 1818 { 1819 PetscReal nrm; 1820 PetscScalar cnorm; 1821 PetscErrorCode ierr; 1822 1823 PetscFunctionBegin; 1824 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1825 PetscValidHeaderSpecific(y,VEC_COOKIE,2); 1826 PetscCheckSameComm(snes,1,y,2); 1827 1828 ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 1829 if (nrm > *delta) { 1830 nrm = *delta/nrm; 1831 *gpnorm = (1.0 - nrm)*(*fnorm); 1832 cnorm = nrm; 1833 ierr = VecScale(y,cnorm);CHKERRQ(ierr); 1834 *ynorm = *delta; 1835 } else { 1836 *gpnorm = 0.0; 1837 *ynorm = nrm; 1838 } 1839 PetscFunctionReturn(0); 1840 } 1841 1842 #undef __FUNCT__ 1843 #define __FUNCT__ "SNESSolve" 1844 /*@C 1845 SNESSolve - Solves a nonlinear system F(x) = b. 1846 Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 1847 1848 Collective on SNES 1849 1850 Input Parameters: 1851 + snes - the SNES context 1852 . b - the constant part of the equation, or PETSC_NULL to use zero. 1853 - x - the solution vector. 1854 1855 Notes: 1856 The user should initialize the vector,x, with the initial guess 1857 for the nonlinear solve prior to calling SNESSolve. In particular, 1858 to employ an initial guess of zero, the user should explicitly set 1859 this vector to zero by calling VecSet(). 1860 1861 Level: beginner 1862 1863 .keywords: SNES, nonlinear, solve 1864 1865 .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian() 1866 @*/ 1867 PetscErrorCode PETSCSNES_DLLEXPORT SNESSolve(SNES snes,Vec b,Vec x) 1868 { 1869 PetscErrorCode ierr; 1870 PetscTruth flg; 1871 char filename[PETSC_MAX_PATH_LEN]; 1872 PetscViewer viewer; 1873 1874 PetscFunctionBegin; 1875 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1876 PetscValidHeaderSpecific(x,VEC_COOKIE,3); 1877 PetscCheckSameComm(snes,1,x,3); 1878 if (b) PetscValidHeaderSpecific(b,VEC_COOKIE,2); 1879 if (b) PetscCheckSameComm(snes,1,b,2); 1880 1881 /* set solution vector */ 1882 ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 1883 if (snes->vec_sol) { ierr = VecDestroy(snes->vec_sol);CHKERRQ(ierr); } 1884 snes->vec_sol = x; 1885 /* set afine vector if provided */ 1886 if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 1887 if (snes->vec_rhs) { ierr = VecDestroy(snes->vec_rhs);CHKERRQ(ierr); } 1888 snes->vec_rhs = b; 1889 1890 if (!snes->vec_func && snes->vec_rhs) { 1891 ierr = VecDuplicate(b, &snes->vec_func); CHKERRQ(ierr); 1892 } 1893 1894 ierr = SNESSetUp(snes);CHKERRQ(ierr); 1895 1896 if (snes->conv_hist_reset) snes->conv_hist_len = 0; 1897 snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 1898 1899 ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 1900 ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 1901 ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 1902 if (snes->domainerror){ 1903 snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 1904 snes->domainerror = PETSC_FALSE; 1905 } 1906 1907 if (!snes->reason) { 1908 SETERRQ(PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 1909 } 1910 1911 ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 1912 if (flg && !PetscPreLoadingOn) { 1913 ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 1914 ierr = SNESView(snes,viewer);CHKERRQ(ierr); 1915 ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr); 1916 } 1917 1918 ierr = PetscOptionsHasName(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg);CHKERRQ(ierr); 1919 if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 1920 if (snes->printreason) { 1921 if (snes->reason > 0) { 1922 ierr = PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 1923 } else { 1924 ierr = PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 1925 } 1926 } 1927 1928 PetscFunctionReturn(0); 1929 } 1930 1931 /* --------- Internal routines for SNES Package --------- */ 1932 1933 #undef __FUNCT__ 1934 #define __FUNCT__ "SNESSetType" 1935 /*@C 1936 SNESSetType - Sets the method for the nonlinear solver. 1937 1938 Collective on SNES 1939 1940 Input Parameters: 1941 + snes - the SNES context 1942 - type - a known method 1943 1944 Options Database Key: 1945 . -snes_type <type> - Sets the method; use -help for a list 1946 of available methods (for instance, ls or tr) 1947 1948 Notes: 1949 See "petsc/include/petscsnes.h" for available methods (for instance) 1950 + SNESLS - Newton's method with line search 1951 (systems of nonlinear equations) 1952 . SNESTR - Newton's method with trust region 1953 (systems of nonlinear equations) 1954 1955 Normally, it is best to use the SNESSetFromOptions() command and then 1956 set the SNES solver type from the options database rather than by using 1957 this routine. Using the options database provides the user with 1958 maximum flexibility in evaluating the many nonlinear solvers. 1959 The SNESSetType() routine is provided for those situations where it 1960 is necessary to set the nonlinear solver independently of the command 1961 line or options database. This might be the case, for example, when 1962 the choice of solver changes during the execution of the program, 1963 and the user's application is taking responsibility for choosing the 1964 appropriate method. 1965 1966 Level: intermediate 1967 1968 .keywords: SNES, set, type 1969 1970 .seealso: SNESType, SNESCreate() 1971 1972 @*/ 1973 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetType(SNES snes,SNESType type) 1974 { 1975 PetscErrorCode ierr,(*r)(SNES); 1976 PetscTruth match; 1977 1978 PetscFunctionBegin; 1979 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1980 PetscValidCharPointer(type,2); 1981 1982 ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 1983 if (match) PetscFunctionReturn(0); 1984 1985 ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,(void (**)(void)) &r);CHKERRQ(ierr); 1986 if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 1987 /* Destroy the previous private SNES context */ 1988 if (snes->ops->destroy) { ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); } 1989 /* Reinitialize function pointers in SNESOps structure */ 1990 snes->ops->setup = 0; 1991 snes->ops->solve = 0; 1992 snes->ops->view = 0; 1993 snes->ops->setfromoptions = 0; 1994 snes->ops->destroy = 0; 1995 /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 1996 snes->setupcalled = PETSC_FALSE; 1997 ierr = (*r)(snes);CHKERRQ(ierr); 1998 ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 1999 PetscFunctionReturn(0); 2000 } 2001 2002 2003 /* --------------------------------------------------------------------- */ 2004 #undef __FUNCT__ 2005 #define __FUNCT__ "SNESRegisterDestroy" 2006 /*@ 2007 SNESRegisterDestroy - Frees the list of nonlinear solvers that were 2008 registered by SNESRegisterDynamic(). 2009 2010 Not Collective 2011 2012 Level: advanced 2013 2014 .keywords: SNES, nonlinear, register, destroy 2015 2016 .seealso: SNESRegisterAll(), SNESRegisterAll() 2017 @*/ 2018 PetscErrorCode PETSCSNES_DLLEXPORT SNESRegisterDestroy(void) 2019 { 2020 PetscErrorCode ierr; 2021 2022 PetscFunctionBegin; 2023 ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 2024 SNESRegisterAllCalled = PETSC_FALSE; 2025 PetscFunctionReturn(0); 2026 } 2027 2028 #undef __FUNCT__ 2029 #define __FUNCT__ "SNESGetType" 2030 /*@C 2031 SNESGetType - Gets the SNES method type and name (as a string). 2032 2033 Not Collective 2034 2035 Input Parameter: 2036 . snes - nonlinear solver context 2037 2038 Output Parameter: 2039 . type - SNES method (a character string) 2040 2041 Level: intermediate 2042 2043 .keywords: SNES, nonlinear, get, type, name 2044 @*/ 2045 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetType(SNES snes,SNESType *type) 2046 { 2047 PetscFunctionBegin; 2048 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2049 PetscValidPointer(type,2); 2050 *type = ((PetscObject)snes)->type_name; 2051 PetscFunctionReturn(0); 2052 } 2053 2054 #undef __FUNCT__ 2055 #define __FUNCT__ "SNESGetSolution" 2056 /*@ 2057 SNESGetSolution - Returns the vector where the approximate solution is 2058 stored. 2059 2060 Not Collective, but Vec is parallel if SNES is parallel 2061 2062 Input Parameter: 2063 . snes - the SNES context 2064 2065 Output Parameter: 2066 . x - the solution 2067 2068 Level: intermediate 2069 2070 .keywords: SNES, nonlinear, get, solution 2071 2072 .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 2073 @*/ 2074 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetSolution(SNES snes,Vec *x) 2075 { 2076 PetscFunctionBegin; 2077 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2078 PetscValidPointer(x,2); 2079 *x = snes->vec_sol; 2080 PetscFunctionReturn(0); 2081 } 2082 2083 #undef __FUNCT__ 2084 #define __FUNCT__ "SNESGetSolutionUpdate" 2085 /*@ 2086 SNESGetSolutionUpdate - Returns the vector where the solution update is 2087 stored. 2088 2089 Not Collective, but Vec is parallel if SNES is parallel 2090 2091 Input Parameter: 2092 . snes - the SNES context 2093 2094 Output Parameter: 2095 . x - the solution update 2096 2097 Level: advanced 2098 2099 .keywords: SNES, nonlinear, get, solution, update 2100 2101 .seealso: SNESGetSolution(), SNESGetFunction() 2102 @*/ 2103 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetSolutionUpdate(SNES snes,Vec *x) 2104 { 2105 PetscFunctionBegin; 2106 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2107 PetscValidPointer(x,2); 2108 *x = snes->vec_sol_update; 2109 PetscFunctionReturn(0); 2110 } 2111 2112 #undef __FUNCT__ 2113 #define __FUNCT__ "SNESGetFunction" 2114 /*@C 2115 SNESGetFunction - Returns the vector where the function is stored. 2116 2117 Not Collective, but Vec is parallel if SNES is parallel 2118 2119 Input Parameter: 2120 . snes - the SNES context 2121 2122 Output Parameter: 2123 + r - the function (or PETSC_NULL) 2124 . func - the function (or PETSC_NULL) 2125 - ctx - the function context (or PETSC_NULL) 2126 2127 Level: advanced 2128 2129 .keywords: SNES, nonlinear, get, function 2130 2131 .seealso: SNESSetFunction(), SNESGetSolution() 2132 @*/ 2133 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 2134 { 2135 PetscFunctionBegin; 2136 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2137 if (r) *r = snes->vec_func; 2138 if (func) *func = snes->ops->computefunction; 2139 if (ctx) *ctx = snes->funP; 2140 PetscFunctionReturn(0); 2141 } 2142 2143 #undef __FUNCT__ 2144 #define __FUNCT__ "SNESSetOptionsPrefix" 2145 /*@C 2146 SNESSetOptionsPrefix - Sets the prefix used for searching for all 2147 SNES options in the database. 2148 2149 Collective on SNES 2150 2151 Input Parameter: 2152 + snes - the SNES context 2153 - prefix - the prefix to prepend to all option names 2154 2155 Notes: 2156 A hyphen (-) must NOT be given at the beginning of the prefix name. 2157 The first character of all runtime options is AUTOMATICALLY the hyphen. 2158 2159 Level: advanced 2160 2161 .keywords: SNES, set, options, prefix, database 2162 2163 .seealso: SNESSetFromOptions() 2164 @*/ 2165 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetOptionsPrefix(SNES snes,const char prefix[]) 2166 { 2167 PetscErrorCode ierr; 2168 2169 PetscFunctionBegin; 2170 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2171 ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2172 ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 2173 PetscFunctionReturn(0); 2174 } 2175 2176 #undef __FUNCT__ 2177 #define __FUNCT__ "SNESAppendOptionsPrefix" 2178 /*@C 2179 SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 2180 SNES options in the database. 2181 2182 Collective on SNES 2183 2184 Input Parameters: 2185 + snes - the SNES context 2186 - prefix - the prefix to prepend to all option names 2187 2188 Notes: 2189 A hyphen (-) must NOT be given at the beginning of the prefix name. 2190 The first character of all runtime options is AUTOMATICALLY the hyphen. 2191 2192 Level: advanced 2193 2194 .keywords: SNES, append, options, prefix, database 2195 2196 .seealso: SNESGetOptionsPrefix() 2197 @*/ 2198 PetscErrorCode PETSCSNES_DLLEXPORT SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 2199 { 2200 PetscErrorCode ierr; 2201 2202 PetscFunctionBegin; 2203 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2204 ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2205 ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 2206 PetscFunctionReturn(0); 2207 } 2208 2209 #undef __FUNCT__ 2210 #define __FUNCT__ "SNESGetOptionsPrefix" 2211 /*@C 2212 SNESGetOptionsPrefix - Sets the prefix used for searching for all 2213 SNES options in the database. 2214 2215 Not Collective 2216 2217 Input Parameter: 2218 . snes - the SNES context 2219 2220 Output Parameter: 2221 . prefix - pointer to the prefix string used 2222 2223 Notes: On the fortran side, the user should pass in a string 'prifix' of 2224 sufficient length to hold the prefix. 2225 2226 Level: advanced 2227 2228 .keywords: SNES, get, options, prefix, database 2229 2230 .seealso: SNESAppendOptionsPrefix() 2231 @*/ 2232 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 2233 { 2234 PetscErrorCode ierr; 2235 2236 PetscFunctionBegin; 2237 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2238 ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2239 PetscFunctionReturn(0); 2240 } 2241 2242 2243 #undef __FUNCT__ 2244 #define __FUNCT__ "SNESRegister" 2245 /*@C 2246 SNESRegister - See SNESRegisterDynamic() 2247 2248 Level: advanced 2249 @*/ 2250 PetscErrorCode PETSCSNES_DLLEXPORT SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 2251 { 2252 char fullname[PETSC_MAX_PATH_LEN]; 2253 PetscErrorCode ierr; 2254 2255 PetscFunctionBegin; 2256 ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 2257 ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 2258 PetscFunctionReturn(0); 2259 } 2260 2261 #undef __FUNCT__ 2262 #define __FUNCT__ "SNESTestLocalMin" 2263 PetscErrorCode PETSCSNES_DLLEXPORT SNESTestLocalMin(SNES snes) 2264 { 2265 PetscErrorCode ierr; 2266 PetscInt N,i,j; 2267 Vec u,uh,fh; 2268 PetscScalar value; 2269 PetscReal norm; 2270 2271 PetscFunctionBegin; 2272 ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 2273 ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 2274 ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 2275 2276 /* currently only works for sequential */ 2277 ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 2278 ierr = VecGetSize(u,&N);CHKERRQ(ierr); 2279 for (i=0; i<N; i++) { 2280 ierr = VecCopy(u,uh);CHKERRQ(ierr); 2281 ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 2282 for (j=-10; j<11; j++) { 2283 value = PetscSign(j)*exp(PetscAbs(j)-10.0); 2284 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 2285 ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 2286 ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 2287 ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 2288 value = -value; 2289 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 2290 } 2291 } 2292 ierr = VecDestroy(uh);CHKERRQ(ierr); 2293 ierr = VecDestroy(fh);CHKERRQ(ierr); 2294 PetscFunctionReturn(0); 2295 } 2296 2297 #undef __FUNCT__ 2298 #define __FUNCT__ "SNESKSPSetUseEW" 2299 /*@ 2300 SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 2301 computing relative tolerance for linear solvers within an inexact 2302 Newton method. 2303 2304 Collective on SNES 2305 2306 Input Parameters: 2307 + snes - SNES context 2308 - flag - PETSC_TRUE or PETSC_FALSE 2309 2310 Notes: 2311 Currently, the default is to use a constant relative tolerance for 2312 the inner linear solvers. Alternatively, one can use the 2313 Eisenstat-Walker method, where the relative convergence tolerance 2314 is reset at each Newton iteration according progress of the nonlinear 2315 solver. 2316 2317 Level: advanced 2318 2319 Reference: 2320 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 2321 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 2322 2323 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 2324 2325 .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 2326 @*/ 2327 PetscErrorCode PETSCSNES_DLLEXPORT SNESKSPSetUseEW(SNES snes,PetscTruth flag) 2328 { 2329 PetscFunctionBegin; 2330 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2331 snes->ksp_ewconv = flag; 2332 PetscFunctionReturn(0); 2333 } 2334 2335 #undef __FUNCT__ 2336 #define __FUNCT__ "SNESKSPGetUseEW" 2337 /*@ 2338 SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 2339 for computing relative tolerance for linear solvers within an 2340 inexact Newton method. 2341 2342 Not Collective 2343 2344 Input Parameter: 2345 . snes - SNES context 2346 2347 Output Parameter: 2348 . flag - PETSC_TRUE or PETSC_FALSE 2349 2350 Notes: 2351 Currently, the default is to use a constant relative tolerance for 2352 the inner linear solvers. Alternatively, one can use the 2353 Eisenstat-Walker method, where the relative convergence tolerance 2354 is reset at each Newton iteration according progress of the nonlinear 2355 solver. 2356 2357 Level: advanced 2358 2359 Reference: 2360 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 2361 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 2362 2363 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 2364 2365 .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 2366 @*/ 2367 PetscErrorCode PETSCSNES_DLLEXPORT SNESKSPGetUseEW(SNES snes, PetscTruth *flag) 2368 { 2369 PetscFunctionBegin; 2370 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2371 PetscValidPointer(flag,2); 2372 *flag = snes->ksp_ewconv; 2373 PetscFunctionReturn(0); 2374 } 2375 2376 #undef __FUNCT__ 2377 #define __FUNCT__ "SNESKSPSetParametersEW" 2378 /*@ 2379 SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 2380 convergence criteria for the linear solvers within an inexact 2381 Newton method. 2382 2383 Collective on SNES 2384 2385 Input Parameters: 2386 + snes - SNES context 2387 . version - version 1, 2 (default is 2) or 3 2388 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 2389 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 2390 . gamma - multiplicative factor for version 2 rtol computation 2391 (0 <= gamma2 <= 1) 2392 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 2393 . alpha2 - power for safeguard 2394 - threshold - threshold for imposing safeguard (0 < threshold < 1) 2395 2396 Note: 2397 Version 3 was contributed by Luis Chacon, June 2006. 2398 2399 Use PETSC_DEFAULT to retain the default for any of the parameters. 2400 2401 Level: advanced 2402 2403 Reference: 2404 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 2405 inexact Newton method", Utah State University Math. Stat. Dept. Res. 2406 Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 2407 2408 .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 2409 2410 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 2411 @*/ 2412 PetscErrorCode PETSCSNES_DLLEXPORT SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 2413 PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 2414 { 2415 SNESKSPEW *kctx; 2416 PetscFunctionBegin; 2417 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2418 kctx = (SNESKSPEW*)snes->kspconvctx; 2419 if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 2420 2421 if (version != PETSC_DEFAULT) kctx->version = version; 2422 if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 2423 if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 2424 if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 2425 if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 2426 if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 2427 if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 2428 2429 if (kctx->version < 1 || kctx->version > 3) { 2430 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 2431 } 2432 if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 2433 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 2434 } 2435 if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 2436 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 2437 } 2438 if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 2439 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 2440 } 2441 if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 2442 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 2443 } 2444 if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 2445 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 2446 } 2447 PetscFunctionReturn(0); 2448 } 2449 2450 #undef __FUNCT__ 2451 #define __FUNCT__ "SNESKSPGetParametersEW" 2452 /*@ 2453 SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 2454 convergence criteria for the linear solvers within an inexact 2455 Newton method. 2456 2457 Not Collective 2458 2459 Input Parameters: 2460 snes - SNES context 2461 2462 Output Parameters: 2463 + version - version 1, 2 (default is 2) or 3 2464 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 2465 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 2466 . gamma - multiplicative factor for version 2 rtol computation 2467 (0 <= gamma2 <= 1) 2468 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 2469 . alpha2 - power for safeguard 2470 - threshold - threshold for imposing safeguard (0 < threshold < 1) 2471 2472 Level: advanced 2473 2474 .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 2475 2476 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 2477 @*/ 2478 PetscErrorCode PETSCSNES_DLLEXPORT SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 2479 PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 2480 { 2481 SNESKSPEW *kctx; 2482 PetscFunctionBegin; 2483 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2484 kctx = (SNESKSPEW*)snes->kspconvctx; 2485 if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 2486 if(version) *version = kctx->version; 2487 if(rtol_0) *rtol_0 = kctx->rtol_0; 2488 if(rtol_max) *rtol_max = kctx->rtol_max; 2489 if(gamma) *gamma = kctx->gamma; 2490 if(alpha) *alpha = kctx->alpha; 2491 if(alpha2) *alpha2 = kctx->alpha2; 2492 if(threshold) *threshold = kctx->threshold; 2493 PetscFunctionReturn(0); 2494 } 2495 2496 #undef __FUNCT__ 2497 #define __FUNCT__ "SNESKSPEW_PreSolve" 2498 static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 2499 { 2500 PetscErrorCode ierr; 2501 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 2502 PetscReal rtol=PETSC_DEFAULT,stol; 2503 2504 PetscFunctionBegin; 2505 if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 2506 if (!snes->iter) { /* first time in, so use the original user rtol */ 2507 rtol = kctx->rtol_0; 2508 } else { 2509 if (kctx->version == 1) { 2510 rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 2511 if (rtol < 0.0) rtol = -rtol; 2512 stol = pow(kctx->rtol_last,kctx->alpha2); 2513 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 2514 } else if (kctx->version == 2) { 2515 rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 2516 stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 2517 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 2518 } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 2519 rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 2520 /* safeguard: avoid sharp decrease of rtol */ 2521 stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 2522 stol = PetscMax(rtol,stol); 2523 rtol = PetscMin(kctx->rtol_0,stol); 2524 /* safeguard: avoid oversolving */ 2525 stol = kctx->gamma*(snes->ttol)/snes->norm; 2526 stol = PetscMax(rtol,stol); 2527 rtol = PetscMin(kctx->rtol_0,stol); 2528 } else SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 2529 } 2530 /* safeguard: avoid rtol greater than one */ 2531 rtol = PetscMin(rtol,kctx->rtol_max); 2532 ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 2533 ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 2534 PetscFunctionReturn(0); 2535 } 2536 2537 #undef __FUNCT__ 2538 #define __FUNCT__ "SNESKSPEW_PostSolve" 2539 static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 2540 { 2541 PetscErrorCode ierr; 2542 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 2543 PCSide pcside; 2544 Vec lres; 2545 2546 PetscFunctionBegin; 2547 if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 2548 ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 2549 ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 2550 if (kctx->version == 1) { 2551 ierr = KSPGetPreconditionerSide(ksp,&pcside);CHKERRQ(ierr); 2552 if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 2553 /* KSP residual is true linear residual */ 2554 ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 2555 } else { 2556 /* KSP residual is preconditioned residual */ 2557 /* compute true linear residual norm */ 2558 ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 2559 ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 2560 ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 2561 ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 2562 ierr = VecDestroy(lres);CHKERRQ(ierr); 2563 } 2564 } 2565 PetscFunctionReturn(0); 2566 } 2567 2568 #undef __FUNCT__ 2569 #define __FUNCT__ "SNES_KSPSolve" 2570 PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 2571 { 2572 PetscErrorCode ierr; 2573 2574 PetscFunctionBegin; 2575 if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 2576 ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 2577 if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 2578 PetscFunctionReturn(0); 2579 } 2580