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