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