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