1 #ifndef lint 2 static char vcid[] = "$Id: snes.c,v 1.28 1995/12/21 18:33:54 bsmith Exp bsmith $"; 3 #endif 4 5 #include "draw.h" /*I "draw.h" I*/ 6 #include "snesimpl.h" /*I "snes.h" I*/ 7 #include "sys/nreg.h" /*I "sys/nreg.h" I*/ 8 #include "pinclude/pviewer.h" 9 #include <math.h> 10 11 extern int SNESGetTypeFromOptions_Private(SNES,SNESType*); 12 extern int SNESPrintTypes_Private(char*,char*); 13 14 /*@ 15 SNESView - Prints the SNES data structure. 16 17 Input Parameters: 18 . SNES - the SNES context 19 . viewer - visualization context 20 21 Options Database Key: 22 $ -snes_view : calls SNESView() at end of SNESSolve() 23 24 Notes: 25 The available visualization contexts include 26 $ STDOUT_VIEWER_SELF - standard output (default) 27 $ STDOUT_VIEWER_WORLD - synchronized standard 28 $ output where only the first processor opens 29 $ the file. All other processors send their 30 $ data to the first processor to print. 31 32 The user can open alternative vistualization contexts with 33 $ ViewerFileOpenASCII() - output to a specified file 34 35 .keywords: SNES, view 36 37 .seealso: ViewerFileOpenASCII() 38 @*/ 39 int SNESView(SNES snes,Viewer viewer) 40 { 41 PetscObject vobj = (PetscObject) viewer; 42 SNES_KSP_EW_ConvCtx *kctx; 43 FILE *fd; 44 int ierr; 45 SLES sles; 46 char *method; 47 48 if (vobj->cookie == VIEWER_COOKIE && (vobj->type == ASCII_FILE_VIEWER || 49 vobj->type == ASCII_FILES_VIEWER)) { 50 ierr = ViewerFileGetPointer_Private(viewer,&fd); CHKERRQ(ierr); 51 MPIU_fprintf(snes->comm,fd,"SNES Object:\n"); 52 SNESGetType(snes,PETSC_NULL,&method); 53 MPIU_fprintf(snes->comm,fd," method: %s\n",method); 54 if (snes->view) (*snes->view)((PetscObject)snes,viewer); 55 MPIU_fprintf(snes->comm,fd, 56 " maximum iterations=%d, maximum function evaluations=%d\n", 57 snes->max_its,snes->max_funcs); 58 MPIU_fprintf(snes->comm,fd, 59 " tolerances: relative=%g, absolute=%g, truncation=%g, solution=%g\n", 60 snes->rtol, snes->atol, snes->trunctol, snes->xtol); 61 if (snes->method_class == SNES_UNCONSTRAINED_MINIMIZATION) 62 MPIU_fprintf(snes->comm,fd," min function tolerance=%g\n",snes->fmin); 63 if (snes->ksp_ewconv) { 64 kctx = (SNES_KSP_EW_ConvCtx *)snes->kspconvctx; 65 if (kctx) { 66 MPIU_fprintf(snes->comm,fd, 67 " Eisenstat-Walker computation of KSP relative tolerance (version %d)\n", 68 kctx->version); 69 MPIU_fprintf(snes->comm,fd, 70 " rtol_0=%g, rtol_max=%g, threshold=%g\n",kctx->rtol_0, 71 kctx->rtol_max,kctx->threshold); 72 MPIU_fprintf(snes->comm,fd," gamma=%g, alpha=%g, alpha2=%g\n", 73 kctx->gamma,kctx->alpha,kctx->alpha2); 74 } 75 } 76 SNESGetSLES(snes,&sles); 77 ierr = SLESView(sles,viewer); CHKERRQ(ierr); 78 } 79 return 0; 80 } 81 82 /*@ 83 SNESSetFromOptions - Sets various SLES parameters from user options. 84 85 Input Parameter: 86 . snes - the SNES context 87 88 .keywords: SNES, nonlinear, set, options, database 89 90 .seealso: SNESPrintHelp() 91 @*/ 92 int SNESSetFromOptions(SNES snes) 93 { 94 SNESType method; 95 double tmp; 96 SLES sles; 97 int ierr,version = PETSC_DEFAULT; 98 double rtol_0 = PETSC_DEFAULT; 99 double rtol_max = PETSC_DEFAULT; 100 double gamma2 = PETSC_DEFAULT; 101 double alpha = PETSC_DEFAULT; 102 double alpha2 = PETSC_DEFAULT; 103 double threshold = PETSC_DEFAULT; 104 105 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 106 if (snes->setup_called)SETERRQ(1,"SNESSetFromOptions:Must call prior to SNESSetUp!"); 107 if (SNESGetTypeFromOptions_Private(snes,&method)) { 108 SNESSetType(snes,method); 109 } 110 if (OptionsHasName(PETSC_NULL,"-help")) SNESPrintHelp(snes); 111 if (OptionsGetDouble(snes->prefix,"-snes_stol",&tmp)) { 112 SNESSetSolutionTolerance(snes,tmp); 113 } 114 if (OptionsGetDouble(snes->prefix,"-snes_ttol",&tmp)) { 115 SNESSetTruncationTolerance(snes,tmp); 116 } 117 if (OptionsGetDouble(snes->prefix,"-snes_atol",&tmp)) { 118 SNESSetAbsoluteTolerance(snes,tmp); 119 } 120 if (OptionsGetDouble(snes->prefix,"-snes_trtol",&tmp)) { 121 SNESSetTrustRegionTolerance(snes,tmp); 122 } 123 if (OptionsGetDouble(snes->prefix,"-snes_rtol",&tmp)) { 124 SNESSetRelativeTolerance(snes,tmp); 125 } 126 if (OptionsGetDouble(snes->prefix,"-snes_fmin",&tmp)) { 127 SNESSetMinFunctionTolerance(snes,tmp); 128 } 129 OptionsGetInt(snes->prefix,"-snes_max_it",&snes->max_its); 130 OptionsGetInt(snes->prefix,"-snes_max_funcs",&snes->max_funcs); 131 if (OptionsHasName(snes->prefix,"-snes_ksp_ew_conv")) { 132 snes->ksp_ewconv = 1; 133 } 134 OptionsGetInt(snes->prefix,"-snes_ksp_ew_version",&version); 135 OptionsGetDouble(snes->prefix,"-snes_ksp_ew_rtol0",&rtol_0); 136 OptionsGetDouble(snes->prefix,"-snes_ksp_ew_rtolmax",&rtol_max); 137 OptionsGetDouble(snes->prefix,"-snes_ksp_ew_gamma",&gamma2); 138 OptionsGetDouble(snes->prefix,"-snes_ksp_ew_alpha",&alpha); 139 OptionsGetDouble(snes->prefix,"-snes_ksp_ew_alpha2",&alpha2); 140 OptionsGetDouble(snes->prefix,"-snes_ksp_ew_threshold",&threshold); 141 ierr = SNES_KSP_SetParametersEW(snes,version,rtol_0,rtol_max,gamma2,alpha, 142 alpha2,threshold); CHKERRQ(ierr); 143 if (OptionsHasName(snes->prefix,"-snes_monitor")) { 144 SNESSetMonitor(snes,SNESDefaultMonitor,0); 145 } 146 if (OptionsHasName(snes->prefix,"-snes_smonitor")) { 147 SNESSetMonitor(snes,SNESDefaultSMonitor,0); 148 } 149 if (OptionsHasName(snes->prefix,"-snes_xmonitor")){ 150 int rank = 0; 151 DrawLG lg; 152 MPI_Initialized(&rank); 153 if (rank) MPI_Comm_rank(snes->comm,&rank); 154 if (!rank) { 155 ierr = SNESLGMonitorCreate(0,0,0,0,300,300,&lg); CHKERRQ(ierr); 156 ierr = SNESSetMonitor(snes,SNESLGMonitor,(void *)lg); CHKERRQ(ierr); 157 PLogObjectParent(snes,lg); 158 } 159 } 160 if (OptionsHasName(snes->prefix,"-snes_fd") && 161 snes->method_class == SNES_NONLINEAR_EQUATIONS) { 162 ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre, 163 SNESDefaultComputeJacobian,snes->funP); CHKERRQ(ierr); 164 } 165 if (OptionsHasName(snes->prefix,"-snes_mf") && 166 snes->method_class == SNES_NONLINEAR_EQUATIONS) { 167 Mat J; 168 ierr = SNESDefaultMatrixFreeMatCreate(snes,snes->vec_sol,&J);CHKERRQ(ierr); 169 ierr = SNESSetJacobian(snes,J,J,0,snes->funP); CHKERRQ(ierr); 170 PLogObjectParent(snes,J); 171 snes->mfshell = J; 172 } 173 ierr = SNESGetSLES(snes,&sles); CHKERRQ(ierr); 174 ierr = SLESSetFromOptions(sles); CHKERRQ(ierr); 175 if (!snes->setfromoptions) return 0; 176 return (*snes->setfromoptions)(snes); 177 } 178 179 /*@ 180 SNESPrintHelp - Prints all options for the SNES component. 181 182 Input Parameter: 183 . snes - the SNES context 184 185 Options Database Keys: 186 $ -help, -h 187 188 .keywords: SNES, nonlinear, help 189 190 .seealso: SLESSetFromOptions() 191 @*/ 192 int SNESPrintHelp(SNES snes) 193 { 194 char *prefix = "-"; 195 SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx *)snes->kspconvctx; 196 if (snes->prefix) prefix = snes->prefix; 197 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 198 MPIU_printf(snes->comm,"SNES options ----------------------------\n"); 199 SNESPrintTypes_Private(prefix,"snes_type"); 200 MPIU_printf(snes->comm," %ssnes_monitor: use default SNES monitor\n",prefix); 201 MPIU_printf(snes->comm," %ssnes_view: view SNES info after each nonlinear solve\n",prefix); 202 MPIU_printf(snes->comm," %ssnes_max_it its (default %d)\n",prefix,snes->max_its); 203 MPIU_printf(snes->comm," %ssnes_stol tol (default %g)\n",prefix,snes->xtol); 204 MPIU_printf(snes->comm," %ssnes_atol tol (default %g)\n",prefix,snes->atol); 205 MPIU_printf(snes->comm," %ssnes_rtol tol (default %g)\n",prefix,snes->rtol); 206 MPIU_printf(snes->comm," %ssnes_ttol tol (default %g)\n",prefix,snes->trunctol); 207 MPIU_printf(snes->comm, 208 " options for solving systems of nonlinear equations only:\n"); 209 MPIU_printf(snes->comm," %ssnes_fd: use finite differences for Jacobian\n",prefix); 210 MPIU_printf(snes->comm," %ssnes_mf: use matrix-free Jacobian\n",prefix); 211 MPIU_printf(snes->comm," %ssnes_ksp_ew_conv: use Eisenstat-Walker computation of KSP rtol. Params are:\n",prefix); 212 MPIU_printf(snes->comm, 213 " %ssnes_ksp_ew_version version (1 or 2, default is %d)\n", 214 prefix,kctx->version); 215 MPIU_printf(snes->comm, 216 " %ssnes_ksp_ew_rtol0 rtol0 (0 <= rtol0 < 1, default %g)\n", 217 prefix,kctx->rtol_0); 218 MPIU_printf(snes->comm, 219 " %ssnes_ksp_ew_rtolmax rtolmax (0 <= rtolmax < 1, default %g)\n", 220 prefix,kctx->rtol_max); 221 MPIU_printf(snes->comm, 222 " %ssnes_ksp_ew_gamma gamma (0 <= gamma <= 1, default %g)\n", 223 prefix,kctx->gamma); 224 MPIU_printf(snes->comm, 225 " %ssnes_ksp_ew_alpha alpha (1 < alpha <= 2, default %g)\n", 226 prefix,kctx->alpha); 227 MPIU_printf(snes->comm, 228 " %ssnes_ksp_ew_alpha2 alpha2 (default %g)\n", 229 prefix,kctx->alpha2); 230 MPIU_printf(snes->comm, 231 " %ssnes_ksp_ew_threshold threshold (0 < threshold < 1, default %g)\n", 232 prefix,kctx->threshold); 233 MPIU_printf(snes->comm, 234 " options for solving unconstrained minimization problems only:\n"); 235 MPIU_printf(snes->comm," %ssnes_fmin tol (default %g)\n",prefix,snes->fmin); 236 MPIU_printf(snes->comm," Run program with %ssnes_type method -help for help on ",prefix); 237 MPIU_printf(snes->comm,"a particular method\n"); 238 if (snes->printhelp) (*snes->printhelp)(snes); 239 return 0; 240 } 241 /*@ 242 SNESSetApplicationContext - Sets the optional user-defined context for 243 the nonlinear solvers. 244 245 Input Parameters: 246 . snes - the SNES context 247 . usrP - optional user context 248 249 .keywords: SNES, nonlinear, set, application, context 250 251 .seealso: SNESGetApplicationContext() 252 @*/ 253 int SNESSetApplicationContext(SNES snes,void *usrP) 254 { 255 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 256 snes->user = usrP; 257 return 0; 258 } 259 /*@C 260 SNESGetApplicationContext - Gets the user-defined context for the 261 nonlinear solvers. 262 263 Input Parameter: 264 . snes - SNES context 265 266 Output Parameter: 267 . usrP - user context 268 269 .keywords: SNES, nonlinear, get, application, context 270 271 .seealso: SNESSetApplicationContext() 272 @*/ 273 int SNESGetApplicationContext( SNES snes, void **usrP ) 274 { 275 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 276 *usrP = snes->user; 277 return 0; 278 } 279 /*@ 280 SNESGetIterationNumber - Gets the current iteration number of the 281 nonlinear solver. 282 283 Input Parameter: 284 . snes - SNES context 285 286 Output Parameter: 287 . iter - iteration number 288 289 .keywords: SNES, nonlinear, get, iteration, number 290 @*/ 291 int SNESGetIterationNumber(SNES snes,int* iter) 292 { 293 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 294 *iter = snes->iter; 295 return 0; 296 } 297 /*@ 298 SNESGetFunctionNorm - Gets the norm of the current function that was set 299 with SNESSSetFunction(). 300 301 Input Parameter: 302 . snes - SNES context 303 304 Output Parameter: 305 . fnorm - 2-norm of function 306 307 Note: 308 SNESGetFunctionNorm() is valid for SNES_NONLINEAR_EQUATIONS methods only. 309 310 .keywords: SNES, nonlinear, get, function, norm 311 @*/ 312 int SNESGetFunctionNorm(SNES snes,Scalar *fnorm) 313 { 314 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 315 if (snes->method_class != SNES_NONLINEAR_EQUATIONS) SETERRQ(1, 316 "SNESGetFunctionNorm:For SNES_NONLINEAR_EQUATIONS only"); 317 *fnorm = snes->norm; 318 return 0; 319 } 320 /*@ 321 SNESGetGradientNorm - Gets the norm of the current gradient that was set 322 with SNESSSetGradient(). 323 324 Input Parameter: 325 . snes - SNES context 326 327 Output Parameter: 328 . fnorm - 2-norm of gradient 329 330 Note: 331 SNESGetGradientNorm() is valid for SNES_UNCONSTRAINED_MINIMIZATION 332 methods only. 333 334 .keywords: SNES, nonlinear, get, gradient, norm 335 @*/ 336 int SNESGetGradientNorm(SNES snes,Scalar *gnorm) 337 { 338 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 339 if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1, 340 "SNESGetGradientNorm:For SNES_UNCONSTRAINED_MINIMIZATION only"); 341 *gnorm = snes->norm; 342 return 0; 343 } 344 /*@ 345 SNESGetNumberUnsuccessfulSteps - Gets the number of unsuccessful steps 346 attempted by the nonlinear solver. 347 348 Input Parameter: 349 . snes - SNES context 350 351 Output Parameter: 352 . nfails - number of unsuccessful steps attempted 353 354 .keywords: SNES, nonlinear, get, number, unsuccessful, steps 355 @*/ 356 int SNESGetNumberUnsuccessfulSteps(SNES snes,int* nfails) 357 { 358 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 359 *nfails = snes->nfailures; 360 return 0; 361 } 362 /*@C 363 SNESGetSLES - Returns the SLES context for a SNES solver. 364 365 Input Parameter: 366 . snes - the SNES context 367 368 Output Parameter: 369 . sles - the SLES context 370 371 Notes: 372 The user can then directly manipulate the SLES context to set various 373 options, etc. Likewise, the user can then extract and manipulate the 374 KSP and PC contexts as well. 375 376 .keywords: SNES, nonlinear, get, SLES, context 377 378 .seealso: SLESGetPC(), SLESGetKSP() 379 @*/ 380 int SNESGetSLES(SNES snes,SLES *sles) 381 { 382 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 383 *sles = snes->sles; 384 return 0; 385 } 386 /* -----------------------------------------------------------*/ 387 /*@C 388 SNESCreate - Creates a nonlinear solver context. 389 390 Input Parameter: 391 . comm - MPI communicator 392 . type - type of method, one of 393 $ SNES_NONLINEAR_EQUATIONS 394 $ (for systems of nonlinear equations) 395 $ SNES_UNCONSTRAINED_MINIMIZATION 396 $ (for unconstrained minimization) 397 398 Output Parameter: 399 . outsnes - the new SNES context 400 401 .keywords: SNES, nonlinear, create, context 402 403 .seealso: SNESSetUp(), SNESSolve(), SNESDestroy() 404 @*/ 405 int SNESCreate(MPI_Comm comm,SNESProblemType type,SNES *outsnes) 406 { 407 int ierr; 408 SNES snes; 409 SNES_KSP_EW_ConvCtx *kctx; 410 *outsnes = 0; 411 PetscHeaderCreate(snes,_SNES,SNES_COOKIE,SNES_UNKNOWN_METHOD,comm); 412 PLogObjectCreate(snes); 413 snes->max_its = 50; 414 snes->max_funcs = 1000; 415 snes->norm = 0.0; 416 snes->rtol = 1.e-8; 417 snes->atol = 1.e-10; 418 snes->xtol = 1.e-8; 419 snes->trunctol = 1.e-12; 420 snes->nfuncs = 0; 421 snes->nfailures = 0; 422 snes->monitor = 0; 423 snes->data = 0; 424 snes->view = 0; 425 snes->computeumfunction = 0; 426 snes->umfunP = 0; 427 snes->fc = 0; 428 snes->deltatol = 1.e-12; 429 snes->fmin = -1.e30; 430 snes->method_class = type; 431 snes->set_method_called = 0; 432 snes->setup_called = 0; 433 snes->ksp_ewconv = 0; 434 435 /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 436 kctx = PetscNew(SNES_KSP_EW_ConvCtx); CHKPTRQ(kctx); 437 snes->kspconvctx = (void*)kctx; 438 kctx->version = 2; 439 kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 440 this was too large for some test cases */ 441 kctx->rtol_last = 0; 442 kctx->rtol_max = .9; 443 kctx->gamma = 1.0; 444 kctx->alpha2 = .5*(1.0 + sqrt(5.0)); 445 kctx->alpha = kctx->alpha2; 446 kctx->threshold = .1; 447 kctx->lresid_last = 0; 448 kctx->norm_last = 0; 449 450 ierr = SLESCreate(comm,&snes->sles); CHKERRQ(ierr); 451 PLogObjectParent(snes,snes->sles) 452 *outsnes = snes; 453 return 0; 454 } 455 456 /* --------------------------------------------------------------- */ 457 /*@C 458 SNESSetFunction - Sets the function evaluation routine and function 459 vector for use by the SNES routines in solving systems of nonlinear 460 equations. 461 462 Input Parameters: 463 . snes - the SNES context 464 . func - function evaluation routine 465 . resid_neg - indicator whether func evaluates f or -f. 466 If resid_neg is NEGATIVE_FUNCTION_VALUE, then func evaluates -f; otherwise, 467 func evaluates f. 468 . ctx - optional user-defined function context 469 . r - vector to store function value 470 471 Calling sequence of func: 472 . func (SNES, Vec x, Vec f, void *ctx); 473 474 . x - input vector 475 . f - function vector or its negative 476 . ctx - optional user-defined context for private data for the 477 function evaluation routine (may be null) 478 479 Notes: 480 The Newton-like methods typically solve linear systems of the form 481 $ f'(x) x = -f(x), 482 $ where f'(x) denotes the Jacobian matrix and f(x) is the function. 483 By setting resid_neg = 1, the user can supply -f(x) directly. 484 485 SNESSetFunction() is valid for SNES_NONLINEAR_EQUATIONS methods only. 486 Analogous routines for SNES_UNCONSTRAINED_MINIMIZATION methods are 487 SNESSetMinimizationFunction() and SNESSetGradient(); 488 489 .keywords: SNES, nonlinear, set, function 490 491 .seealso: SNESGetFunction(), SNESSetJacobian(), SNESSetSolution() 492 @*/ 493 int SNESSetFunction( SNES snes, Vec r, int (*func)(SNES,Vec,Vec,void*), 494 void *ctx,SNESFunctionSign rneg) 495 { 496 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 497 if (snes->method_class != SNES_NONLINEAR_EQUATIONS) SETERRQ(1, 498 "SNESSetFunction:For SNES_NONLINEAR_EQUATIONS only"); 499 snes->computefunction = func; 500 snes->rsign = (int) rneg; 501 snes->vec_func = snes->vec_func_always = r; 502 snes->funP = ctx; 503 return 0; 504 } 505 506 /*@ 507 SNESComputeFunction - Computes the function that has been set with 508 SNESSetFunction(). 509 510 Input Parameters: 511 . snes - the SNES context 512 . x - input vector 513 514 Output Parameter: 515 . y - function vector or its negative, as set by SNESSetFunction() 516 517 Notes: 518 SNESComputeFunction() is valid for SNES_NONLINEAR_EQUATIONS methods only. 519 Analogous routines for SNES_UNCONSTRAINED_MINIMIZATION methods are 520 SNESComputeMinimizationFunction() and SNESComputeGradient(); 521 522 .keywords: SNES, nonlinear, compute, function 523 524 .seealso: SNESSetFunction() 525 @*/ 526 int SNESComputeFunction(SNES snes,Vec x, Vec y) 527 { 528 int ierr; 529 Scalar mone = -1.0; 530 531 PLogEventBegin(SNES_FunctionEval,snes,x,y,0); 532 ierr = (*snes->computefunction)(snes,x,y,snes->funP); CHKERRQ(ierr); 533 if (!snes->rsign) { 534 ierr = VecScale(&mone,y); CHKERRQ(ierr); 535 } 536 PLogEventEnd(SNES_FunctionEval,snes,x,y,0); 537 return 0; 538 } 539 540 /*@C 541 SNESSetMinimizationFunction - Sets the function evaluation routine for 542 unconstrained minimization. 543 544 Input Parameters: 545 . snes - the SNES context 546 . func - function evaluation routine 547 . ctx - optional user-defined function context 548 549 Calling sequence of func: 550 . func (SNES snes,Vec x,double *f,void *ctx); 551 552 . x - input vector 553 . f - function 554 . ctx - optional user-defined context for private data for the 555 function evaluation routine (may be null) 556 557 Notes: 558 SNESSetMinimizationFunction() is valid for SNES_UNCONSTRAINED_MINIMIZATION 559 methods only. An analogous routine for SNES_NONLINEAR_EQUATIONS methods is 560 SNESSetFunction(). 561 562 .keywords: SNES, nonlinear, set, minimization, function 563 564 .seealso: SNESGetMinimizationFunction(), SNESSetHessian(), SNESSetGradient(), 565 SNESSetSolution() 566 @*/ 567 int SNESSetMinimizationFunction(SNES snes,int (*func)(SNES,Vec,double*,void*), 568 void *ctx) 569 { 570 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 571 if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1, 572 "SNESSetMinimizationFunction:Only for SNES_UNCONSTRAINED_MINIMIZATION"); 573 snes->computeumfunction = func; 574 snes->umfunP = ctx; 575 return 0; 576 } 577 578 /*@ 579 SNESComputeMinimizationFunction - Computes the function that has been 580 set with SNESSetMinimizationFunction(). 581 582 Input Parameters: 583 . snes - the SNES context 584 . x - input vector 585 586 Output Parameter: 587 . y - function value 588 589 Notes: 590 SNESComputeMinimizationFunction() is valid only for 591 SNES_UNCONSTRAINED_MINIMIZATION methods. An analogous routine for 592 SNES_NONLINEAR_EQUATIONS methods is SNESComputeFunction(). 593 @*/ 594 int SNESComputeMinimizationFunction(SNES snes,Vec x,double *y) 595 { 596 int ierr; 597 if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1, 598 "SNESComputeMinimizationFunction:Only for SNES_UNCONSTRAINED_MINIMIZATION"); 599 PLogEventBegin(SNES_MinimizationFunctionEval,snes,x,y,0); 600 ierr = (*snes->computeumfunction)(snes,x,y,snes->umfunP); CHKERRQ(ierr); 601 PLogEventEnd(SNES_MinimizationFunctionEval,snes,x,y,0); 602 return 0; 603 } 604 605 /*@C 606 SNESSetGradient - Sets the gradient evaluation routine and gradient 607 vector for use by the SNES routines. 608 609 Input Parameters: 610 . snes - the SNES context 611 . func - function evaluation routine 612 . ctx - optional user-defined function context 613 . r - vector to store gradient value 614 615 Calling sequence of func: 616 . func (SNES, Vec x, Vec g, void *ctx); 617 618 . x - input vector 619 . g - gradient vector 620 . ctx - optional user-defined context for private data for the 621 function evaluation routine (may be null) 622 623 Notes: 624 SNESSetMinimizationFunction() is valid for SNES_UNCONSTRAINED_MINIMIZATION 625 methods only. An analogous routine for SNES_NONLINEAR_EQUATIONS methods is 626 SNESSetFunction(). 627 628 .keywords: SNES, nonlinear, set, function 629 630 .seealso: SNESGetGradient(), SNESSetHessian(), SNESSetMinimizationFunction(), 631 SNESSetSolution() 632 @*/ 633 int SNESSetGradient(SNES snes,Vec r,int (*func)(SNES,Vec,Vec,void*), 634 void *ctx) 635 { 636 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 637 if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1, 638 "SNESSetGradient:For SNES_UNCONSTRAINED_MINIMIZATION only"); 639 snes->computefunction = func; 640 snes->vec_func = snes->vec_func_always = r; 641 snes->funP = ctx; 642 return 0; 643 } 644 645 /*@ 646 SNESComputeGradient - Computes the gradient that has been 647 set with SNESSetGradient(). 648 649 Input Parameters: 650 . snes - the SNES context 651 . x - input vector 652 653 Output Parameter: 654 . y - gradient vector 655 656 Notes: 657 SNESComputeGradient() is valid only for 658 SNES_UNCONSTRAINED_MINIMIZATION methods. An analogous routine for 659 SNES_NONLINEAR_EQUATIONS methods is SNESComputeFunction(). 660 @*/ 661 int SNESComputeGradient(SNES snes,Vec x, Vec y) 662 { 663 int ierr; 664 if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1, 665 "SNESComputeGradient:For SNES_UNCONSTRAINED_MINIMIZATION only"); 666 PLogEventBegin(SNES_GradientEval,snes,x,y,0); 667 ierr = (*snes->computefunction)(snes,x,y,snes->funP); CHKERRQ(ierr); 668 PLogEventEnd(SNES_GradientEval,snes,x,y,0); 669 return 0; 670 } 671 672 int SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 673 { 674 int ierr; 675 if (snes->method_class != SNES_NONLINEAR_EQUATIONS) SETERRQ(1, 676 "SNESComputeJacobian: For SNES_NONLINEAR_EQUATIONS only"); 677 if (!snes->computejacobian) return 0; 678 PLogEventBegin(SNES_JacobianEval,snes,X,*A,*B); 679 *flg = ALLMAT_DIFFERENT_NONZERO_PATTERN; 680 ierr = (*snes->computejacobian)(snes,X,A,B,flg,snes->jacP); CHKERRQ(ierr); 681 PLogEventEnd(SNES_JacobianEval,snes,X,*A,*B); 682 return 0; 683 } 684 685 int SNESComputeHessian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 686 { 687 int ierr; 688 if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1, 689 "SNESComputeHessian:For SNES_UNCONSTRAINED_MINIMIZATION only"); 690 if (!snes->computejacobian) return 0; 691 PLogEventBegin(SNES_HessianEval,snes,X,*A,*B); 692 ierr = (*snes->computejacobian)(snes,X,A,B,flg,snes->jacP); CHKERRQ(ierr); 693 PLogEventEnd(SNES_HessianEval,snes,X,*A,*B); 694 return 0; 695 } 696 697 /*@C 698 SNESSetJacobian - Sets the function to compute Jacobian as well as the 699 location to store it. 700 701 Input Parameters: 702 . snes - the SNES context 703 . A - Jacobian matrix 704 . B - preconditioner matrix (usually same as the Jacobian) 705 . func - Jacobian evaluation routine 706 . ctx - optional user-defined context for private data for the 707 Jacobian evaluation routine (may be null) 708 709 Calling sequence of func: 710 . func (SNES,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 711 712 . x - input vector 713 . A - Jacobian matrix 714 . B - preconditioner matrix, usually the same as A 715 . flag - flag indicating information about matrix structure, 716 same as flag in SLESSetOperators() 717 . ctx - optional user-defined Jacobian context 718 719 Notes: 720 The function func() takes Mat * as the matrix arguments rather than Mat. 721 This allows the Jacobian evaluation routine to replace A and/or B with a 722 completely new new matrix structure (not just different matrix elements) 723 when appropriate, for instance, if the nonzero structure is changing 724 throughout the global iterations. 725 726 .keywords: SNES, nonlinear, set, Jacobian, matrix 727 728 .seealso: SNESSetFunction(), SNESSetSolution() 729 @*/ 730 int SNESSetJacobian(SNES snes,Mat A,Mat B,int (*func)(SNES,Vec,Mat*,Mat*, 731 MatStructure*,void*),void *ctx) 732 { 733 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 734 if (snes->method_class != SNES_NONLINEAR_EQUATIONS) SETERRQ(1, 735 "SNESSetJacobian:For SNES_NONLINEAR_EQUATIONS only"); 736 snes->computejacobian = func; 737 snes->jacP = ctx; 738 snes->jacobian = A; 739 snes->jacobian_pre = B; 740 return 0; 741 } 742 /*@ 743 SNESGetJacobian - Returns the Jacobian matrix and optionally the user 744 provided context for evaluating the Jacobian. 745 746 Input Parameter: 747 . snes - the nonlinear solver context 748 749 Output Parameters: 750 . A - location to stash Jacobian matrix (or PETSC_NULL) 751 . B - location to stash preconditioner matrix (or PETSC_NULL) 752 . ctx - location to stash Jacobian ctx (or PETSC_NULL) 753 754 .seealso: SNESSetJacobian(), SNESComputeJacobian() 755 @*/ 756 int SNESGetJacobian(SNES snes,Mat *A,Mat *B, void **ctx) 757 { 758 if (A) *A = snes->jacobian; 759 if (B) *B = snes->jacobian_pre; 760 if (ctx) *ctx = snes->jacP; 761 return 0; 762 } 763 764 /*@C 765 SNESSetHessian - Sets the function to compute Hessian as well as the 766 location to store it. 767 768 Input Parameters: 769 . snes - the SNES context 770 . A - Hessian matrix 771 . B - preconditioner matrix (usually same as the Hessian) 772 . func - Jacobian evaluation routine 773 . ctx - optional user-defined context for private data for the 774 Hessian evaluation routine (may be null) 775 776 Calling sequence of func: 777 . func (SNES,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 778 779 . x - input vector 780 . A - Hessian matrix 781 . B - preconditioner matrix, usually the same as A 782 . flag - flag indicating information about matrix structure, 783 same as flag in SLESSetOperators() 784 . ctx - optional user-defined Hessian context 785 786 Notes: 787 The function func() takes Mat * as the matrix arguments rather than Mat. 788 This allows the Hessian evaluation routine to replace A and/or B with a 789 completely new new matrix structure (not just different matrix elements) 790 when appropriate, for instance, if the nonzero structure is changing 791 throughout the global iterations. 792 793 .keywords: SNES, nonlinear, set, Hessian, matrix 794 795 .seealso: SNESSetMinimizationFunction(), SNESSetSolution(), SNESSetGradient() 796 @*/ 797 int SNESSetHessian(SNES snes,Mat A,Mat B,int (*func)(SNES,Vec,Mat*,Mat*, 798 MatStructure*,void*),void *ctx) 799 { 800 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 801 if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1, 802 "SNESSetHessian:For SNES_UNCONSTRAINED_MINIMIZATION only"); 803 snes->computejacobian = func; 804 snes->jacP = ctx; 805 snes->jacobian = A; 806 snes->jacobian_pre = B; 807 return 0; 808 } 809 810 /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 811 812 /*@ 813 SNESSetUp - Sets up the internal data structures for the later use 814 of a nonlinear solver. Call SNESSetUp() after calling SNESCreate() 815 and optional routines of the form SNESSetXXX(), but before calling 816 SNESSolve(). 817 818 Input Parameter: 819 . snes - the SNES context 820 821 .keywords: SNES, nonlinear, setup 822 823 .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 824 @*/ 825 int SNESSetUp(SNES snes) 826 { 827 int ierr; 828 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 829 if (!snes->vec_sol) 830 SETERRQ(1,"SNESSetUp:Must call SNESSetSolution() first"); 831 832 if ((snes->method_class == SNES_NONLINEAR_EQUATIONS)) { 833 if (!snes->set_method_called) 834 {ierr = SNESSetType(snes,SNES_EQ_NLS); CHKERRQ(ierr);} 835 if (!snes->vec_func) SETERRQ(1, 836 "SNESSetUp:Must call SNESSetFunction() first"); 837 if (!snes->computefunction) SETERRQ(1, 838 "SNESSetUp:Must call SNESSetFunction() first"); 839 if (!snes->jacobian) SETERRQ(1, 840 "SNESSetUp:Must call SNESSetJacobian() first"); 841 842 /* Set the KSP stopping criterion to use the Eisenstat-Walker method */ 843 if (snes->ksp_ewconv && snes->type != SNES_EQ_NTR) { 844 SLES sles; KSP ksp; 845 ierr = SNESGetSLES(snes,&sles); CHKERRQ(ierr); 846 ierr = SLESGetKSP(sles,&ksp); CHKERRQ(ierr); 847 ierr = KSPSetConvergenceTest(ksp,SNES_KSP_EW_Converged_Private, 848 (void *)snes); CHKERRQ(ierr); 849 } 850 } else if ((snes->method_class == SNES_UNCONSTRAINED_MINIMIZATION)) { 851 if (!snes->set_method_called) 852 {ierr = SNESSetType(snes,SNES_UM_NTR); CHKERRQ(ierr);} 853 if (!snes->vec_func) SETERRQ(1, 854 "SNESSetUp:Must call SNESSetGradient() first"); 855 if (!snes->computefunction) SETERRQ(1, 856 "SNESSetUp:Must call SNESSetGradient() first"); 857 if (!snes->computeumfunction) SETERRQ(1, 858 "SNESSetUp:Must call SNESSetMinimizationFunction() first"); 859 if (!snes->jacobian) SETERRQ(1, 860 "SNESSetUp:Must call SNESSetHessian() first"); 861 } else SETERRQ(1,"SNESSetUp:Unknown method class"); 862 if (snes->setup) {ierr = (*snes->setup)(snes); CHKERRQ(ierr);} 863 snes->setup_called = 1; 864 return 0; 865 } 866 867 /*@C 868 SNESDestroy - Destroys the nonlinear solver context that was created 869 with SNESCreate(). 870 871 Input Parameter: 872 . snes - the SNES context 873 874 .keywords: SNES, nonlinear, destroy 875 876 .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 877 @*/ 878 int SNESDestroy(SNES snes) 879 { 880 int ierr; 881 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 882 ierr = (*(snes)->destroy)((PetscObject)snes); CHKERRQ(ierr); 883 if (snes->kspconvctx) PetscFree(snes->kspconvctx); 884 if (snes->mfshell) MatDestroy(snes->mfshell); 885 ierr = SLESDestroy(snes->sles); CHKERRQ(ierr); 886 PLogObjectDestroy((PetscObject)snes); 887 PetscHeaderDestroy((PetscObject)snes); 888 return 0; 889 } 890 891 /* ----------- Routines to set solver parameters ---------- */ 892 893 /*@ 894 SNESSetMaxIterations - Sets the maximum number of global iterations to use. 895 896 Input Parameters: 897 . snes - the SNES context 898 . maxits - maximum number of iterations to use 899 900 Options Database Key: 901 $ -snes_max_it maxits 902 903 Note: 904 The default maximum number of iterations is 50. 905 906 .keywords: SNES, nonlinear, set, maximum, iterations 907 908 .seealso: SNESSetMaxFunctionEvaluations() 909 @*/ 910 int SNESSetMaxIterations(SNES snes,int maxits) 911 { 912 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 913 snes->max_its = maxits; 914 return 0; 915 } 916 917 /*@ 918 SNESSetMaxFunctionEvaluations - Sets the maximum number of function 919 evaluations to use. 920 921 Input Parameters: 922 . snes - the SNES context 923 . maxf - maximum number of function evaluations 924 925 Options Database Key: 926 $ -snes_max_funcs maxf 927 928 Note: 929 The default maximum number of function evaluations is 1000. 930 931 .keywords: SNES, nonlinear, set, maximum, function, evaluations 932 933 .seealso: SNESSetMaxIterations() 934 @*/ 935 int SNESSetMaxFunctionEvaluations(SNES snes,int maxf) 936 { 937 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 938 snes->max_funcs = maxf; 939 return 0; 940 } 941 942 /*@ 943 SNESSetRelativeTolerance - Sets the relative convergence tolerance. 944 945 Input Parameters: 946 . snes - the SNES context 947 . rtol - tolerance 948 949 Options Database Key: 950 $ -snes_rtol tol 951 952 .keywords: SNES, nonlinear, set, relative, convergence, tolerance 953 954 .seealso: SNESSetAbsoluteTolerance(), SNESSetSolutionTolerance(), 955 SNESSetTruncationTolerance() 956 @*/ 957 int SNESSetRelativeTolerance(SNES snes,double rtol) 958 { 959 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 960 snes->rtol = rtol; 961 return 0; 962 } 963 964 /*@ 965 SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 966 967 Input Parameters: 968 . snes - the SNES context 969 . tol - tolerance 970 971 Options Database Key: 972 $ -snes_trtol tol 973 974 .keywords: SNES, nonlinear, set, trust region, tolerance 975 976 .seealso: SNESSetAbsoluteTolerance(), SNESSetSolutionTolerance(), 977 SNESSetTruncationTolerance() 978 @*/ 979 int SNESSetTrustRegionTolerance(SNES snes,double tol) 980 { 981 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 982 snes->deltatol = tol; 983 return 0; 984 } 985 986 /*@ 987 SNESSetAbsoluteTolerance - Sets the absolute convergence tolerance. 988 989 Input Parameters: 990 . snes - the SNES context 991 . atol - tolerance 992 993 Options Database Key: 994 $ -snes_atol tol 995 996 .keywords: SNES, nonlinear, set, absolute, convergence, tolerance 997 998 .seealso: SNESSetRelativeTolerance(), SNESSetSolutionTolerance(), 999 SNESSetTruncationTolerance() 1000 @*/ 1001 int SNESSetAbsoluteTolerance(SNES snes,double atol) 1002 { 1003 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1004 snes->atol = atol; 1005 return 0; 1006 } 1007 1008 /*@ 1009 SNESSetTruncationTolerance - Sets the tolerance that may be used by the 1010 step routines to control the accuracy of the step computation. 1011 1012 Input Parameters: 1013 . snes - the SNES context 1014 . tol - tolerance 1015 1016 Options Database Key: 1017 $ -snes_ttol tol 1018 1019 Notes: 1020 If the step computation involves an application of the inverse 1021 Jacobian (or Hessian), this parameter may be used to control the 1022 accuracy of that application. 1023 1024 .keywords: SNES, nonlinear, set, truncation, tolerance 1025 1026 .seealso: SNESSetRelativeTolerance(), SNESSetSolutionTolerance(), 1027 SNESSetAbsoluteTolerance() 1028 @*/ 1029 int SNESSetTruncationTolerance(SNES snes,double tol) 1030 { 1031 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1032 snes->trunctol = tol; 1033 return 0; 1034 } 1035 1036 /*@ 1037 SNESSetSolutionTolerance - Sets the convergence tolerance in terms of 1038 the norm of the change in the solution between steps. 1039 1040 Input Parameters: 1041 . snes - the SNES context 1042 . tol - tolerance 1043 1044 Options Database Key: 1045 $ -snes_stol tol 1046 1047 .keywords: SNES, nonlinear, set, solution, tolerance 1048 1049 .seealso: SNESSetTruncationTolerance(), SNESSetRelativeTolerance(), 1050 SNESSetAbsoluteTolerance() 1051 @*/ 1052 int SNESSetSolutionTolerance( SNES snes, double tol ) 1053 { 1054 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1055 snes->xtol = tol; 1056 return 0; 1057 } 1058 1059 /*@ 1060 SNESSetMinFunctionTolerance - Sets the minimum allowable function tolerance 1061 for unconstrained minimization solvers. 1062 1063 Input Parameters: 1064 . snes - the SNES context 1065 . ftol - minimum function tolerance 1066 1067 Options Database Key: 1068 $ -snes_fmin ftol 1069 1070 Note: 1071 SNESSetMinFunctionTolerance() is valid for SNES_UNCONSTRAINED_MINIMIZATION 1072 methods only. 1073 1074 .keywords: SNES, nonlinear, set, minimum, convergence, function, tolerance 1075 1076 .seealso: SNESSetRelativeTolerance(), SNESSetSolutionTolerance(), 1077 SNESSetTruncationTolerance() 1078 @*/ 1079 int SNESSetMinFunctionTolerance(SNES snes,double ftol) 1080 { 1081 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1082 snes->fmin = ftol; 1083 return 0; 1084 } 1085 1086 1087 1088 /* ---------- Routines to set various aspects of nonlinear solver --------- */ 1089 1090 /*@C 1091 SNESSetSolution - Sets the initial guess routine and solution vector 1092 for use by the SNES routines. 1093 1094 Input Parameters: 1095 . snes - the SNES context 1096 . x - the solution vector 1097 . func - optional routine to compute an initial guess (may be null) 1098 . ctx - optional user-defined context for private data for the 1099 initial guess routine (may be null) 1100 1101 Calling sequence of func: 1102 int guess(Vec x, void *ctx) 1103 1104 . x - input vector 1105 . ctx - optional user-defined initial guess context 1106 1107 Note: 1108 If no initial guess routine is indicated, an initial guess of zero 1109 will be used. 1110 1111 .keywords: SNES, nonlinear, set, solution, initial guess 1112 1113 .seealso: SNESGetSolution(), SNESSetJacobian(), SNESSetFunction() 1114 @*/ 1115 int SNESSetSolution(SNES snes,Vec x,int (*func)(SNES,Vec,void*),void *ctx) 1116 { 1117 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1118 snes->vec_sol = snes->vec_sol_always = x; 1119 snes->computeinitialguess = func; 1120 snes->gusP = ctx; 1121 return 0; 1122 } 1123 1124 /* ------------ Routines to set performance monitoring options ----------- */ 1125 1126 /*@C 1127 SNESSetMonitor - Sets the function that is to be used at every 1128 iteration of the nonlinear solver to display the iteration's 1129 progress. 1130 1131 Input Parameters: 1132 . snes - the SNES context 1133 . func - monitoring routine 1134 . mctx - optional user-defined context for private data for the 1135 monitor routine (may be null) 1136 1137 Calling sequence of func: 1138 int func((SNES snes,int its, Vec x,Vec f, 1139 double norm,void *mctx) 1140 1141 $ snes - the SNES context 1142 $ its - iteration number 1143 $ mctx - optional monitoring context 1144 $ 1145 $ SNES_NONLINEAR_EQUATIONS methods: 1146 $ norm - 2-norm function value (may be estimated) 1147 $ 1148 $ SNES_UNCONSTRAINED_MINIMIZATION methods: 1149 $ norm - 2-norm gradient value (may be estimated) 1150 1151 .keywords: SNES, nonlinear, set, monitor 1152 1153 .seealso: SNESDefaultMonitor() 1154 @*/ 1155 int SNESSetMonitor( SNES snes, int (*func)(SNES,int,double,void*), 1156 void *mctx ) 1157 { 1158 snes->monitor = func; 1159 snes->monP = (void*)mctx; 1160 return 0; 1161 } 1162 1163 /*@C 1164 SNESSetConvergenceTest - Sets the function that is to be used 1165 to test for convergence of the nonlinear iterative solution. 1166 1167 Input Parameters: 1168 . snes - the SNES context 1169 . func - routine to test for convergence 1170 . cctx - optional context for private data for the convergence routine 1171 (may be null) 1172 1173 Calling sequence of func: 1174 int func (SNES snes,double xnorm,double gnorm, 1175 double f,void *cctx) 1176 1177 $ snes - the SNES context 1178 $ cctx - optional convergence context 1179 $ xnorm - 2-norm of current iterate 1180 $ 1181 $ SNES_NONLINEAR_EQUATIONS methods: 1182 $ gnorm - 2-norm of current step 1183 $ f - 2-norm of function 1184 $ 1185 $ SNES_UNCONSTRAINED_MINIMIZATION methods: 1186 $ gnorm - 2-norm of current gradient 1187 $ f - function value 1188 1189 .keywords: SNES, nonlinear, set, convergence, test 1190 1191 .seealso: SNESDefaultConverged() 1192 @*/ 1193 int SNESSetConvergenceTest(SNES snes, 1194 int (*func)(SNES,double,double,double,void*),void *cctx) 1195 { 1196 (snes)->converged = func; 1197 (snes)->cnvP = cctx; 1198 return 0; 1199 } 1200 1201 /* 1202 SNESScaleStep_Private - Scales a step so that its length is less than the 1203 positive parameter delta. 1204 1205 Input Parameters: 1206 . snes - the SNES context 1207 . y - approximate solution of linear system 1208 . fnorm - 2-norm of current function 1209 . delta - trust region size 1210 1211 Output Parameters: 1212 . gpnorm - predicted function norm at the new point, assuming local 1213 linearization. The value is zero if the step lies within the trust 1214 region, and exceeds zero otherwise. 1215 . ynorm - 2-norm of the step 1216 1217 Note: 1218 For non-trust region methods such as SNES_EQ_NLS, the parameter delta 1219 is set to be the maximum allowable step size. 1220 1221 .keywords: SNES, nonlinear, scale, step 1222 */ 1223 int SNESScaleStep_Private(SNES snes,Vec y,double *fnorm,double *delta, 1224 double *gpnorm,double *ynorm) 1225 { 1226 double norm; 1227 Scalar cnorm; 1228 VecNorm(y,NORM_2, &norm ); 1229 if (norm > *delta) { 1230 norm = *delta/norm; 1231 *gpnorm = (1.0 - norm)*(*fnorm); 1232 cnorm = norm; 1233 VecScale( &cnorm, y ); 1234 *ynorm = *delta; 1235 } else { 1236 *gpnorm = 0.0; 1237 *ynorm = norm; 1238 } 1239 return 0; 1240 } 1241 1242 /*@ 1243 SNESSolve - Solves a nonlinear system. Call SNESSolve after calling 1244 SNESCreate(), optional routines of the form SNESSetXXX(), and SNESSetUp(). 1245 1246 Input Parameter: 1247 . snes - the SNES context 1248 1249 Output Parameter: 1250 its - number of iterations until termination 1251 1252 .keywords: SNES, nonlinear, solve 1253 1254 .seealso: SNESCreate(), SNESSetUp(), SNESDestroy() 1255 @*/ 1256 int SNESSolve(SNES snes,int *its) 1257 { 1258 int ierr; 1259 PLogEventBegin(SNES_Solve,snes,0,0,0); 1260 ierr = (*(snes)->solve)(snes,its); CHKERRQ(ierr); 1261 PLogEventEnd(SNES_Solve,snes,0,0,0); 1262 if (OptionsHasName(PETSC_NULL,"-snes_view")) { 1263 SNESView(snes,STDOUT_VIEWER_WORLD); CHKERRQ(ierr); 1264 } 1265 return 0; 1266 } 1267 1268 /* --------- Internal routines for SNES Package --------- */ 1269 1270 /* 1271 SNESComputeInitialGuess - Manages computation of initial approximation. 1272 */ 1273 int SNESComputeInitialGuess( SNES snes,Vec x ) 1274 { 1275 int ierr; 1276 Scalar zero = 0.0; 1277 if (snes->computeinitialguess) { 1278 ierr = (*snes->computeinitialguess)(snes, x, snes->gusP); CHKERRQ(ierr); 1279 } 1280 else { 1281 ierr = VecSet(&zero,x); CHKERRQ(ierr); 1282 } 1283 return 0; 1284 } 1285 1286 /* ------------------------------------------------------------------ */ 1287 1288 NRList *__NLList; 1289 1290 /*@ 1291 SNESSetType - Sets the method for the nonlinear solver. 1292 1293 Input Parameters: 1294 . snes - the SNES context 1295 . method - a known method 1296 1297 Notes: 1298 See "petsc/include/snes.h" for available methods (for instance) 1299 $ Systems of nonlinear equations: 1300 $ SNES_EQ_NLS - Newton's method with line search 1301 $ SNES_EQ_NTR - Newton's method with trust region 1302 $ Unconstrained minimization: 1303 $ SNES_UM_NTR - Newton's method with trust region 1304 $ SNES_UM_NLS - Newton's method with line search 1305 1306 Options Database Command: 1307 $ -snes_type <method> 1308 $ Use -help for a list of available methods 1309 $ (for instance, ls or tr) 1310 1311 .keysords: SNES, set, method 1312 @*/ 1313 int SNESSetType(SNES snes,SNESType method) 1314 { 1315 int (*r)(SNES); 1316 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1317 /* Get the function pointers for the iterative method requested */ 1318 if (!__NLList) {SNESRegisterAll();} 1319 if (!__NLList) {SETERRQ(1,"SNESSetType:Could not get methods");} 1320 r = (int (*)(SNES))NRFindRoutine( __NLList, (int)method, (char *)0 ); 1321 if (!r) {SETERRQ(1,"SNESSetType:Unknown method");} 1322 if (snes->data) PetscFree(snes->data); 1323 snes->set_method_called = 1; 1324 return (*r)(snes); 1325 } 1326 1327 /* --------------------------------------------------------------------- */ 1328 /*@C 1329 SNESRegister - Adds the method to the nonlinear solver package, given 1330 a function pointer and a nonlinear solver name of the type SNESType. 1331 1332 Input Parameters: 1333 . name - for instance SNES_EQ_NLS, SNES_EQ_NTR, ... 1334 . sname - corfunPonding string for name 1335 . create - routine to create method context 1336 1337 .keywords: SNES, nonlinear, register 1338 1339 .seealso: SNESRegisterAll(), SNESRegisterDestroy() 1340 @*/ 1341 int SNESRegister(int name, char *sname, int (*create)(SNES)) 1342 { 1343 int ierr; 1344 if (!__NLList) {ierr = NRCreate(&__NLList); CHKERRQ(ierr);} 1345 NRRegister( __NLList, name, sname, (int (*)(void*))create ); 1346 return 0; 1347 } 1348 /* --------------------------------------------------------------------- */ 1349 /*@C 1350 SNESRegisterDestroy - Frees the list of nonlinear solvers that were 1351 registered by SNESRegister(). 1352 1353 .keywords: SNES, nonlinear, register, destroy 1354 1355 .seealso: SNESRegisterAll(), SNESRegisterAll() 1356 @*/ 1357 int SNESRegisterDestroy() 1358 { 1359 if (__NLList) { 1360 NRDestroy( __NLList ); 1361 __NLList = 0; 1362 } 1363 return 0; 1364 } 1365 1366 /* 1367 SNESGetTypeFromOptions_Private - Sets the selected method from the 1368 options database. 1369 1370 Input Parameter: 1371 . ctx - the SNES context 1372 1373 Output Parameter: 1374 . method - solver method 1375 1376 Returns: 1377 Returns 1 if the method is found; 0 otherwise. 1378 1379 Options Database Key: 1380 $ -snes_type method 1381 */ 1382 int SNESGetTypeFromOptions_Private(SNES ctx,SNESType *method) 1383 { 1384 char sbuf[50]; 1385 if (OptionsGetString(ctx->prefix,"-snes_type", sbuf, 50 )) { 1386 if (!__NLList) SNESRegisterAll(); 1387 *method = (SNESType)NRFindID( __NLList, sbuf ); 1388 return 1; 1389 } 1390 return 0; 1391 } 1392 1393 /*@C 1394 SNESGetType - Gets the SNES type and method name (as a string). 1395 1396 Input Parameter: 1397 . snes - nonlinear solver context 1398 1399 Output Parameter: 1400 . method - SNES method (or PETSC_NULL) 1401 . name - name of SNES method (or PETSC_NULL) 1402 1403 .keywords: SNES, nonlinear, get, method, name 1404 @*/ 1405 int SNESGetType(SNES snes, SNESType *method,char **name) 1406 { 1407 int ierr; 1408 if (!__NLList) {ierr = SNESRegisterAll(); CHKERRQ(ierr);} 1409 if (method) *method = (SNESType) snes->type; 1410 if (name) *name = NRFindName( __NLList, (int) snes->type ); 1411 return 0; 1412 } 1413 1414 #include <stdio.h> 1415 /* 1416 SNESPrintTypes_Private - Prints the SNES methods available from the 1417 options database. 1418 1419 Input Parameters: 1420 . prefix - prefix (usually "-") 1421 . name - the options database name (by default "snes_type") 1422 */ 1423 int SNESPrintTypes_Private(char* prefix,char *name) 1424 { 1425 FuncList *entry; 1426 if (!__NLList) {SNESRegisterAll();} 1427 entry = __NLList->head; 1428 fprintf(stderr," %s%s (one of)",prefix,name); 1429 while (entry) { 1430 fprintf(stderr," %s",entry->name); 1431 entry = entry->next; 1432 } 1433 fprintf(stderr,"\n"); 1434 return 0; 1435 } 1436 1437 /*@C 1438 SNESGetSolution - Returns the vector where the approximate solution is 1439 stored. 1440 1441 Input Parameter: 1442 . snes - the SNES context 1443 1444 Output Parameter: 1445 . x - the solution 1446 1447 .keywords: SNES, nonlinear, get, solution 1448 1449 .seealso: SNESSetSolution(), SNESGetFunction(), SNESGetSolutionUpdate() 1450 @*/ 1451 int SNESGetSolution(SNES snes,Vec *x) 1452 { 1453 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1454 *x = snes->vec_sol_always; 1455 return 0; 1456 } 1457 1458 /*@C 1459 SNESGetSolutionUpdate - Returns the vector where the solution update is 1460 stored. 1461 1462 Input Parameter: 1463 . snes - the SNES context 1464 1465 Output Parameter: 1466 . x - the solution update 1467 1468 Notes: 1469 This vector is implementation dependent. 1470 1471 .keywords: SNES, nonlinear, get, solution, update 1472 1473 .seealso: SNESGetSolution(), SNESGetFunction 1474 @*/ 1475 int SNESGetSolutionUpdate(SNES snes,Vec *x) 1476 { 1477 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1478 *x = snes->vec_sol_update_always; 1479 return 0; 1480 } 1481 1482 /*@C 1483 SNESGetFunction - Returns the vector where the function is 1484 stored. Actually usually returns the vector where the negative of 1485 the function is stored. 1486 1487 Input Parameter: 1488 . snes - the SNES context 1489 1490 Output Parameter: 1491 . r - the function (or its negative) 1492 1493 Notes: 1494 SNESGetFunction() is valid for SNES_NONLINEAR_EQUATIONS methods only 1495 Analogous routines for SNES_UNCONSTRAINED_MINIMIZATION methods are 1496 SNESGetMinimizationFunction() and SNESGetGradient(); 1497 1498 .keywords: SNES, nonlinear, get function 1499 1500 .seealso: SNESSetFunction(), SNESGetSolution() 1501 @*/ 1502 int SNESGetFunction(SNES snes,Vec *r) 1503 { 1504 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1505 if (snes->method_class != SNES_NONLINEAR_EQUATIONS) SETERRQ(1, 1506 "SNESGetFunction:For SNES_NONLINEAR_EQUATIONS only"); 1507 *r = snes->vec_func_always; 1508 return 0; 1509 } 1510 1511 /*@C 1512 SNESGetGradient - Returns the vector where the gradient is 1513 stored. Actually usually returns the vector where the negative of 1514 the function is stored. 1515 1516 Input Parameter: 1517 . snes - the SNES context 1518 1519 Output Parameter: 1520 . r - the gradient 1521 1522 Notes: 1523 SNESGetGradient() is valid for SNES_UNCONSTRAINED_MINIMIZATION methods 1524 only. An analogous routine for SNES_NONLINEAR_EQUATIONS methods is 1525 SNESGetFunction(). 1526 1527 .keywords: SNES, nonlinear, get, gradient 1528 1529 .seealso: SNESGetMinimizationFunction(), SNESGetSolution() 1530 @*/ 1531 int SNESGetGradient(SNES snes,Vec *r) 1532 { 1533 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1534 if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1, 1535 "SNESGetGradient:For SNES_UNCONSTRAINED_MINIMIZATION only"); 1536 *r = snes->vec_func_always; 1537 return 0; 1538 } 1539 1540 /*@ 1541 SNESGetMinimizationFunction - Returns the scalar function value for 1542 unconstrained minimization problems. 1543 1544 Input Parameter: 1545 . snes - the SNES context 1546 1547 Output Parameter: 1548 . r - the function 1549 1550 Notes: 1551 SNESGetMinimizationFunction() is valid for SNES_UNCONSTRAINED_MINIMIZATION 1552 methods only. An analogous routine for SNES_NONLINEAR_EQUATIONS methods is 1553 SNESGetFunction(). 1554 1555 .keywords: SNES, nonlinear, get, function 1556 1557 .seealso: SNESGetGradient(), SNESGetSolution() 1558 @*/ 1559 int SNESGetMinimizationFunction(SNES snes,double *r) 1560 { 1561 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1562 if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1, 1563 "SNESGetMinimizationFunction:For SNES_UNCONSTRAINED_MINIMIZATION only"); 1564 *r = snes->fc; 1565 return 0; 1566 } 1567 1568 1569 1570 1571 1572