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