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