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