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