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