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