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 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_reset = reset; 1707 PetscFunctionReturn(0); 1708 } 1709 1710 #undef __FUNCT__ 1711 #define __FUNCT__ "SNESGetConvergenceHistory" 1712 /*@C 1713 SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 1714 1715 Collective on SNES 1716 1717 Input Parameter: 1718 . snes - iterative context obtained from SNESCreate() 1719 1720 Output Parameters: 1721 . a - array to hold history 1722 . its - integer array holds the number of linear iterations (or 1723 negative if not converged) for each solve. 1724 - na - size of a and its 1725 1726 Notes: 1727 The calling sequence for this routine in Fortran is 1728 $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 1729 1730 This routine is useful, e.g., when running a code for purposes 1731 of accurate performance monitoring, when no I/O should be done 1732 during the section of code that is being timed. 1733 1734 Level: intermediate 1735 1736 .keywords: SNES, get, convergence, history 1737 1738 .seealso: SNESSetConvergencHistory() 1739 1740 @*/ 1741 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 1742 { 1743 PetscFunctionBegin; 1744 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1745 if (a) *a = snes->conv_hist; 1746 if (its) *its = snes->conv_hist_its; 1747 if (na) *na = snes->conv_hist_len; 1748 PetscFunctionReturn(0); 1749 } 1750 1751 #undef __FUNCT__ 1752 #define __FUNCT__ "SNESSetUpdate" 1753 /*@C 1754 SNESSetUpdate - Sets the general-purpose update function called 1755 at the beginning o every iteration of the nonlinear solve. Specifically 1756 it is called just before the Jacobian is "evaluated". 1757 1758 Collective on SNES 1759 1760 Input Parameters: 1761 . snes - The nonlinear solver context 1762 . func - The function 1763 1764 Calling sequence of func: 1765 . func (SNES snes, PetscInt step); 1766 1767 . step - The current step of the iteration 1768 1769 Level: intermediate 1770 1771 .keywords: SNES, update 1772 1773 .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 1774 @*/ 1775 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 1776 { 1777 PetscFunctionBegin; 1778 PetscValidHeaderSpecific(snes, SNES_COOKIE,1); 1779 snes->ops->update = func; 1780 PetscFunctionReturn(0); 1781 } 1782 1783 #undef __FUNCT__ 1784 #define __FUNCT__ "SNESDefaultUpdate" 1785 /*@ 1786 SNESDefaultUpdate - The default update function which does nothing. 1787 1788 Not collective 1789 1790 Input Parameters: 1791 . snes - The nonlinear solver context 1792 . step - The current step of the iteration 1793 1794 Level: intermediate 1795 1796 .keywords: SNES, update 1797 .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 1798 @*/ 1799 PetscErrorCode PETSCSNES_DLLEXPORT SNESDefaultUpdate(SNES snes, PetscInt step) 1800 { 1801 PetscFunctionBegin; 1802 PetscFunctionReturn(0); 1803 } 1804 1805 #undef __FUNCT__ 1806 #define __FUNCT__ "SNESScaleStep_Private" 1807 /* 1808 SNESScaleStep_Private - Scales a step so that its length is less than the 1809 positive parameter delta. 1810 1811 Input Parameters: 1812 + snes - the SNES context 1813 . y - approximate solution of linear system 1814 . fnorm - 2-norm of current function 1815 - delta - trust region size 1816 1817 Output Parameters: 1818 + gpnorm - predicted function norm at the new point, assuming local 1819 linearization. The value is zero if the step lies within the trust 1820 region, and exceeds zero otherwise. 1821 - ynorm - 2-norm of the step 1822 1823 Note: 1824 For non-trust region methods such as SNESLS, the parameter delta 1825 is set to be the maximum allowable step size. 1826 1827 .keywords: SNES, nonlinear, scale, step 1828 */ 1829 PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 1830 { 1831 PetscReal nrm; 1832 PetscScalar cnorm; 1833 PetscErrorCode ierr; 1834 1835 PetscFunctionBegin; 1836 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1837 PetscValidHeaderSpecific(y,VEC_COOKIE,2); 1838 PetscCheckSameComm(snes,1,y,2); 1839 1840 ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 1841 if (nrm > *delta) { 1842 nrm = *delta/nrm; 1843 *gpnorm = (1.0 - nrm)*(*fnorm); 1844 cnorm = nrm; 1845 ierr = VecScale(y,cnorm);CHKERRQ(ierr); 1846 *ynorm = *delta; 1847 } else { 1848 *gpnorm = 0.0; 1849 *ynorm = nrm; 1850 } 1851 PetscFunctionReturn(0); 1852 } 1853 1854 #undef __FUNCT__ 1855 #define __FUNCT__ "SNESSolve" 1856 /*@C 1857 SNESSolve - Solves a nonlinear system F(x) = b. 1858 Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 1859 1860 Collective on SNES 1861 1862 Input Parameters: 1863 + snes - the SNES context 1864 . b - the constant part of the equation, or PETSC_NULL to use zero. 1865 - x - the solution vector. 1866 1867 Notes: 1868 The user should initialize the vector,x, with the initial guess 1869 for the nonlinear solve prior to calling SNESSolve. In particular, 1870 to employ an initial guess of zero, the user should explicitly set 1871 this vector to zero by calling VecSet(). 1872 1873 Level: beginner 1874 1875 .keywords: SNES, nonlinear, solve 1876 1877 .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian() 1878 @*/ 1879 PetscErrorCode PETSCSNES_DLLEXPORT SNESSolve(SNES snes,Vec b,Vec x) 1880 { 1881 PetscErrorCode ierr; 1882 PetscTruth flg; 1883 char filename[PETSC_MAX_PATH_LEN]; 1884 PetscViewer viewer; 1885 1886 PetscFunctionBegin; 1887 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1888 PetscValidHeaderSpecific(x,VEC_COOKIE,3); 1889 PetscCheckSameComm(snes,1,x,3); 1890 if (b) PetscValidHeaderSpecific(b,VEC_COOKIE,2); 1891 if (b) PetscCheckSameComm(snes,1,b,2); 1892 1893 /* set solution vector */ 1894 ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 1895 if (snes->vec_sol) { ierr = VecDestroy(snes->vec_sol);CHKERRQ(ierr); } 1896 snes->vec_sol = x; 1897 /* set afine vector if provided */ 1898 if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 1899 if (snes->vec_rhs) { ierr = VecDestroy(snes->vec_rhs);CHKERRQ(ierr); } 1900 snes->vec_rhs = b; 1901 1902 if (!snes->vec_func && snes->vec_rhs) { 1903 ierr = VecDuplicate(b, &snes->vec_func); CHKERRQ(ierr); 1904 } 1905 1906 ierr = SNESSetUp(snes);CHKERRQ(ierr); 1907 1908 if (snes->conv_hist_reset) snes->conv_hist_len = 0; 1909 snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 1910 1911 ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 1912 ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 1913 ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 1914 if (snes->domainerror){ 1915 snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 1916 snes->domainerror = PETSC_FALSE; 1917 } 1918 1919 if (!snes->reason) { 1920 SETERRQ(PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 1921 } 1922 1923 ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 1924 if (flg && !PetscPreLoadingOn) { 1925 ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 1926 ierr = SNESView(snes,viewer);CHKERRQ(ierr); 1927 ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr); 1928 } 1929 1930 ierr = PetscOptionsHasName(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg);CHKERRQ(ierr); 1931 if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 1932 if (snes->printreason) { 1933 if (snes->reason > 0) { 1934 ierr = PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 1935 } else { 1936 ierr = PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 1937 } 1938 } 1939 1940 PetscFunctionReturn(0); 1941 } 1942 1943 /* --------- Internal routines for SNES Package --------- */ 1944 1945 #undef __FUNCT__ 1946 #define __FUNCT__ "SNESSetType" 1947 /*@C 1948 SNESSetType - Sets the method for the nonlinear solver. 1949 1950 Collective on SNES 1951 1952 Input Parameters: 1953 + snes - the SNES context 1954 - type - a known method 1955 1956 Options Database Key: 1957 . -snes_type <type> - Sets the method; use -help for a list 1958 of available methods (for instance, ls or tr) 1959 1960 Notes: 1961 See "petsc/include/petscsnes.h" for available methods (for instance) 1962 + SNESLS - Newton's method with line search 1963 (systems of nonlinear equations) 1964 . SNESTR - Newton's method with trust region 1965 (systems of nonlinear equations) 1966 1967 Normally, it is best to use the SNESSetFromOptions() command and then 1968 set the SNES solver type from the options database rather than by using 1969 this routine. Using the options database provides the user with 1970 maximum flexibility in evaluating the many nonlinear solvers. 1971 The SNESSetType() routine is provided for those situations where it 1972 is necessary to set the nonlinear solver independently of the command 1973 line or options database. This might be the case, for example, when 1974 the choice of solver changes during the execution of the program, 1975 and the user's application is taking responsibility for choosing the 1976 appropriate method. 1977 1978 Level: intermediate 1979 1980 .keywords: SNES, set, type 1981 1982 .seealso: SNESType, SNESCreate() 1983 1984 @*/ 1985 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetType(SNES snes,SNESType type) 1986 { 1987 PetscErrorCode ierr,(*r)(SNES); 1988 PetscTruth match; 1989 1990 PetscFunctionBegin; 1991 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 1992 PetscValidCharPointer(type,2); 1993 1994 ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 1995 if (match) PetscFunctionReturn(0); 1996 1997 ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,(void (**)(void)) &r);CHKERRQ(ierr); 1998 if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 1999 /* Destroy the previous private SNES context */ 2000 if (snes->ops->destroy) { ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); } 2001 /* Reinitialize function pointers in SNESOps structure */ 2002 snes->ops->setup = 0; 2003 snes->ops->solve = 0; 2004 snes->ops->view = 0; 2005 snes->ops->setfromoptions = 0; 2006 snes->ops->destroy = 0; 2007 /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 2008 snes->setupcalled = PETSC_FALSE; 2009 ierr = (*r)(snes);CHKERRQ(ierr); 2010 ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 2011 PetscFunctionReturn(0); 2012 } 2013 2014 2015 /* --------------------------------------------------------------------- */ 2016 #undef __FUNCT__ 2017 #define __FUNCT__ "SNESRegisterDestroy" 2018 /*@ 2019 SNESRegisterDestroy - Frees the list of nonlinear solvers that were 2020 registered by SNESRegisterDynamic(). 2021 2022 Not Collective 2023 2024 Level: advanced 2025 2026 .keywords: SNES, nonlinear, register, destroy 2027 2028 .seealso: SNESRegisterAll(), SNESRegisterAll() 2029 @*/ 2030 PetscErrorCode PETSCSNES_DLLEXPORT SNESRegisterDestroy(void) 2031 { 2032 PetscErrorCode ierr; 2033 2034 PetscFunctionBegin; 2035 ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 2036 SNESRegisterAllCalled = PETSC_FALSE; 2037 PetscFunctionReturn(0); 2038 } 2039 2040 #undef __FUNCT__ 2041 #define __FUNCT__ "SNESGetType" 2042 /*@C 2043 SNESGetType - Gets the SNES method type and name (as a string). 2044 2045 Not Collective 2046 2047 Input Parameter: 2048 . snes - nonlinear solver context 2049 2050 Output Parameter: 2051 . type - SNES method (a character string) 2052 2053 Level: intermediate 2054 2055 .keywords: SNES, nonlinear, get, type, name 2056 @*/ 2057 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetType(SNES snes,SNESType *type) 2058 { 2059 PetscFunctionBegin; 2060 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2061 PetscValidPointer(type,2); 2062 *type = ((PetscObject)snes)->type_name; 2063 PetscFunctionReturn(0); 2064 } 2065 2066 #undef __FUNCT__ 2067 #define __FUNCT__ "SNESGetSolution" 2068 /*@ 2069 SNESGetSolution - Returns the vector where the approximate solution is 2070 stored. 2071 2072 Not Collective, but Vec is parallel if SNES is parallel 2073 2074 Input Parameter: 2075 . snes - the SNES context 2076 2077 Output Parameter: 2078 . x - the solution 2079 2080 Level: intermediate 2081 2082 .keywords: SNES, nonlinear, get, solution 2083 2084 .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 2085 @*/ 2086 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetSolution(SNES snes,Vec *x) 2087 { 2088 PetscFunctionBegin; 2089 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2090 PetscValidPointer(x,2); 2091 *x = snes->vec_sol; 2092 PetscFunctionReturn(0); 2093 } 2094 2095 #undef __FUNCT__ 2096 #define __FUNCT__ "SNESGetSolutionUpdate" 2097 /*@ 2098 SNESGetSolutionUpdate - Returns the vector where the solution update is 2099 stored. 2100 2101 Not Collective, but Vec is parallel if SNES is parallel 2102 2103 Input Parameter: 2104 . snes - the SNES context 2105 2106 Output Parameter: 2107 . x - the solution update 2108 2109 Level: advanced 2110 2111 .keywords: SNES, nonlinear, get, solution, update 2112 2113 .seealso: SNESGetSolution(), SNESGetFunction() 2114 @*/ 2115 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetSolutionUpdate(SNES snes,Vec *x) 2116 { 2117 PetscFunctionBegin; 2118 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2119 PetscValidPointer(x,2); 2120 *x = snes->vec_sol_update; 2121 PetscFunctionReturn(0); 2122 } 2123 2124 #undef __FUNCT__ 2125 #define __FUNCT__ "SNESGetFunction" 2126 /*@C 2127 SNESGetFunction - Returns the vector where the function is stored. 2128 2129 Not Collective, but Vec is parallel if SNES is parallel 2130 2131 Input Parameter: 2132 . snes - the SNES context 2133 2134 Output Parameter: 2135 + r - the function (or PETSC_NULL) 2136 . func - the function (or PETSC_NULL) 2137 - ctx - the function context (or PETSC_NULL) 2138 2139 Level: advanced 2140 2141 .keywords: SNES, nonlinear, get, function 2142 2143 .seealso: SNESSetFunction(), SNESGetSolution() 2144 @*/ 2145 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 2146 { 2147 PetscFunctionBegin; 2148 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2149 if (r) *r = snes->vec_func; 2150 if (func) *func = snes->ops->computefunction; 2151 if (ctx) *ctx = snes->funP; 2152 PetscFunctionReturn(0); 2153 } 2154 2155 #undef __FUNCT__ 2156 #define __FUNCT__ "SNESSetOptionsPrefix" 2157 /*@C 2158 SNESSetOptionsPrefix - Sets the prefix used for searching for all 2159 SNES options in the database. 2160 2161 Collective on SNES 2162 2163 Input Parameter: 2164 + snes - the SNES context 2165 - prefix - the prefix to prepend to all option names 2166 2167 Notes: 2168 A hyphen (-) must NOT be given at the beginning of the prefix name. 2169 The first character of all runtime options is AUTOMATICALLY the hyphen. 2170 2171 Level: advanced 2172 2173 .keywords: SNES, set, options, prefix, database 2174 2175 .seealso: SNESSetFromOptions() 2176 @*/ 2177 PetscErrorCode PETSCSNES_DLLEXPORT SNESSetOptionsPrefix(SNES snes,const char prefix[]) 2178 { 2179 PetscErrorCode ierr; 2180 2181 PetscFunctionBegin; 2182 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2183 ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2184 ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 2185 PetscFunctionReturn(0); 2186 } 2187 2188 #undef __FUNCT__ 2189 #define __FUNCT__ "SNESAppendOptionsPrefix" 2190 /*@C 2191 SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 2192 SNES options in the database. 2193 2194 Collective on SNES 2195 2196 Input Parameters: 2197 + snes - the SNES context 2198 - prefix - the prefix to prepend to all option names 2199 2200 Notes: 2201 A hyphen (-) must NOT be given at the beginning of the prefix name. 2202 The first character of all runtime options is AUTOMATICALLY the hyphen. 2203 2204 Level: advanced 2205 2206 .keywords: SNES, append, options, prefix, database 2207 2208 .seealso: SNESGetOptionsPrefix() 2209 @*/ 2210 PetscErrorCode PETSCSNES_DLLEXPORT SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 2211 { 2212 PetscErrorCode ierr; 2213 2214 PetscFunctionBegin; 2215 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2216 ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2217 ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 2218 PetscFunctionReturn(0); 2219 } 2220 2221 #undef __FUNCT__ 2222 #define __FUNCT__ "SNESGetOptionsPrefix" 2223 /*@C 2224 SNESGetOptionsPrefix - Sets the prefix used for searching for all 2225 SNES options in the database. 2226 2227 Not Collective 2228 2229 Input Parameter: 2230 . snes - the SNES context 2231 2232 Output Parameter: 2233 . prefix - pointer to the prefix string used 2234 2235 Notes: On the fortran side, the user should pass in a string 'prefix' of 2236 sufficient length to hold the prefix. 2237 2238 Level: advanced 2239 2240 .keywords: SNES, get, options, prefix, database 2241 2242 .seealso: SNESAppendOptionsPrefix() 2243 @*/ 2244 PetscErrorCode PETSCSNES_DLLEXPORT SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 2245 { 2246 PetscErrorCode ierr; 2247 2248 PetscFunctionBegin; 2249 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2250 ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2251 PetscFunctionReturn(0); 2252 } 2253 2254 2255 #undef __FUNCT__ 2256 #define __FUNCT__ "SNESRegister" 2257 /*@C 2258 SNESRegister - See SNESRegisterDynamic() 2259 2260 Level: advanced 2261 @*/ 2262 PetscErrorCode PETSCSNES_DLLEXPORT SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 2263 { 2264 char fullname[PETSC_MAX_PATH_LEN]; 2265 PetscErrorCode ierr; 2266 2267 PetscFunctionBegin; 2268 ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 2269 ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 2270 PetscFunctionReturn(0); 2271 } 2272 2273 #undef __FUNCT__ 2274 #define __FUNCT__ "SNESTestLocalMin" 2275 PetscErrorCode PETSCSNES_DLLEXPORT SNESTestLocalMin(SNES snes) 2276 { 2277 PetscErrorCode ierr; 2278 PetscInt N,i,j; 2279 Vec u,uh,fh; 2280 PetscScalar value; 2281 PetscReal norm; 2282 2283 PetscFunctionBegin; 2284 ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 2285 ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 2286 ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 2287 2288 /* currently only works for sequential */ 2289 ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 2290 ierr = VecGetSize(u,&N);CHKERRQ(ierr); 2291 for (i=0; i<N; i++) { 2292 ierr = VecCopy(u,uh);CHKERRQ(ierr); 2293 ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 2294 for (j=-10; j<11; j++) { 2295 value = PetscSign(j)*exp(PetscAbs(j)-10.0); 2296 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 2297 ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 2298 ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 2299 ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 2300 value = -value; 2301 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 2302 } 2303 } 2304 ierr = VecDestroy(uh);CHKERRQ(ierr); 2305 ierr = VecDestroy(fh);CHKERRQ(ierr); 2306 PetscFunctionReturn(0); 2307 } 2308 2309 #undef __FUNCT__ 2310 #define __FUNCT__ "SNESKSPSetUseEW" 2311 /*@ 2312 SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 2313 computing relative tolerance for linear solvers within an inexact 2314 Newton method. 2315 2316 Collective on SNES 2317 2318 Input Parameters: 2319 + snes - SNES context 2320 - flag - PETSC_TRUE or PETSC_FALSE 2321 2322 Notes: 2323 Currently, the default is to use a constant relative tolerance for 2324 the inner linear solvers. Alternatively, one can use the 2325 Eisenstat-Walker method, where the relative convergence tolerance 2326 is reset at each Newton iteration according progress of the nonlinear 2327 solver. 2328 2329 Level: advanced 2330 2331 Reference: 2332 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 2333 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 2334 2335 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 2336 2337 .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 2338 @*/ 2339 PetscErrorCode PETSCSNES_DLLEXPORT SNESKSPSetUseEW(SNES snes,PetscTruth flag) 2340 { 2341 PetscFunctionBegin; 2342 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2343 snes->ksp_ewconv = flag; 2344 PetscFunctionReturn(0); 2345 } 2346 2347 #undef __FUNCT__ 2348 #define __FUNCT__ "SNESKSPGetUseEW" 2349 /*@ 2350 SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 2351 for computing relative tolerance for linear solvers within an 2352 inexact Newton method. 2353 2354 Not Collective 2355 2356 Input Parameter: 2357 . snes - SNES context 2358 2359 Output Parameter: 2360 . flag - PETSC_TRUE or PETSC_FALSE 2361 2362 Notes: 2363 Currently, the default is to use a constant relative tolerance for 2364 the inner linear solvers. Alternatively, one can use the 2365 Eisenstat-Walker method, where the relative convergence tolerance 2366 is reset at each Newton iteration according progress of the nonlinear 2367 solver. 2368 2369 Level: advanced 2370 2371 Reference: 2372 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 2373 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 2374 2375 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 2376 2377 .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 2378 @*/ 2379 PetscErrorCode PETSCSNES_DLLEXPORT SNESKSPGetUseEW(SNES snes, PetscTruth *flag) 2380 { 2381 PetscFunctionBegin; 2382 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2383 PetscValidPointer(flag,2); 2384 *flag = snes->ksp_ewconv; 2385 PetscFunctionReturn(0); 2386 } 2387 2388 #undef __FUNCT__ 2389 #define __FUNCT__ "SNESKSPSetParametersEW" 2390 /*@ 2391 SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 2392 convergence criteria for the linear solvers within an inexact 2393 Newton method. 2394 2395 Collective on SNES 2396 2397 Input Parameters: 2398 + snes - SNES context 2399 . version - version 1, 2 (default is 2) or 3 2400 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 2401 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 2402 . gamma - multiplicative factor for version 2 rtol computation 2403 (0 <= gamma2 <= 1) 2404 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 2405 . alpha2 - power for safeguard 2406 - threshold - threshold for imposing safeguard (0 < threshold < 1) 2407 2408 Note: 2409 Version 3 was contributed by Luis Chacon, June 2006. 2410 2411 Use PETSC_DEFAULT to retain the default for any of the parameters. 2412 2413 Level: advanced 2414 2415 Reference: 2416 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 2417 inexact Newton method", Utah State University Math. Stat. Dept. Res. 2418 Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 2419 2420 .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 2421 2422 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 2423 @*/ 2424 PetscErrorCode PETSCSNES_DLLEXPORT SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 2425 PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 2426 { 2427 SNESKSPEW *kctx; 2428 PetscFunctionBegin; 2429 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2430 kctx = (SNESKSPEW*)snes->kspconvctx; 2431 if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 2432 2433 if (version != PETSC_DEFAULT) kctx->version = version; 2434 if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 2435 if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 2436 if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 2437 if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 2438 if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 2439 if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 2440 2441 if (kctx->version < 1 || kctx->version > 3) { 2442 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 2443 } 2444 if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 2445 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 2446 } 2447 if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 2448 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 2449 } 2450 if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 2451 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 2452 } 2453 if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 2454 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 2455 } 2456 if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 2457 SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 2458 } 2459 PetscFunctionReturn(0); 2460 } 2461 2462 #undef __FUNCT__ 2463 #define __FUNCT__ "SNESKSPGetParametersEW" 2464 /*@ 2465 SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 2466 convergence criteria for the linear solvers within an inexact 2467 Newton method. 2468 2469 Not Collective 2470 2471 Input Parameters: 2472 snes - SNES context 2473 2474 Output Parameters: 2475 + version - version 1, 2 (default is 2) or 3 2476 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 2477 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 2478 . gamma - multiplicative factor for version 2 rtol computation 2479 (0 <= gamma2 <= 1) 2480 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 2481 . alpha2 - power for safeguard 2482 - threshold - threshold for imposing safeguard (0 < threshold < 1) 2483 2484 Level: advanced 2485 2486 .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 2487 2488 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 2489 @*/ 2490 PetscErrorCode PETSCSNES_DLLEXPORT SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 2491 PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 2492 { 2493 SNESKSPEW *kctx; 2494 PetscFunctionBegin; 2495 PetscValidHeaderSpecific(snes,SNES_COOKIE,1); 2496 kctx = (SNESKSPEW*)snes->kspconvctx; 2497 if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 2498 if(version) *version = kctx->version; 2499 if(rtol_0) *rtol_0 = kctx->rtol_0; 2500 if(rtol_max) *rtol_max = kctx->rtol_max; 2501 if(gamma) *gamma = kctx->gamma; 2502 if(alpha) *alpha = kctx->alpha; 2503 if(alpha2) *alpha2 = kctx->alpha2; 2504 if(threshold) *threshold = kctx->threshold; 2505 PetscFunctionReturn(0); 2506 } 2507 2508 #undef __FUNCT__ 2509 #define __FUNCT__ "SNESKSPEW_PreSolve" 2510 static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 2511 { 2512 PetscErrorCode ierr; 2513 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 2514 PetscReal rtol=PETSC_DEFAULT,stol; 2515 2516 PetscFunctionBegin; 2517 if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 2518 if (!snes->iter) { /* first time in, so use the original user rtol */ 2519 rtol = kctx->rtol_0; 2520 } else { 2521 if (kctx->version == 1) { 2522 rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 2523 if (rtol < 0.0) rtol = -rtol; 2524 stol = pow(kctx->rtol_last,kctx->alpha2); 2525 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 2526 } else if (kctx->version == 2) { 2527 rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 2528 stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 2529 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 2530 } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 2531 rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 2532 /* safeguard: avoid sharp decrease of rtol */ 2533 stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 2534 stol = PetscMax(rtol,stol); 2535 rtol = PetscMin(kctx->rtol_0,stol); 2536 /* safeguard: avoid oversolving */ 2537 stol = kctx->gamma*(snes->ttol)/snes->norm; 2538 stol = PetscMax(rtol,stol); 2539 rtol = PetscMin(kctx->rtol_0,stol); 2540 } else SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 2541 } 2542 /* safeguard: avoid rtol greater than one */ 2543 rtol = PetscMin(rtol,kctx->rtol_max); 2544 ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 2545 ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 2546 PetscFunctionReturn(0); 2547 } 2548 2549 #undef __FUNCT__ 2550 #define __FUNCT__ "SNESKSPEW_PostSolve" 2551 static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 2552 { 2553 PetscErrorCode ierr; 2554 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 2555 PCSide pcside; 2556 Vec lres; 2557 2558 PetscFunctionBegin; 2559 if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 2560 ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 2561 ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 2562 if (kctx->version == 1) { 2563 ierr = KSPGetPreconditionerSide(ksp,&pcside);CHKERRQ(ierr); 2564 if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 2565 /* KSP residual is true linear residual */ 2566 ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 2567 } else { 2568 /* KSP residual is preconditioned residual */ 2569 /* compute true linear residual norm */ 2570 ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 2571 ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 2572 ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 2573 ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 2574 ierr = VecDestroy(lres);CHKERRQ(ierr); 2575 } 2576 } 2577 PetscFunctionReturn(0); 2578 } 2579 2580 #undef __FUNCT__ 2581 #define __FUNCT__ "SNES_KSPSolve" 2582 PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 2583 { 2584 PetscErrorCode ierr; 2585 2586 PetscFunctionBegin; 2587 if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 2588 ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 2589 if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 2590 PetscFunctionReturn(0); 2591 } 2592