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