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