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