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