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