1 #ifndef lint 2 static char vcid[] = "$Id: snes.c,v 1.42 1996/01/23 18:28:07 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 if (type != SNES_UNCONSTRAINED_MINIMIZATION && type != SNES_NONLINEAR_EQUATIONS) 430 SETERRQ(1,"SNESCreate:incorrect method type"); 431 PetscHeaderCreate(snes,_SNES,SNES_COOKIE,SNES_UNKNOWN_METHOD,comm); 432 PLogObjectCreate(snes); 433 snes->max_its = 50; 434 snes->max_funcs = 1000; 435 snes->norm = 0.0; 436 if (type == SNES_UNCONSTRAINED_MINIMIZATION) 437 snes->rtol = 1.e-08; 438 snes->atol = 1.e-10; 439 else { 440 snes->rtol = 1.e-8; 441 snes->ttol = 0.0; 442 snes->atol = 1.e-50; 443 } 444 snes->xtol = 1.e-8; 445 snes->trunctol = 1.e-12; 446 snes->nfuncs = 0; 447 snes->nfailures = 0; 448 snes->monitor = 0; 449 snes->data = 0; 450 snes->view = 0; 451 snes->computeumfunction = 0; 452 snes->umfunP = 0; 453 snes->fc = 0; 454 snes->deltatol = 1.e-12; 455 snes->fmin = -1.e30; 456 snes->method_class = type; 457 snes->set_method_called = 0; 458 snes->setup_called = 0; 459 snes->ksp_ewconv = 0; 460 461 /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 462 kctx = PetscNew(SNES_KSP_EW_ConvCtx); CHKPTRQ(kctx); 463 snes->kspconvctx = (void*)kctx; 464 kctx->version = 2; 465 kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 466 this was too large for some test cases */ 467 kctx->rtol_last = 0; 468 kctx->rtol_max = .9; 469 kctx->gamma = 1.0; 470 kctx->alpha2 = .5*(1.0 + sqrt(5.0)); 471 kctx->alpha = kctx->alpha2; 472 kctx->threshold = .1; 473 kctx->lresid_last = 0; 474 kctx->norm_last = 0; 475 476 ierr = SLESCreate(comm,&snes->sles); CHKERRQ(ierr); 477 PLogObjectParent(snes,snes->sles) 478 479 *outsnes = snes; 480 return 0; 481 } 482 483 /* --------------------------------------------------------------- */ 484 /*@C 485 SNESSetFunction - Sets the function evaluation routine and function 486 vector for use by the SNES routines in solving systems of nonlinear 487 equations. 488 489 Input Parameters: 490 . snes - the SNES context 491 . func - function evaluation routine 492 . ctx - optional user-defined function context 493 . r - vector to store function value 494 495 Calling sequence of func: 496 . func (SNES, Vec x, Vec f, void *ctx); 497 498 . x - input vector 499 . f - vector function 500 . ctx - optional user-defined context for private data for the 501 function evaluation routine (may be null) 502 503 Notes: 504 The Newton-like methods typically solve linear systems of the form 505 $ f'(x) x = -f(x), 506 $ where f'(x) denotes the Jacobian matrix and f(x) is the function. 507 508 SNESSetFunction() is valid for SNES_NONLINEAR_EQUATIONS methods only. 509 Analogous routines for SNES_UNCONSTRAINED_MINIMIZATION methods are 510 SNESSetMinimizationFunction() and SNESSetGradient(); 511 512 .keywords: SNES, nonlinear, set, function 513 514 .seealso: SNESGetFunction(), SNESSetJacobian(), SNESSetSolution() 515 @*/ 516 int SNESSetFunction( SNES snes, Vec r, int (*func)(SNES,Vec,Vec,void*),void *ctx) 517 { 518 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 519 if (snes->method_class != SNES_NONLINEAR_EQUATIONS) SETERRQ(1, 520 "SNESSetFunction:For SNES_NONLINEAR_EQUATIONS only"); 521 snes->computefunction = func; 522 snes->vec_func = snes->vec_func_always = r; 523 snes->funP = ctx; 524 return 0; 525 } 526 527 /*@ 528 SNESComputeFunction - Computes the function that has been set with 529 SNESSetFunction(). 530 531 Input Parameters: 532 . snes - the SNES context 533 . x - input vector 534 535 Output Parameter: 536 . y - function vector or its negative, as set by SNESSetFunction() 537 538 Notes: 539 SNESComputeFunction() is valid for SNES_NONLINEAR_EQUATIONS methods only. 540 Analogous routines for SNES_UNCONSTRAINED_MINIMIZATION methods are 541 SNESComputeMinimizationFunction() and SNESComputeGradient(); 542 543 .keywords: SNES, nonlinear, compute, function 544 545 .seealso: SNESSetFunction() 546 @*/ 547 int SNESComputeFunction(SNES snes,Vec x, Vec y) 548 { 549 int ierr; 550 551 PLogEventBegin(SNES_FunctionEval,snes,x,y,0); 552 ierr = (*snes->computefunction)(snes,x,y,snes->funP); CHKERRQ(ierr); 553 PLogEventEnd(SNES_FunctionEval,snes,x,y,0); 554 return 0; 555 } 556 557 /*@C 558 SNESSetMinimizationFunction - Sets the function evaluation routine for 559 unconstrained minimization. 560 561 Input Parameters: 562 . snes - the SNES context 563 . func - function evaluation routine 564 . ctx - optional user-defined function context 565 566 Calling sequence of func: 567 . func (SNES snes,Vec x,double *f,void *ctx); 568 569 . x - input vector 570 . f - function 571 . ctx - optional user-defined context for private data for the 572 function evaluation routine (may be null) 573 574 Notes: 575 SNESSetMinimizationFunction() is valid for SNES_UNCONSTRAINED_MINIMIZATION 576 methods only. An analogous routine for SNES_NONLINEAR_EQUATIONS methods is 577 SNESSetFunction(). 578 579 .keywords: SNES, nonlinear, set, minimization, function 580 581 .seealso: SNESGetMinimizationFunction(), SNESSetHessian(), SNESSetGradient(), 582 SNESSetSolution() 583 @*/ 584 int SNESSetMinimizationFunction(SNES snes,int (*func)(SNES,Vec,double*,void*), 585 void *ctx) 586 { 587 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 588 if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1, 589 "SNESSetMinimizationFunction:Only for SNES_UNCONSTRAINED_MINIMIZATION"); 590 snes->computeumfunction = func; 591 snes->umfunP = ctx; 592 return 0; 593 } 594 595 /*@ 596 SNESComputeMinimizationFunction - Computes the function that has been 597 set with SNESSetMinimizationFunction(). 598 599 Input Parameters: 600 . snes - the SNES context 601 . x - input vector 602 603 Output Parameter: 604 . y - function value 605 606 Notes: 607 SNESComputeMinimizationFunction() is valid only for 608 SNES_UNCONSTRAINED_MINIMIZATION methods. An analogous routine for 609 SNES_NONLINEAR_EQUATIONS methods is SNESComputeFunction(). 610 @*/ 611 int SNESComputeMinimizationFunction(SNES snes,Vec x,double *y) 612 { 613 int ierr; 614 if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1, 615 "SNESComputeMinimizationFunction:Only for SNES_UNCONSTRAINED_MINIMIZATION"); 616 PLogEventBegin(SNES_MinimizationFunctionEval,snes,x,y,0); 617 ierr = (*snes->computeumfunction)(snes,x,y,snes->umfunP); CHKERRQ(ierr); 618 PLogEventEnd(SNES_MinimizationFunctionEval,snes,x,y,0); 619 return 0; 620 } 621 622 /*@C 623 SNESSetGradient - Sets the gradient evaluation routine and gradient 624 vector for use by the SNES routines. 625 626 Input Parameters: 627 . snes - the SNES context 628 . func - function evaluation routine 629 . ctx - optional user-defined function context 630 . r - vector to store gradient value 631 632 Calling sequence of func: 633 . func (SNES, Vec x, Vec g, void *ctx); 634 635 . x - input vector 636 . g - gradient vector 637 . ctx - optional user-defined context for private data for the 638 function evaluation routine (may be null) 639 640 Notes: 641 SNESSetMinimizationFunction() is valid for SNES_UNCONSTRAINED_MINIMIZATION 642 methods only. An analogous routine for SNES_NONLINEAR_EQUATIONS methods is 643 SNESSetFunction(). 644 645 .keywords: SNES, nonlinear, set, function 646 647 .seealso: SNESGetGradient(), SNESSetHessian(), SNESSetMinimizationFunction(), 648 SNESSetSolution() 649 @*/ 650 int SNESSetGradient(SNES snes,Vec r,int (*func)(SNES,Vec,Vec,void*), 651 void *ctx) 652 { 653 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 654 if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1, 655 "SNESSetGradient:For SNES_UNCONSTRAINED_MINIMIZATION only"); 656 snes->computefunction = func; 657 snes->vec_func = snes->vec_func_always = r; 658 snes->funP = ctx; 659 return 0; 660 } 661 662 /*@ 663 SNESComputeGradient - Computes the gradient that has been 664 set with SNESSetGradient(). 665 666 Input Parameters: 667 . snes - the SNES context 668 . x - input vector 669 670 Output Parameter: 671 . y - gradient vector 672 673 Notes: 674 SNESComputeGradient() is valid only for 675 SNES_UNCONSTRAINED_MINIMIZATION methods. An analogous routine for 676 SNES_NONLINEAR_EQUATIONS methods is SNESComputeFunction(). 677 @*/ 678 int SNESComputeGradient(SNES snes,Vec x, Vec y) 679 { 680 int ierr; 681 if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1, 682 "SNESComputeGradient:For SNES_UNCONSTRAINED_MINIMIZATION only"); 683 PLogEventBegin(SNES_GradientEval,snes,x,y,0); 684 ierr = (*snes->computefunction)(snes,x,y,snes->funP); CHKERRQ(ierr); 685 PLogEventEnd(SNES_GradientEval,snes,x,y,0); 686 return 0; 687 } 688 689 int SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 690 { 691 int ierr; 692 if (snes->method_class != SNES_NONLINEAR_EQUATIONS) SETERRQ(1, 693 "SNESComputeJacobian: For SNES_NONLINEAR_EQUATIONS only"); 694 if (!snes->computejacobian) return 0; 695 PLogEventBegin(SNES_JacobianEval,snes,X,*A,*B); 696 *flg = ALLMAT_DIFFERENT_NONZERO_PATTERN; 697 ierr = (*snes->computejacobian)(snes,X,A,B,flg,snes->jacP); CHKERRQ(ierr); 698 PLogEventEnd(SNES_JacobianEval,snes,X,*A,*B); 699 return 0; 700 } 701 702 int SNESComputeHessian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 703 { 704 int ierr; 705 if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1, 706 "SNESComputeHessian:For SNES_UNCONSTRAINED_MINIMIZATION only"); 707 if (!snes->computejacobian) return 0; 708 PLogEventBegin(SNES_HessianEval,snes,X,*A,*B); 709 ierr = (*snes->computejacobian)(snes,X,A,B,flg,snes->jacP); CHKERRQ(ierr); 710 PLogEventEnd(SNES_HessianEval,snes,X,*A,*B); 711 return 0; 712 } 713 714 /*@C 715 SNESSetJacobian - Sets the function to compute Jacobian as well as the 716 location to store it. 717 718 Input Parameters: 719 . snes - the SNES context 720 . A - Jacobian matrix 721 . B - preconditioner matrix (usually same as the Jacobian) 722 . func - Jacobian evaluation routine 723 . ctx - optional user-defined context for private data for the 724 Jacobian evaluation routine (may be null) 725 726 Calling sequence of func: 727 . func (SNES,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 728 729 . x - input vector 730 . A - Jacobian matrix 731 . B - preconditioner matrix, usually the same as A 732 . flag - flag indicating information about matrix structure, 733 same as flag in SLESSetOperators() 734 . ctx - optional user-defined Jacobian context 735 736 Notes: 737 The function func() takes Mat * as the matrix arguments rather than Mat. 738 This allows the Jacobian evaluation routine to replace A and/or B with a 739 completely new new matrix structure (not just different matrix elements) 740 when appropriate, for instance, if the nonzero structure is changing 741 throughout the global iterations. 742 743 .keywords: SNES, nonlinear, set, Jacobian, matrix 744 745 .seealso: SNESSetFunction(), SNESSetSolution() 746 @*/ 747 int SNESSetJacobian(SNES snes,Mat A,Mat B,int (*func)(SNES,Vec,Mat*,Mat*, 748 MatStructure*,void*),void *ctx) 749 { 750 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 751 if (snes->method_class != SNES_NONLINEAR_EQUATIONS) SETERRQ(1, 752 "SNESSetJacobian:For SNES_NONLINEAR_EQUATIONS only"); 753 snes->computejacobian = func; 754 snes->jacP = ctx; 755 snes->jacobian = A; 756 snes->jacobian_pre = B; 757 return 0; 758 } 759 /*@ 760 SNESGetJacobian - Returns the Jacobian matrix and optionally the user 761 provided context for evaluating the Jacobian. 762 763 Input Parameter: 764 . snes - the nonlinear solver context 765 766 Output Parameters: 767 . A - location to stash Jacobian matrix (or PETSC_NULL) 768 . B - location to stash preconditioner matrix (or PETSC_NULL) 769 . ctx - location to stash Jacobian ctx (or PETSC_NULL) 770 771 .seealso: SNESSetJacobian(), SNESComputeJacobian() 772 @*/ 773 int SNESGetJacobian(SNES snes,Mat *A,Mat *B, void **ctx) 774 { 775 if (A) *A = snes->jacobian; 776 if (B) *B = snes->jacobian_pre; 777 if (ctx) *ctx = snes->jacP; 778 return 0; 779 } 780 781 /*@C 782 SNESSetHessian - Sets the function to compute Hessian as well as the 783 location to store it. 784 785 Input Parameters: 786 . snes - the SNES context 787 . A - Hessian matrix 788 . B - preconditioner matrix (usually same as the Hessian) 789 . func - Jacobian evaluation routine 790 . ctx - optional user-defined context for private data for the 791 Hessian evaluation routine (may be null) 792 793 Calling sequence of func: 794 . func (SNES,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 795 796 . x - input vector 797 . A - Hessian matrix 798 . B - preconditioner matrix, usually the same as A 799 . flag - flag indicating information about matrix structure, 800 same as flag in SLESSetOperators() 801 . ctx - optional user-defined Hessian context 802 803 Notes: 804 The function func() takes Mat * as the matrix arguments rather than Mat. 805 This allows the Hessian evaluation routine to replace A and/or B with a 806 completely new new matrix structure (not just different matrix elements) 807 when appropriate, for instance, if the nonzero structure is changing 808 throughout the global iterations. 809 810 .keywords: SNES, nonlinear, set, Hessian, matrix 811 812 .seealso: SNESSetMinimizationFunction(), SNESSetSolution(), SNESSetGradient() 813 @*/ 814 int SNESSetHessian(SNES snes,Mat A,Mat B,int (*func)(SNES,Vec,Mat*,Mat*, 815 MatStructure*,void*),void *ctx) 816 { 817 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 818 if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1, 819 "SNESSetHessian:For SNES_UNCONSTRAINED_MINIMIZATION only"); 820 snes->computejacobian = func; 821 snes->jacP = ctx; 822 snes->jacobian = A; 823 snes->jacobian_pre = B; 824 return 0; 825 } 826 827 /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 828 829 /*@ 830 SNESSetUp - Sets up the internal data structures for the later use 831 of a nonlinear solver. Call SNESSetUp() after calling SNESCreate() 832 and optional routines of the form SNESSetXXX(), but before calling 833 SNESSolve(). 834 835 Input Parameter: 836 . snes - the SNES context 837 838 .keywords: SNES, nonlinear, setup 839 840 .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 841 @*/ 842 int SNESSetUp(SNES snes) 843 { 844 int ierr; 845 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 846 if (!snes->vec_sol) SETERRQ(1,"SNESSetUp:Must call SNESSetSolution() first"); 847 848 if ((snes->method_class == SNES_NONLINEAR_EQUATIONS)) { 849 if (!snes->vec_func) SETERRQ(1,"SNESSetUp:Must call SNESSetFunction() first"); 850 if (!snes->computefunction) SETERRQ(1,"SNESSetUp:Must call SNESSetFunction() first"); 851 if (!snes->jacobian) SETERRQ(1,"SNESSetUp:Must call SNESSetJacobian() first"); 852 853 /* Set the KSP stopping criterion to use the Eisenstat-Walker method */ 854 if (snes->ksp_ewconv && snes->type != SNES_EQ_NTR) { 855 SLES sles; KSP ksp; 856 ierr = SNESGetSLES(snes,&sles); CHKERRQ(ierr); 857 ierr = SLESGetKSP(sles,&ksp); CHKERRQ(ierr); 858 ierr = KSPSetConvergenceTest(ksp,SNES_KSP_EW_Converged_Private, 859 (void *)snes); CHKERRQ(ierr); 860 } 861 } else if ((snes->method_class == SNES_UNCONSTRAINED_MINIMIZATION)) { 862 if (!snes->vec_func) SETERRQ(1,"SNESSetUp:Must call SNESSetGradient() first"); 863 if (!snes->computefunction) SETERRQ(1,"SNESSetUp:Must call SNESSetGradient() first"); 864 if (!snes->computeumfunction) 865 SETERRQ(1,"SNESSetUp:Must call SNESSetMinimizationFunction() first"); 866 if (!snes->jacobian) SETERRQ(1,"SNESSetUp:Must call SNESSetHessian() first"); 867 } else SETERRQ(1,"SNESSetUp:Unknown method class"); 868 if (snes->setup) {ierr = (*snes->setup)(snes); CHKERRQ(ierr);} 869 snes->setup_called = 1; 870 return 0; 871 } 872 873 /*@C 874 SNESDestroy - Destroys the nonlinear solver context that was created 875 with SNESCreate(). 876 877 Input Parameter: 878 . snes - the SNES context 879 880 .keywords: SNES, nonlinear, destroy 881 882 .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 883 @*/ 884 int SNESDestroy(SNES snes) 885 { 886 int ierr; 887 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 888 ierr = (*(snes)->destroy)((PetscObject)snes); CHKERRQ(ierr); 889 if (snes->kspconvctx) PetscFree(snes->kspconvctx); 890 if (snes->mfshell) MatDestroy(snes->mfshell); 891 ierr = SLESDestroy(snes->sles); CHKERRQ(ierr); 892 PLogObjectDestroy((PetscObject)snes); 893 PetscHeaderDestroy((PetscObject)snes); 894 return 0; 895 } 896 897 /* ----------- Routines to set solver parameters ---------- */ 898 899 /*@ 900 SNESSetMaxIterations - Sets the maximum number of global iterations to use. 901 902 Input Parameters: 903 . snes - the SNES context 904 . maxits - maximum number of iterations to use 905 906 Options Database Key: 907 $ -snes_max_it maxits 908 909 Note: 910 The default maximum number of iterations is 50. 911 912 .keywords: SNES, nonlinear, set, maximum, iterations 913 914 .seealso: SNESSetMaxFunctionEvaluations() 915 @*/ 916 int SNESSetMaxIterations(SNES snes,int maxits) 917 { 918 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 919 snes->max_its = maxits; 920 return 0; 921 } 922 923 /*@ 924 SNESSetMaxFunctionEvaluations - Sets the maximum number of function 925 evaluations to use. 926 927 Input Parameters: 928 . snes - the SNES context 929 . maxf - maximum number of function evaluations 930 931 Options Database Key: 932 $ -snes_max_funcs maxf 933 934 Note: 935 The default maximum number of function evaluations is 1000. 936 937 .keywords: SNES, nonlinear, set, maximum, function, evaluations 938 939 .seealso: SNESSetMaxIterations() 940 @*/ 941 int SNESSetMaxFunctionEvaluations(SNES snes,int maxf) 942 { 943 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 944 snes->max_funcs = maxf; 945 return 0; 946 } 947 948 /*@ 949 SNESSetRelativeTolerance - Sets the relative convergence tolerance. 950 951 Input Parameters: 952 . snes - the SNES context 953 . rtol - tolerance 954 955 Options Database Key: 956 $ -snes_rtol tol 957 958 .keywords: SNES, nonlinear, set, relative, convergence, tolerance 959 960 .seealso: SNESSetAbsoluteTolerance(), SNESSetSolutionTolerance(), 961 SNESSetTruncationTolerance() 962 @*/ 963 int SNESSetRelativeTolerance(SNES snes,double rtol) 964 { 965 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 966 snes->rtol = rtol; 967 return 0; 968 } 969 970 /*@ 971 SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 972 973 Input Parameters: 974 . snes - the SNES context 975 . tol - tolerance 976 977 Options Database Key: 978 $ -snes_trtol tol 979 980 .keywords: SNES, nonlinear, set, trust region, tolerance 981 982 .seealso: SNESSetAbsoluteTolerance(), SNESSetSolutionTolerance(), 983 SNESSetTruncationTolerance() 984 @*/ 985 int SNESSetTrustRegionTolerance(SNES snes,double tol) 986 { 987 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 988 snes->deltatol = tol; 989 return 0; 990 } 991 992 /*@ 993 SNESSetAbsoluteTolerance - Sets the absolute convergence tolerance. 994 995 Input Parameters: 996 . snes - the SNES context 997 . atol - tolerance 998 999 Options Database Key: 1000 $ -snes_atol tol 1001 1002 .keywords: SNES, nonlinear, set, absolute, convergence, tolerance 1003 1004 .seealso: SNESSetRelativeTolerance(), SNESSetSolutionTolerance(), 1005 SNESSetTruncationTolerance() 1006 @*/ 1007 int SNESSetAbsoluteTolerance(SNES snes,double atol) 1008 { 1009 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1010 snes->atol = atol; 1011 return 0; 1012 } 1013 1014 /*@ 1015 SNESSetTruncationTolerance - Sets the tolerance that may be used by the 1016 step routines to control the accuracy of the step computation. 1017 1018 Input Parameters: 1019 . snes - the SNES context 1020 . tol - tolerance 1021 1022 Options Database Key: 1023 $ -snes_ttol tol 1024 1025 Notes: 1026 If the step computation involves an application of the inverse 1027 Jacobian (or Hessian), this parameter may be used to control the 1028 accuracy of that application. 1029 1030 .keywords: SNES, nonlinear, set, truncation, tolerance 1031 1032 .seealso: SNESSetRelativeTolerance(), SNESSetSolutionTolerance(), 1033 SNESSetAbsoluteTolerance() 1034 @*/ 1035 int SNESSetTruncationTolerance(SNES snes,double tol) 1036 { 1037 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1038 snes->trunctol = tol; 1039 return 0; 1040 } 1041 1042 /*@ 1043 SNESSetSolutionTolerance - Sets the convergence tolerance in terms of 1044 the norm of the change in the solution between steps. 1045 1046 Input Parameters: 1047 . snes - the SNES context 1048 . tol - tolerance 1049 1050 Options Database Key: 1051 $ -snes_stol tol 1052 1053 .keywords: SNES, nonlinear, set, solution, tolerance 1054 1055 .seealso: SNESSetTruncationTolerance(), SNESSetRelativeTolerance(), 1056 SNESSetAbsoluteTolerance() 1057 @*/ 1058 int SNESSetSolutionTolerance( SNES snes, double tol ) 1059 { 1060 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1061 snes->xtol = tol; 1062 return 0; 1063 } 1064 1065 /*@ 1066 SNESSetMinFunctionTolerance - Sets the minimum allowable function tolerance 1067 for unconstrained minimization solvers. 1068 1069 Input Parameters: 1070 . snes - the SNES context 1071 . ftol - minimum function tolerance 1072 1073 Options Database Key: 1074 $ -snes_fmin ftol 1075 1076 Note: 1077 SNESSetMinFunctionTolerance() is valid for SNES_UNCONSTRAINED_MINIMIZATION 1078 methods only. 1079 1080 .keywords: SNES, nonlinear, set, minimum, convergence, function, tolerance 1081 1082 .seealso: SNESSetRelativeTolerance(), SNESSetSolutionTolerance(), 1083 SNESSetTruncationTolerance() 1084 @*/ 1085 int SNESSetMinFunctionTolerance(SNES snes,double ftol) 1086 { 1087 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1088 snes->fmin = ftol; 1089 return 0; 1090 } 1091 1092 1093 1094 /* ---------- Routines to set various aspects of nonlinear solver --------- */ 1095 1096 /*@C 1097 SNESSetSolution - Sets the solution vector for use by the SNES routines. 1098 1099 Input Parameters: 1100 . snes - the SNES context 1101 . x - the solution vector 1102 1103 1104 .keywords: SNES, nonlinear, set, solution, initial guess 1105 1106 .seealso: SNESGetSolution(), SNESSetJacobian(), SNESSetFunction() 1107 @*/ 1108 int SNESSetSolution(SNES snes,Vec x) 1109 { 1110 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1111 snes->vec_sol = snes->vec_sol_always = x; 1112 return 0; 1113 } 1114 1115 /* ------------ Routines to set performance monitoring options ----------- */ 1116 1117 /*@C 1118 SNESSetMonitor - Sets the function that is to be used at every 1119 iteration of the nonlinear solver to display the iteration's 1120 progress. 1121 1122 Input Parameters: 1123 . snes - the SNES context 1124 . func - monitoring routine 1125 . mctx - optional user-defined context for private data for the 1126 monitor routine (may be null) 1127 1128 Calling sequence of func: 1129 int func(SNES snes,int its, Vec x,Vec f,double norm,void *mctx) 1130 1131 $ snes - the SNES context 1132 $ its - iteration number 1133 $ mctx - optional monitoring context 1134 $ 1135 $ SNES_NONLINEAR_EQUATIONS methods: 1136 $ norm - 2-norm function value (may be estimated) 1137 $ 1138 $ SNES_UNCONSTRAINED_MINIMIZATION methods: 1139 $ norm - 2-norm gradient value (may be estimated) 1140 1141 .keywords: SNES, nonlinear, set, monitor 1142 1143 .seealso: SNESDefaultMonitor() 1144 @*/ 1145 int SNESSetMonitor( SNES snes, int (*func)(SNES,int,double,void*), 1146 void *mctx ) 1147 { 1148 snes->monitor = func; 1149 snes->monP = (void*)mctx; 1150 return 0; 1151 } 1152 1153 /*@C 1154 SNESSetConvergenceTest - Sets the function that is to be used 1155 to test for convergence of the nonlinear iterative solution. 1156 1157 Input Parameters: 1158 . snes - the SNES context 1159 . func - routine to test for convergence 1160 . cctx - optional context for private data for the convergence routine 1161 (may be null) 1162 1163 Calling sequence of func: 1164 int func (SNES snes,double xnorm,double gnorm, 1165 double f,void *cctx) 1166 1167 $ snes - the SNES context 1168 $ cctx - optional convergence context 1169 $ xnorm - 2-norm of current iterate 1170 $ 1171 $ SNES_NONLINEAR_EQUATIONS methods: 1172 $ gnorm - 2-norm of current step 1173 $ f - 2-norm of function 1174 $ 1175 $ SNES_UNCONSTRAINED_MINIMIZATION methods: 1176 $ gnorm - 2-norm of current gradient 1177 $ f - function value 1178 1179 .keywords: SNES, nonlinear, set, convergence, test 1180 1181 .seealso: SNESDefaultConverged() 1182 @*/ 1183 int SNESSetConvergenceTest(SNES snes, 1184 int (*func)(SNES,double,double,double,void*),void *cctx) 1185 { 1186 (snes)->converged = func; 1187 (snes)->cnvP = cctx; 1188 return 0; 1189 } 1190 1191 /* 1192 SNESScaleStep_Private - Scales a step so that its length is less than the 1193 positive parameter delta. 1194 1195 Input Parameters: 1196 . snes - the SNES context 1197 . y - approximate solution of linear system 1198 . fnorm - 2-norm of current function 1199 . delta - trust region size 1200 1201 Output Parameters: 1202 . gpnorm - predicted function norm at the new point, assuming local 1203 linearization. The value is zero if the step lies within the trust 1204 region, and exceeds zero otherwise. 1205 . ynorm - 2-norm of the step 1206 1207 Note: 1208 For non-trust region methods such as SNES_EQ_NLS, the parameter delta 1209 is set to be the maximum allowable step size. 1210 1211 .keywords: SNES, nonlinear, scale, step 1212 */ 1213 int SNESScaleStep_Private(SNES snes,Vec y,double *fnorm,double *delta, 1214 double *gpnorm,double *ynorm) 1215 { 1216 double norm; 1217 Scalar cnorm; 1218 VecNorm(y,NORM_2, &norm ); 1219 if (norm > *delta) { 1220 norm = *delta/norm; 1221 *gpnorm = (1.0 - norm)*(*fnorm); 1222 cnorm = norm; 1223 VecScale( &cnorm, y ); 1224 *ynorm = *delta; 1225 } else { 1226 *gpnorm = 0.0; 1227 *ynorm = norm; 1228 } 1229 return 0; 1230 } 1231 1232 /*@ 1233 SNESSolve - Solves a nonlinear system. Call SNESSolve after calling 1234 SNESCreate(), optional routines of the form SNESSetXXX(), and SNESSetUp(). 1235 1236 Input Parameter: 1237 . snes - the SNES context 1238 1239 Output Parameter: 1240 its - number of iterations until termination 1241 1242 .keywords: SNES, nonlinear, solve 1243 1244 .seealso: SNESCreate(), SNESSetUp(), SNESDestroy() 1245 @*/ 1246 int SNESSolve(SNES snes,int *its) 1247 { 1248 int ierr, flg; 1249 1250 if (!snes->setup_called) {ierr = SNESSetUp(snes); CHKERRQ(ierr);} 1251 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1252 PLogEventBegin(SNES_Solve,snes,0,0,0); 1253 ierr = (*(snes)->solve)(snes,its); CHKERRQ(ierr); 1254 PLogEventEnd(SNES_Solve,snes,0,0,0); 1255 ierr = OptionsHasName(PETSC_NULL,"-snes_view", &flg); CHKERRQ(ierr); 1256 if (flg) { ierr = SNESView(snes,STDOUT_VIEWER_WORLD); CHKERRQ(ierr); } 1257 return 0; 1258 } 1259 1260 /* --------- Internal routines for SNES Package --------- */ 1261 static NRList *__SNESList = 0; 1262 1263 /*@ 1264 SNESSetType - Sets the method for the nonlinear solver. 1265 1266 Input Parameters: 1267 . snes - the SNES context 1268 . method - a known method 1269 1270 Notes: 1271 See "petsc/include/snes.h" for available methods (for instance) 1272 $ Systems of nonlinear equations: 1273 $ SNES_EQ_NLS - Newton's method with line search 1274 $ SNES_EQ_NTR - Newton's method with trust region 1275 $ Unconstrained minimization: 1276 $ SNES_UM_NTR - Newton's method with trust region 1277 $ SNES_UM_NLS - Newton's method with line search 1278 1279 Options Database Command: 1280 $ -snes_type <method> 1281 $ Use -help for a list of available methods 1282 $ (for instance, ls or tr) 1283 1284 .keysords: SNES, set, method 1285 @*/ 1286 int SNESSetType(SNES snes,SNESType method) 1287 { 1288 int (*r)(SNES); 1289 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1290 /* Get the function pointers for the iterative method requested */ 1291 if (!__SNESList) {SNESRegisterAll();} 1292 if (!__SNESList) {SETERRQ(1,"SNESSetType:Could not get methods");} 1293 r = (int (*)(SNES))NRFindRoutine( __SNESList, (int)method, (char *)0 ); 1294 if (!r) {SETERRQ(1,"SNESSetType:Unknown method");} 1295 if (snes->data) PetscFree(snes->data); 1296 snes->set_method_called = 1; 1297 return (*r)(snes); 1298 } 1299 1300 /* --------------------------------------------------------------------- */ 1301 /*@C 1302 SNESRegister - Adds the method to the nonlinear solver package, given 1303 a function pointer and a nonlinear solver name of the type SNESType. 1304 1305 Input Parameters: 1306 . name - for instance SNES_EQ_NLS, SNES_EQ_NTR, ... 1307 . sname - corfunPonding string for name 1308 . create - routine to create method context 1309 1310 .keywords: SNES, nonlinear, register 1311 1312 .seealso: SNESRegisterAll(), SNESRegisterDestroy() 1313 @*/ 1314 int SNESRegister(int name, char *sname, int (*create)(SNES)) 1315 { 1316 int ierr; 1317 if (!__SNESList) {ierr = NRCreate(&__SNESList); CHKERRQ(ierr);} 1318 NRRegister( __SNESList, name, sname, (int (*)(void*))create ); 1319 return 0; 1320 } 1321 /* --------------------------------------------------------------------- */ 1322 /*@C 1323 SNESRegisterDestroy - Frees the list of nonlinear solvers that were 1324 registered by SNESRegister(). 1325 1326 .keywords: SNES, nonlinear, register, destroy 1327 1328 .seealso: SNESRegisterAll(), SNESRegisterAll() 1329 @*/ 1330 int SNESRegisterDestroy() 1331 { 1332 if (__SNESList) { 1333 NRDestroy( __SNESList ); 1334 __SNESList = 0; 1335 } 1336 return 0; 1337 } 1338 1339 /* 1340 SNESGetTypeFromOptions_Private - Sets the selected method from the 1341 options database. 1342 1343 Input Parameter: 1344 . ctx - the SNES context 1345 1346 Output Parameter: 1347 . method - solver method 1348 1349 Returns: 1350 Returns 1 if the method is found; 0 otherwise. 1351 1352 Options Database Key: 1353 $ -snes_type method 1354 */ 1355 int SNESGetTypeFromOptions_Private(SNES ctx,SNESType *method,int *flg) 1356 { 1357 int ierr; 1358 char sbuf[50]; 1359 ierr = OptionsGetString(ctx->prefix,"-snes_type", sbuf, 50, flg); CHKERRQ(ierr); 1360 if (*flg) { 1361 if (!__SNESList) {ierr = SNESRegisterAll(); CHKERRQ(ierr);} 1362 *method = (SNESType)NRFindID( __SNESList, sbuf ); 1363 } 1364 return 0; 1365 } 1366 1367 /*@C 1368 SNESGetType - Gets the SNES method type and name (as a string). 1369 1370 Input Parameter: 1371 . snes - nonlinear solver context 1372 1373 Output Parameter: 1374 . method - SNES method (or use PETSC_NULL) 1375 . name - name of SNES method (or use PETSC_NULL) 1376 1377 .keywords: SNES, nonlinear, get, method, name 1378 @*/ 1379 int SNESGetType(SNES snes, SNESType *method,char **name) 1380 { 1381 int ierr; 1382 if (!__SNESList) {ierr = SNESRegisterAll(); CHKERRQ(ierr);} 1383 if (method) *method = (SNESType) snes->type; 1384 if (name) *name = NRFindName( __SNESList, (int) snes->type ); 1385 return 0; 1386 } 1387 1388 #include <stdio.h> 1389 /* 1390 SNESPrintTypes_Private - Prints the SNES methods available from the 1391 options database. 1392 1393 Input Parameters: 1394 . prefix - prefix (usually "-") 1395 . name - the options database name (by default "snes_type") 1396 */ 1397 int SNESPrintTypes_Private(char* prefix,char *name) 1398 { 1399 FuncList *entry; 1400 if (!__SNESList) {SNESRegisterAll();} 1401 entry = __SNESList->head; 1402 fprintf(stderr," %s%s (one of)",prefix,name); 1403 while (entry) { 1404 fprintf(stderr," %s",entry->name); 1405 entry = entry->next; 1406 } 1407 fprintf(stderr,"\n"); 1408 return 0; 1409 } 1410 1411 /*@C 1412 SNESGetSolution - Returns the vector where the approximate solution is 1413 stored. 1414 1415 Input Parameter: 1416 . snes - the SNES context 1417 1418 Output Parameter: 1419 . x - the solution 1420 1421 .keywords: SNES, nonlinear, get, solution 1422 1423 .seealso: SNESSetSolution(), SNESGetFunction(), SNESGetSolutionUpdate() 1424 @*/ 1425 int SNESGetSolution(SNES snes,Vec *x) 1426 { 1427 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1428 *x = snes->vec_sol_always; 1429 return 0; 1430 } 1431 1432 /*@C 1433 SNESGetSolutionUpdate - Returns the vector where the solution update is 1434 stored. 1435 1436 Input Parameter: 1437 . snes - the SNES context 1438 1439 Output Parameter: 1440 . x - the solution update 1441 1442 Notes: 1443 This vector is implementation dependent. 1444 1445 .keywords: SNES, nonlinear, get, solution, update 1446 1447 .seealso: SNESGetSolution(), SNESGetFunction 1448 @*/ 1449 int SNESGetSolutionUpdate(SNES snes,Vec *x) 1450 { 1451 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1452 *x = snes->vec_sol_update_always; 1453 return 0; 1454 } 1455 1456 /*@C 1457 SNESGetFunction - Returns the vector where the function is 1458 stored. Actually usually returns the vector where the negative of 1459 the function is stored. 1460 1461 Input Parameter: 1462 . snes - the SNES context 1463 1464 Output Parameter: 1465 . r - the function (or its negative) 1466 1467 Notes: 1468 SNESGetFunction() is valid for SNES_NONLINEAR_EQUATIONS methods only 1469 Analogous routines for SNES_UNCONSTRAINED_MINIMIZATION methods are 1470 SNESGetMinimizationFunction() and SNESGetGradient(); 1471 1472 .keywords: SNES, nonlinear, get function 1473 1474 .seealso: SNESSetFunction(), SNESGetSolution() 1475 @*/ 1476 int SNESGetFunction(SNES snes,Vec *r) 1477 { 1478 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1479 if (snes->method_class != SNES_NONLINEAR_EQUATIONS) SETERRQ(1, 1480 "SNESGetFunction:For SNES_NONLINEAR_EQUATIONS only"); 1481 *r = snes->vec_func_always; 1482 return 0; 1483 } 1484 1485 /*@C 1486 SNESGetGradient - Returns the vector where the gradient is 1487 stored. Actually usually returns the vector where the negative of 1488 the function is stored. 1489 1490 Input Parameter: 1491 . snes - the SNES context 1492 1493 Output Parameter: 1494 . r - the gradient 1495 1496 Notes: 1497 SNESGetGradient() is valid for SNES_UNCONSTRAINED_MINIMIZATION methods 1498 only. An analogous routine for SNES_NONLINEAR_EQUATIONS methods is 1499 SNESGetFunction(). 1500 1501 .keywords: SNES, nonlinear, get, gradient 1502 1503 .seealso: SNESGetMinimizationFunction(), SNESGetSolution() 1504 @*/ 1505 int SNESGetGradient(SNES snes,Vec *r) 1506 { 1507 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1508 if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1, 1509 "SNESGetGradient:For SNES_UNCONSTRAINED_MINIMIZATION only"); 1510 *r = snes->vec_func_always; 1511 return 0; 1512 } 1513 1514 /*@ 1515 SNESGetMinimizationFunction - Returns the scalar function value for 1516 unconstrained minimization problems. 1517 1518 Input Parameter: 1519 . snes - the SNES context 1520 1521 Output Parameter: 1522 . r - the function 1523 1524 Notes: 1525 SNESGetMinimizationFunction() is valid for SNES_UNCONSTRAINED_MINIMIZATION 1526 methods only. An analogous routine for SNES_NONLINEAR_EQUATIONS methods is 1527 SNESGetFunction(). 1528 1529 .keywords: SNES, nonlinear, get, function 1530 1531 .seealso: SNESGetGradient(), SNESGetSolution() 1532 @*/ 1533 int SNESGetMinimizationFunction(SNES snes,double *r) 1534 { 1535 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1536 if (snes->method_class != SNES_UNCONSTRAINED_MINIMIZATION) SETERRQ(1, 1537 "SNESGetMinimizationFunction:For SNES_UNCONSTRAINED_MINIMIZATION only"); 1538 *r = snes->fc; 1539 return 0; 1540 } 1541 1542 1543 /*@C 1544 SNESSetOptionsPrefix - Sets the prefix used for searching for all 1545 SNES options in the database. 1546 1547 Input Parameter: 1548 . snes - the SNES context 1549 . prefix - the prefix to prepend to all option names 1550 1551 .keywords: SNES, set, options, prefix, database 1552 @*/ 1553 int SNESSetOptionsPrefix(SNES snes,char *prefix) 1554 { 1555 int ierr; 1556 1557 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1558 ierr = PetscObjectSetPrefix((PetscObject)snes, prefix); CHKERRQ(ierr); 1559 ierr = SLESSetOptionsPrefix(snes->sles,prefix);CHKERRQ(ierr); 1560 return 0; 1561 } 1562 1563 /*@C 1564 SNESAppendOptionsPrefix - Append to the prefix used for searching for all 1565 SNES options in the database. 1566 1567 Input Parameter: 1568 . snes - the SNES context 1569 . prefix - the prefix to prepend to all option names 1570 1571 .keywords: SNES, append, options, prefix, database 1572 @*/ 1573 int SNESAppendOptionsPrefix(SNES snes,char *prefix) 1574 { 1575 int ierr; 1576 1577 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1578 ierr = PetscObjectAppendPrefix((PetscObject)snes, prefix); CHKERRQ(ierr); 1579 ierr = SLESAppendOptionsPrefix(snes->sles,prefix);CHKERRQ(ierr); 1580 return 0; 1581 } 1582 1583 /*@ 1584 SNESGetOptionsPrefix - Sets the prefix used for searching for all 1585 SNES options in the database. 1586 1587 Input Parameter: 1588 . snes - the SNES context 1589 1590 Output Parameter: 1591 . prefix - pointer to the prefix string used 1592 1593 .keywords: SNES, get, options, prefix, database 1594 @*/ 1595 int SNESGetOptionsPrefix(SNES snes,char **prefix) 1596 { 1597 int ierr; 1598 1599 PETSCVALIDHEADERSPECIFIC(snes,SNES_COOKIE); 1600 ierr = PetscObjectGetPrefix((PetscObject)snes, prefix); CHKERRQ(ierr); 1601 return 0; 1602 } 1603 1604 1605 1606 1607 1608