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