1*11320018SBarry Smith 2*11320018SBarry Smith #ifndef lint 3*11320018SBarry Smith static char vcid[] = "$Id: snes.c,v 1.11 1995/04/27 20:17:07 bsmith Exp bsmith $"; 4*11320018SBarry Smith #endif 5*11320018SBarry Smith 6*11320018SBarry Smith #include "draw.h" 7*11320018SBarry Smith #include "snesimpl.h" 8*11320018SBarry Smith #include "options.h" 9*11320018SBarry Smith 10*11320018SBarry Smith /*@ 11*11320018SBarry Smith SNESSetFromOptions - Sets various SLES parameters from user options. 12*11320018SBarry Smith 13*11320018SBarry Smith Input Parameter: 14*11320018SBarry Smith . snes - the SNES context 15*11320018SBarry Smith 16*11320018SBarry Smith .keywords: SNES, nonlinear, set, options, database 17*11320018SBarry Smith 18*11320018SBarry Smith .seealso: SNESPrintHelp() 19*11320018SBarry Smith @*/ 20*11320018SBarry Smith int SNESSetFromOptions(SNES snes) 21*11320018SBarry Smith { 22*11320018SBarry Smith SNESMETHOD method; 23*11320018SBarry Smith double tmp; 24*11320018SBarry Smith SLES sles; 25*11320018SBarry Smith VALIDHEADER(snes,SNES_COOKIE); 26*11320018SBarry Smith if (SNESGetMethodFromOptions(snes,&method)) { 27*11320018SBarry Smith SNESSetMethod(snes,method); 28*11320018SBarry Smith } 29*11320018SBarry Smith if (OptionsHasName(0,0,"-help")) SNESPrintHelp(snes); 30*11320018SBarry Smith if (OptionsGetDouble(0,snes->prefix,"-snes_stol",&tmp)) { 31*11320018SBarry Smith SNESSetSolutionTolerance(snes,tmp); 32*11320018SBarry Smith } 33*11320018SBarry Smith if (OptionsGetDouble(0,snes->prefix,"-snes_ttol",&tmp)) { 34*11320018SBarry Smith SNESSetTruncationTolerance(snes,tmp); 35*11320018SBarry Smith } 36*11320018SBarry Smith if (OptionsGetDouble(0,snes->prefix,"-snes_atol",&tmp)) { 37*11320018SBarry Smith SNESSetAbsoluteTolerance(snes,tmp); 38*11320018SBarry Smith } 39*11320018SBarry Smith if (OptionsGetDouble(0,snes->prefix,"-snes_rtol",&tmp)) { 40*11320018SBarry Smith SNESSetRelativeTolerance(snes,tmp); 41*11320018SBarry Smith } 42*11320018SBarry Smith OptionsGetInt(0,snes->prefix,"-snes_max_it",&snes->max_its); 43*11320018SBarry Smith OptionsGetInt(0,snes->prefix,"-snes_max_resid",&snes->max_resids); 44*11320018SBarry Smith if (OptionsHasName(0,snes->prefix,"-snes_monitor")) { 45*11320018SBarry Smith SNESSetMonitor(snes,SNESDefaultMonitor,0); 46*11320018SBarry Smith } 47*11320018SBarry Smith if (OptionsHasName(0,snes->prefix,"-snes_xmonitor")){ 48*11320018SBarry Smith int ierr,mytid = 0; 49*11320018SBarry Smith DrawLGCtx lg; 50*11320018SBarry Smith MPI_Initialized(&mytid); 51*11320018SBarry Smith if (mytid) MPI_Comm_rank(snes->comm,&mytid); 52*11320018SBarry Smith if (!mytid) { 53*11320018SBarry Smith ierr = SNESLGMonitorCreate(0,0,0,0,300,300,&lg); CHKERR(ierr); 54*11320018SBarry Smith SNESSetMonitor(snes,SNESLGMonitor,(void *)lg); 55*11320018SBarry Smith } 56*11320018SBarry Smith } 57*11320018SBarry Smith SNESGetSLES(snes,&sles); 58*11320018SBarry Smith SLESSetFromOptions(sles); 59*11320018SBarry Smith if (!snes->SetFromOptions) return 0; 60*11320018SBarry Smith return (*snes->SetFromOptions)(snes); 61*11320018SBarry Smith } 62*11320018SBarry Smith 63*11320018SBarry Smith /*@ 64*11320018SBarry Smith SNESPrintHelp - Prints all options for the SNES component. 65*11320018SBarry Smith 66*11320018SBarry Smith Input Parameter: 67*11320018SBarry Smith . snes - the SNES context 68*11320018SBarry Smith 69*11320018SBarry Smith .keywords: SNES, nonlinear, help 70*11320018SBarry Smith 71*11320018SBarry Smith .seealso: SLESSetFromOptions() 72*11320018SBarry Smith @*/ 73*11320018SBarry Smith int SNESPrintHelp(SNES snes) 74*11320018SBarry Smith { 75*11320018SBarry Smith int rank; 76*11320018SBarry Smith char *prefix = "-"; 77*11320018SBarry Smith if (snes->prefix) prefix = snes->prefix; 78*11320018SBarry Smith VALIDHEADER(snes,SNES_COOKIE); 79*11320018SBarry Smith if (!snes->PrintHelp) return 0; 80*11320018SBarry Smith MPI_Comm_rank(snes->comm,&rank); if (rank) return 0; 81*11320018SBarry Smith fprintf(stderr,"SNES options ----------------------------\n"); 82*11320018SBarry Smith fprintf(stderr,"%ssnes_method [ls] \n",prefix); 83*11320018SBarry Smith fprintf(stderr,"%ssnes_stol tol (default %g)\n",prefix,snes->xtol); 84*11320018SBarry Smith fprintf(stderr,"%ssnes_atol tol (default %g)\n",prefix,snes->atol); 85*11320018SBarry Smith fprintf(stderr,"%ssnes_rtol tol (default %g)\n",prefix,snes->rtol); 86*11320018SBarry Smith fprintf(stderr,"%ssnes_ttol tol (default %g)\n",prefix,snes->trunctol); 87*11320018SBarry Smith fprintf(stderr,"%ssnes_max_it its (default %d)\n",prefix,snes->max_its); 88*11320018SBarry Smith fprintf(stderr,"%ssnes_monitor\n",prefix); 89*11320018SBarry Smith return (*snes->PrintHelp)(snes); 90*11320018SBarry Smith } 91*11320018SBarry Smith /*@ 92*11320018SBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 93*11320018SBarry Smith the nonlinear solvers. 94*11320018SBarry Smith 95*11320018SBarry Smith Input Parameters: 96*11320018SBarry Smith . snes - the SNES context 97*11320018SBarry Smith . usrP - optional user context 98*11320018SBarry Smith 99*11320018SBarry Smith .keywords: SNES, nonlinear, set, application, context 100*11320018SBarry Smith 101*11320018SBarry Smith .seealso: SNESGetApplicationContext() 102*11320018SBarry Smith @*/ 103*11320018SBarry Smith int SNESSetApplicationContext(SNES snes,void *usrP) 104*11320018SBarry Smith { 105*11320018SBarry Smith VALIDHEADER(snes,SNES_COOKIE); 106*11320018SBarry Smith snes->user = usrP; 107*11320018SBarry Smith return 0; 108*11320018SBarry Smith } 109*11320018SBarry Smith /*@ 110*11320018SBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 111*11320018SBarry Smith nonlinear solvers. 112*11320018SBarry Smith 113*11320018SBarry Smith Input Parameter: 114*11320018SBarry Smith . snes - SNES context 115*11320018SBarry Smith 116*11320018SBarry Smith Output Parameter: 117*11320018SBarry Smith . usrP - user context 118*11320018SBarry Smith 119*11320018SBarry Smith .keywords: SNES, nonlinear, get, application, context 120*11320018SBarry Smith 121*11320018SBarry Smith .seealso: SNESSetApplicationContext() 122*11320018SBarry Smith @*/ 123*11320018SBarry Smith int SNESGetApplicationContext( SNES snes, void **usrP ) 124*11320018SBarry Smith { 125*11320018SBarry Smith VALIDHEADER(snes,SNES_COOKIE); 126*11320018SBarry Smith *usrP = snes->user; 127*11320018SBarry Smith return 0; 128*11320018SBarry Smith } 129*11320018SBarry Smith 130*11320018SBarry Smith /*@ 131*11320018SBarry Smith SNESGetSLES - Returns the SLES context for a SNES solver. 132*11320018SBarry Smith 133*11320018SBarry Smith Input Parameter: 134*11320018SBarry Smith . snes - the SNES context 135*11320018SBarry Smith 136*11320018SBarry Smith Output Parameter: 137*11320018SBarry Smith . sles - the SLES context 138*11320018SBarry Smith 139*11320018SBarry Smith Notes: 140*11320018SBarry Smith The user can then directly manipulate the SLES context to set various 141*11320018SBarry Smith options, etc. Likewise, the user can then manipulate the KSP and PC 142*11320018SBarry Smith contexts as well. 143*11320018SBarry Smith 144*11320018SBarry Smith .keywords: SNES, nonlinear, get, SLES, context 145*11320018SBarry Smith 146*11320018SBarry Smith .seealso: SLESGetPC(), SLESGetKSP() 147*11320018SBarry Smith @*/ 148*11320018SBarry Smith int SNESGetSLES(SNES snes,SLES *sles) 149*11320018SBarry Smith { 150*11320018SBarry Smith VALIDHEADER(snes,SNES_COOKIE); 151*11320018SBarry Smith *sles = snes->sles; 152*11320018SBarry Smith return 0; 153*11320018SBarry Smith } 154*11320018SBarry Smith 155*11320018SBarry Smith /* -----------------------------------------------------------*/ 156*11320018SBarry Smith 157*11320018SBarry Smith /*@ 158*11320018SBarry Smith SNESCreate - Creates a nonlinear solver context. 159*11320018SBarry Smith 160*11320018SBarry Smith Input Parameter: 161*11320018SBarry Smith . comm - MPI communicator 162*11320018SBarry Smith 163*11320018SBarry Smith Output Parameter: 164*11320018SBarry Smith . outsnes - the new SNES context 165*11320018SBarry Smith 166*11320018SBarry Smith .keywords: SNES, nonlinear, create, context 167*11320018SBarry Smith 168*11320018SBarry Smith .seealso: SNESSetUp(), SNESSolve(), SNESDestroy() 169*11320018SBarry Smith @*/ 170*11320018SBarry Smith int SNESCreate(MPI_Comm comm, SNES *outsnes) 171*11320018SBarry Smith { 172*11320018SBarry Smith int ierr; 173*11320018SBarry Smith SNES snes; 174*11320018SBarry Smith *outsnes = 0; 175*11320018SBarry Smith PETSCHEADERCREATE(snes,_SNES,SNES_COOKIE,SNES_NLS,comm); 176*11320018SBarry Smith PLogObjectCreate(snes); 177*11320018SBarry Smith snes->max_its = 50; 178*11320018SBarry Smith snes->max_resids = 1000; 179*11320018SBarry Smith snes->max_funcs = 1000; 180*11320018SBarry Smith snes->norm = 0.0; 181*11320018SBarry Smith snes->rtol = 1.e-8; 182*11320018SBarry Smith snes->atol = 1.e-10; 183*11320018SBarry Smith snes->xtol = 1.e-8; 184*11320018SBarry Smith snes->trunctol = 1.e-12; 185*11320018SBarry Smith snes->nresids = 0; 186*11320018SBarry Smith snes->Monitor = 0; 187*11320018SBarry Smith ierr = SLESCreate(comm,&snes->sles); CHKERR(ierr); 188*11320018SBarry Smith PLogObjectParent(snes,snes->sles) 189*11320018SBarry Smith *outsnes = snes; 190*11320018SBarry Smith return 0; 191*11320018SBarry Smith } 192*11320018SBarry Smith 193*11320018SBarry Smith /* --------------------------------------------------------------- */ 194*11320018SBarry Smith /*@C 195*11320018SBarry Smith SNESSetFunction - Sets the residual evaluation routine and residual 196*11320018SBarry Smith vector for use by the SNES routines. 197*11320018SBarry Smith 198*11320018SBarry Smith Input Parameters: 199*11320018SBarry Smith . snes - the SNES context 200*11320018SBarry Smith . func - residual evaluation routine 201*11320018SBarry Smith . resid_neg - indicator whether func evaluates f or -f. 202*11320018SBarry Smith If resid_neg is nonzero, then func evaluates -f; otherwise, 203*11320018SBarry Smith func evaluates f. 204*11320018SBarry Smith . ctx - optional user-defined function context 205*11320018SBarry Smith . r - vector to store residual 206*11320018SBarry Smith 207*11320018SBarry Smith Calling sequence of func: 208*11320018SBarry Smith . func (Vec x, Vec f, void *ctx); 209*11320018SBarry Smith 210*11320018SBarry Smith . x - input vector 211*11320018SBarry Smith . f - residual vector or its negative 212*11320018SBarry Smith . ctx - optional user-defined context for private data for the 213*11320018SBarry Smith residual evaluation routine (may be null) 214*11320018SBarry Smith 215*11320018SBarry Smith Notes: 216*11320018SBarry Smith The Newton-like methods typically solve linear systems of the form 217*11320018SBarry Smith $ f'(x) x = -f(x), 218*11320018SBarry Smith $ where f'(x) denotes the Jacobian matrix and f(x) is the residual. 219*11320018SBarry Smith By setting resid_neg = 1, the user can supply -f(x) directly. 220*11320018SBarry Smith 221*11320018SBarry Smith .keywords: SNES, nonlinear, set, residual 222*11320018SBarry Smith 223*11320018SBarry Smith .seealso: SNESGetFunction(), SNESSetJacobian(), SNESSetSolution() 224*11320018SBarry Smith @*/ 225*11320018SBarry Smith int SNESSetFunction( SNES snes, Vec r, int (*func)(Vec,Vec,void*), 226*11320018SBarry Smith void *ctx,int rneg) 227*11320018SBarry Smith { 228*11320018SBarry Smith VALIDHEADER(snes,SNES_COOKIE); 229*11320018SBarry Smith snes->ComputeResidual = func; 230*11320018SBarry Smith snes->rsign = rneg; 231*11320018SBarry Smith snes->vec_res = r; 232*11320018SBarry Smith snes->resP = ctx; 233*11320018SBarry Smith return 0; 234*11320018SBarry Smith } 235*11320018SBarry Smith 236*11320018SBarry Smith int SNESComputeFunction(SNES snes,Vec x, Vec y) 237*11320018SBarry Smith { 238*11320018SBarry Smith int ierr; 239*11320018SBarry Smith Scalar mone = -1.0; 240*11320018SBarry Smith ierr = (*snes->ComputeResidual)(x,y,snes->resP); CHKERR(ierr); 241*11320018SBarry Smith snes->nresids++; 242*11320018SBarry Smith if (!snes->rsign) { 243*11320018SBarry Smith ierr = VecScale(&mone,y); CHKERR(ierr); 244*11320018SBarry Smith } 245*11320018SBarry Smith return 0; 246*11320018SBarry Smith } 247*11320018SBarry Smith 248*11320018SBarry Smith /*@ 249*11320018SBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 250*11320018SBarry Smith location to store it. 251*11320018SBarry Smith 252*11320018SBarry Smith Input Parameters: 253*11320018SBarry Smith . snes - the SNES context 254*11320018SBarry Smith . A - Jacobian matrix 255*11320018SBarry Smith . func - Jacobian evaluation routine 256*11320018SBarry Smith . ctx - optional user-defined context for private data for the 257*11320018SBarry Smith Jacobian evaluation routine (may be null) 258*11320018SBarry Smith 259*11320018SBarry Smith Calling sequence of func: 260*11320018SBarry Smith . func (Vec x, Mat *A, Mat *B, int *flag,void *ctx); 261*11320018SBarry Smith 262*11320018SBarry Smith . x - input vector 263*11320018SBarry Smith . A - Jacobian matrix 264*11320018SBarry Smith . B - preconditioner matrix, usually the same as A 265*11320018SBarry Smith . flag - same as options to SLESSetOperators(). Usually 0 or 266*11320018SBarry Smith $ MAT_SAME_NONZERO_PATTERN 267*11320018SBarry Smith . ctx - optional user-defined Jacobian context 268*11320018SBarry Smith 269*11320018SBarry Smith Notes: 270*11320018SBarry Smith The function func() takes a Mat * as an argument rather than a Mat. 271*11320018SBarry Smith This is to allow the Jacobian code to replace it with a new matrix 272*11320018SBarry Smith when appropriate, for instance, if the nonzero structure is changing. 273*11320018SBarry Smith 274*11320018SBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 275*11320018SBarry Smith 276*11320018SBarry Smith .seealso: SNESSetFunction(), SNESSetSolution() 277*11320018SBarry Smith @*/ 278*11320018SBarry Smith int SNESSetJacobian(SNES snes,Mat A,Mat B,int (*func)(Vec,Mat*,Mat*,int*,void*), 279*11320018SBarry Smith void *ctx) 280*11320018SBarry Smith { 281*11320018SBarry Smith VALIDHEADER(snes,SNES_COOKIE); 282*11320018SBarry Smith snes->ComputeJacobian = func; 283*11320018SBarry Smith snes->jacP = ctx; 284*11320018SBarry Smith snes->jacobian = A; 285*11320018SBarry Smith snes->jacobian_pre = B; 286*11320018SBarry Smith return 0; 287*11320018SBarry Smith } 288*11320018SBarry Smith 289*11320018SBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 290*11320018SBarry Smith 291*11320018SBarry Smith /*@ 292*11320018SBarry Smith SNESSetUp - Sets up the internal data structures for the later use 293*11320018SBarry Smith of a nonlinear solver. Call SNESSetUp() after calling SNESCreate() 294*11320018SBarry Smith and optional routines of the form SNESSetXXX(), but before calling 295*11320018SBarry Smith SNESSolve(). 296*11320018SBarry Smith 297*11320018SBarry Smith Input Parameter: 298*11320018SBarry Smith . snes - the SNES context 299*11320018SBarry Smith 300*11320018SBarry Smith .keywords: SNES, nonlinear, setup 301*11320018SBarry Smith 302*11320018SBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 303*11320018SBarry Smith @*/ 304*11320018SBarry Smith int SNESSetUp(SNES snes) 305*11320018SBarry Smith { 306*11320018SBarry Smith VALIDHEADER(snes,SNES_COOKIE); 307*11320018SBarry Smith return (*(snes)->Setup)( snes ); 308*11320018SBarry Smith } 309*11320018SBarry Smith 310*11320018SBarry Smith /*@ 311*11320018SBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 312*11320018SBarry Smith with SNESCreate(). 313*11320018SBarry Smith 314*11320018SBarry Smith Input Parameter: 315*11320018SBarry Smith . snes - the SNES context 316*11320018SBarry Smith 317*11320018SBarry Smith .keywords: SNES, nonlinear, destroy 318*11320018SBarry Smith 319*11320018SBarry Smith .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 320*11320018SBarry Smith @*/ 321*11320018SBarry Smith int SNESDestroy(SNES snes) 322*11320018SBarry Smith { 323*11320018SBarry Smith VALIDHEADER(snes,SNES_COOKIE); 324*11320018SBarry Smith return (*(snes)->destroy)( (PetscObject) snes ); 325*11320018SBarry Smith } 326*11320018SBarry Smith 327*11320018SBarry Smith /* ----------- Routines to set solver parameters ---------- */ 328*11320018SBarry Smith 329*11320018SBarry Smith /*@ 330*11320018SBarry Smith SNESSetMaxIterations - Sets the maximum number of global iterations to use. 331*11320018SBarry Smith 332*11320018SBarry Smith Input Parameters: 333*11320018SBarry Smith . snes - the SNES context 334*11320018SBarry Smith . maxits - maximum number of iterations to use 335*11320018SBarry Smith 336*11320018SBarry Smith Options Database Key: 337*11320018SBarry Smith $ -snes_max_it maxits 338*11320018SBarry Smith 339*11320018SBarry Smith Note: 340*11320018SBarry Smith The default maximum number of iterations is 50. 341*11320018SBarry Smith 342*11320018SBarry Smith .keywords: SNES, nonlinear, set, maximum, iterations 343*11320018SBarry Smith 344*11320018SBarry Smith .seealso: SNESSetMaxResidualEvaluations() 345*11320018SBarry Smith @*/ 346*11320018SBarry Smith int SNESSetMaxIterations(SNES snes,int maxits) 347*11320018SBarry Smith { 348*11320018SBarry Smith VALIDHEADER(snes,SNES_COOKIE); 349*11320018SBarry Smith snes->max_its = maxits; 350*11320018SBarry Smith return 0; 351*11320018SBarry Smith } 352*11320018SBarry Smith 353*11320018SBarry Smith /*@ 354*11320018SBarry Smith SNESSetMaxResidualEvaluations - Sets the maximum number of residual 355*11320018SBarry Smith evaluations to use. 356*11320018SBarry Smith 357*11320018SBarry Smith Input Parameters: 358*11320018SBarry Smith . snes - the SNES context 359*11320018SBarry Smith . maxr - maximum number of residual evaluations 360*11320018SBarry Smith 361*11320018SBarry Smith Options Database Key: 362*11320018SBarry Smith $ -snes_max_resid maxr 363*11320018SBarry Smith 364*11320018SBarry Smith Note: 365*11320018SBarry Smith The default maximum number of residual evaluations is 1000. 366*11320018SBarry Smith 367*11320018SBarry Smith .keywords: SNES, nonlinear, set, maximum, residual, evaluations 368*11320018SBarry Smith 369*11320018SBarry Smith .seealso: SNESSetMaxIterations() 370*11320018SBarry Smith @*/ 371*11320018SBarry Smith int SNESSetMaxResidualEvaluations(SNES snes,int maxr) 372*11320018SBarry Smith { 373*11320018SBarry Smith VALIDHEADER(snes,SNES_COOKIE); 374*11320018SBarry Smith snes->max_resids = maxr; 375*11320018SBarry Smith return 0; 376*11320018SBarry Smith } 377*11320018SBarry Smith 378*11320018SBarry Smith /*@ 379*11320018SBarry Smith SNESSetRelativeTolerance - Sets the relative convergence tolerance. 380*11320018SBarry Smith 381*11320018SBarry Smith Input Parameters: 382*11320018SBarry Smith . snes - the SNES context 383*11320018SBarry Smith . rtol - tolerance 384*11320018SBarry Smith 385*11320018SBarry Smith Options Database Key: 386*11320018SBarry Smith $ -snes_rtol tol 387*11320018SBarry Smith 388*11320018SBarry Smith .keywords: SNES, nonlinear, set, relative, convergence, tolerance 389*11320018SBarry Smith 390*11320018SBarry Smith .seealso: SNESSetAbsoluteTolerance(), SNESSetSolutionTolerance(), 391*11320018SBarry Smith SNESSetTruncationTolerance() 392*11320018SBarry Smith @*/ 393*11320018SBarry Smith int SNESSetRelativeTolerance(SNES snes,double rtol) 394*11320018SBarry Smith { 395*11320018SBarry Smith VALIDHEADER(snes,SNES_COOKIE); 396*11320018SBarry Smith snes->rtol = rtol; 397*11320018SBarry Smith return 0; 398*11320018SBarry Smith } 399*11320018SBarry Smith 400*11320018SBarry Smith /*@ 401*11320018SBarry Smith SNESSetAbsoluteTolerance - Sets the absolute convergence tolerance. 402*11320018SBarry Smith 403*11320018SBarry Smith Input Parameters: 404*11320018SBarry Smith . snes - the SNES context 405*11320018SBarry Smith . atol - tolerance 406*11320018SBarry Smith 407*11320018SBarry Smith Options Database Key: 408*11320018SBarry Smith $ -snes_atol tol 409*11320018SBarry Smith 410*11320018SBarry Smith Notes: 411*11320018SBarry Smith $ The following convergence monitoring routines use atol 412*11320018SBarry Smith 413*11320018SBarry Smith .keywords: SNES, nonlinear, set, absolute, convergence, tolerance 414*11320018SBarry Smith 415*11320018SBarry Smith .seealso: SNESSetRelativeTolerance(), SNESSetSolutionTolerance(), 416*11320018SBarry Smith SNESSetTruncationTolerance() 417*11320018SBarry Smith @*/ 418*11320018SBarry Smith int SNESSetAbsoluteTolerance(SNES snes,double atol) 419*11320018SBarry Smith { 420*11320018SBarry Smith VALIDHEADER(snes,SNES_COOKIE); 421*11320018SBarry Smith snes->atol = atol; 422*11320018SBarry Smith return 0; 423*11320018SBarry Smith } 424*11320018SBarry Smith 425*11320018SBarry Smith /*@ 426*11320018SBarry Smith SNESSetTruncationTolerance - Sets the tolerance that may be used by the 427*11320018SBarry Smith step routines to control the accuracy of the step computation. 428*11320018SBarry Smith 429*11320018SBarry Smith Input Parameters: 430*11320018SBarry Smith . snes - the SNES context 431*11320018SBarry Smith . tol - tolerance 432*11320018SBarry Smith 433*11320018SBarry Smith Options Database Key: 434*11320018SBarry Smith $ -snes_ttol tol 435*11320018SBarry Smith 436*11320018SBarry Smith Notes: 437*11320018SBarry Smith If the step computation involves an application of the inverse 438*11320018SBarry Smith Jacobian (or Hessian), this parameter may be used to control the 439*11320018SBarry Smith accuracy of that application. In particular, this tolerance is used 440*11320018SBarry Smith by SNESKSPDefaultConverged() and SNESKSPQuadraticConverged() to determine 441*11320018SBarry Smith the minimum convergence tolerance for the iterative linear solvers. 442*11320018SBarry Smith 443*11320018SBarry Smith .keywords: SNES, nonlinear, set, truncation, tolerance 444*11320018SBarry Smith 445*11320018SBarry Smith .seealso: SNESSetRelativeTolerance(), SNESSetSolutionTolerance(), 446*11320018SBarry Smith SNESSetAbsoluteTolerance() 447*11320018SBarry Smith @*/ 448*11320018SBarry Smith int SNESSetTruncationTolerance(SNES snes,double tol) 449*11320018SBarry Smith { 450*11320018SBarry Smith VALIDHEADER(snes,SNES_COOKIE); 451*11320018SBarry Smith snes->trunctol = tol; 452*11320018SBarry Smith return 0; 453*11320018SBarry Smith } 454*11320018SBarry Smith 455*11320018SBarry Smith /*@ 456*11320018SBarry Smith SNESSetSolutionTolerance - Sets the convergence tolerance in terms of 457*11320018SBarry Smith the norm of the change in the solution between steps. 458*11320018SBarry Smith 459*11320018SBarry Smith Input Parameters: 460*11320018SBarry Smith . snes - the SNES context 461*11320018SBarry Smith . tol - tolerance 462*11320018SBarry Smith 463*11320018SBarry Smith Options Database Key: 464*11320018SBarry Smith $ -snes_stol tol 465*11320018SBarry Smith 466*11320018SBarry Smith .keywords: SNES, nonlinear, set, solution, tolerance 467*11320018SBarry Smith 468*11320018SBarry Smith .seealso: SNESSetTruncationTolerance(), SNESSetRelativeTolerance(), 469*11320018SBarry Smith SNESSetAbsoluteTolerance() 470*11320018SBarry Smith @*/ 471*11320018SBarry Smith int SNESSetSolutionTolerance( SNES snes, double tol ) 472*11320018SBarry Smith { 473*11320018SBarry Smith VALIDHEADER(snes,SNES_COOKIE); 474*11320018SBarry Smith snes->xtol = tol; 475*11320018SBarry Smith return 0; 476*11320018SBarry Smith } 477*11320018SBarry Smith 478*11320018SBarry Smith /* ---------- Routines to set various aspects of nonlinear solver --------- */ 479*11320018SBarry Smith 480*11320018SBarry Smith /*@ 481*11320018SBarry Smith SNESSetSolution - Sets the initial guess routine and solution vector 482*11320018SBarry Smith for use by the SNES routines. 483*11320018SBarry Smith 484*11320018SBarry Smith Input Parameters: 485*11320018SBarry Smith . snes - the SNES context 486*11320018SBarry Smith . x - the solution vector 487*11320018SBarry Smith . func - optional routine to compute an initial guess (may be null) 488*11320018SBarry Smith . ctx - optional user-defined context for private data for the 489*11320018SBarry Smith initial guess routine (may be null) 490*11320018SBarry Smith 491*11320018SBarry Smith Calling sequence of func: 492*11320018SBarry Smith int guess(Vec x, void *ctx) 493*11320018SBarry Smith 494*11320018SBarry Smith . x - input vector 495*11320018SBarry Smith . ctx - optional user-defined initial guess context 496*11320018SBarry Smith 497*11320018SBarry Smith Note: 498*11320018SBarry Smith If no initial guess routine is indicated, an initial guess of zero 499*11320018SBarry Smith will be used. 500*11320018SBarry Smith 501*11320018SBarry Smith .keywords: SNES, nonlinear, set, solution, initial guess 502*11320018SBarry Smith 503*11320018SBarry Smith .seealso: SNESGetSolution(), SNESSetJacobian(), SNESSetFunction() 504*11320018SBarry Smith @*/ 505*11320018SBarry Smith int SNESSetSolution(SNES snes,Vec x,int (*func)(Vec,void*),void *ctx) 506*11320018SBarry Smith { 507*11320018SBarry Smith VALIDHEADER(snes,SNES_COOKIE); 508*11320018SBarry Smith snes->vec_sol = x; 509*11320018SBarry Smith snes->ComputeInitialGuess = func; 510*11320018SBarry Smith snes->gusP = ctx; 511*11320018SBarry Smith return 0; 512*11320018SBarry Smith } 513*11320018SBarry Smith 514*11320018SBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 515*11320018SBarry Smith 516*11320018SBarry Smith /*@C 517*11320018SBarry Smith SNESSetMonitor - Sets the function that is to be used at every 518*11320018SBarry Smith iteration of the nonlinear solver to display the iteration's 519*11320018SBarry Smith progress. 520*11320018SBarry Smith 521*11320018SBarry Smith Input Parameters: 522*11320018SBarry Smith . snes - the SNES context 523*11320018SBarry Smith . func - monitoring routine 524*11320018SBarry Smith . mctx - optional user-defined context for private data for the 525*11320018SBarry Smith monitor routine (may be null) 526*11320018SBarry Smith 527*11320018SBarry Smith Calling sequence of func: 528*11320018SBarry Smith int func((SNES snes,int its, Vec x,Vec f,double fnorm,void *mctx) 529*11320018SBarry Smith 530*11320018SBarry Smith . snes - the SNES context 531*11320018SBarry Smith . its - iteration number 532*11320018SBarry Smith . x - current iterate 533*11320018SBarry Smith . f - current residual (+/-). f is either the residual or its negative, 534*11320018SBarry Smith depending on the user's preference, as set with SNESSetFunction() 535*11320018SBarry Smith . fnorm - 2-norm residual value (may be estimated) 536*11320018SBarry Smith . mctx - optional monitoring context 537*11320018SBarry Smith 538*11320018SBarry Smith .keywords: SNES, nonlinear, set, monitor 539*11320018SBarry Smith 540*11320018SBarry Smith .seealso: SNESDefaultMonitor() 541*11320018SBarry Smith @*/ 542*11320018SBarry Smith int SNESSetMonitor( SNES snes, int (*func)(SNES,int,double,void*), 543*11320018SBarry Smith void *mctx ) 544*11320018SBarry Smith { 545*11320018SBarry Smith snes->Monitor = func; 546*11320018SBarry Smith snes->monP = (void*)mctx; 547*11320018SBarry Smith return 0; 548*11320018SBarry Smith } 549*11320018SBarry Smith 550*11320018SBarry Smith /*@C 551*11320018SBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 552*11320018SBarry Smith to test for convergence of the nonlinear iterative solution. 553*11320018SBarry Smith 554*11320018SBarry Smith Input Parameters: 555*11320018SBarry Smith . snes - the SNES context 556*11320018SBarry Smith . func - routine to test for convergence 557*11320018SBarry Smith . cctx - optional context for private data for the convergence routine 558*11320018SBarry Smith (may be null) 559*11320018SBarry Smith 560*11320018SBarry Smith Calling sequence of func: 561*11320018SBarry Smith int func (SNES snes,double xnorm,double pnorm,double fnorm, 562*11320018SBarry Smith void *cctx) 563*11320018SBarry Smith 564*11320018SBarry Smith . snes - the SNES context 565*11320018SBarry Smith . xnorm - 2-norm of current iterate 566*11320018SBarry Smith . pnorm - 2-norm of current step 567*11320018SBarry Smith . fnorm - 2-norm of residual 568*11320018SBarry Smith . cctx - optional convergence context 569*11320018SBarry Smith 570*11320018SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 571*11320018SBarry Smith 572*11320018SBarry Smith .seealso: SNESDefaultConverged() 573*11320018SBarry Smith @*/ 574*11320018SBarry Smith int SNESSetConvergenceTest(SNES nlP, 575*11320018SBarry Smith int (*func)(SNES,double,double,double,void*),void *cctx) 576*11320018SBarry Smith { 577*11320018SBarry Smith (nlP)->Converged = func; 578*11320018SBarry Smith (nlP)->cnvP = cctx; 579*11320018SBarry Smith return 0; 580*11320018SBarry Smith } 581*11320018SBarry Smith 582*11320018SBarry Smith /*@ 583*11320018SBarry Smith SNESScaleStep - Scales a step so that its length is less than the 584*11320018SBarry Smith positive parameter delta. 585*11320018SBarry Smith 586*11320018SBarry Smith Input Parameters: 587*11320018SBarry Smith . snes - the SNES context 588*11320018SBarry Smith . y - approximate solution of linear system 589*11320018SBarry Smith . fnorm - 2-norm of current residual 590*11320018SBarry Smith . delta - trust region size 591*11320018SBarry Smith 592*11320018SBarry Smith Output Parameters: 593*11320018SBarry Smith . gpnorm - predicted residual norm at the new point, assuming local 594*11320018SBarry Smith linearization. The value is zero if the step lies within the trust 595*11320018SBarry Smith region, and exceeds zero otherwise. 596*11320018SBarry Smith . ynorm - 2-norm of the step 597*11320018SBarry Smith 598*11320018SBarry Smith Note: 599*11320018SBarry Smith For non-trust region methods such as SNES_NLS, the parameter delta 600*11320018SBarry Smith is set to be the maximum allowable step size. 601*11320018SBarry Smith 602*11320018SBarry Smith .keywords: SNES, nonlinear, scale, step 603*11320018SBarry Smith @*/ 604*11320018SBarry Smith int SNESScaleStep(SNES snes,Vec y,double *fnorm,double *delta, 605*11320018SBarry Smith double *gpnorm,double *ynorm) 606*11320018SBarry Smith { 607*11320018SBarry Smith double norm; 608*11320018SBarry Smith Scalar cnorm; 609*11320018SBarry Smith VecNorm(y, &norm ); 610*11320018SBarry Smith if (norm > *delta) { 611*11320018SBarry Smith norm = *delta/norm; 612*11320018SBarry Smith *gpnorm = (1.0 - norm)*(*fnorm); 613*11320018SBarry Smith cnorm = norm; 614*11320018SBarry Smith VecScale( &cnorm, y ); 615*11320018SBarry Smith *ynorm = *delta; 616*11320018SBarry Smith } else { 617*11320018SBarry Smith *gpnorm = 0.0; 618*11320018SBarry Smith *ynorm = norm; 619*11320018SBarry Smith } 620*11320018SBarry Smith return 0; 621*11320018SBarry Smith } 622*11320018SBarry Smith 623*11320018SBarry Smith /*@ 624*11320018SBarry Smith SNESSolve - Solves a nonlinear system. Call SNESSolve after calling 625*11320018SBarry Smith SNESCreate(), optional routines of the form SNESSetXXX(), and SNESSetUp(). 626*11320018SBarry Smith 627*11320018SBarry Smith Input Parameter: 628*11320018SBarry Smith . snes - the SNES context 629*11320018SBarry Smith 630*11320018SBarry Smith Output Parameter: 631*11320018SBarry Smith its - number of iterations until termination 632*11320018SBarry Smith 633*11320018SBarry Smith .keywords: SNES, nonlinear, solve 634*11320018SBarry Smith 635*11320018SBarry Smith .seealso: SNESCreate(), SNESSetUp(), SNESDestroy() 636*11320018SBarry Smith @*/ 637*11320018SBarry Smith int SNESSolve(SNES snes,int *its) 638*11320018SBarry Smith { 639*11320018SBarry Smith int ierr; 640*11320018SBarry Smith PLogEventBegin(SNES_Solve,snes,0,0,0); 641*11320018SBarry Smith ierr = (*(snes)->Solver)( snes,its ); CHKERR(ierr); 642*11320018SBarry Smith PLogEventEnd(SNES_Solve,snes,0,0,0); 643*11320018SBarry Smith return 0; 644*11320018SBarry Smith } 645*11320018SBarry Smith 646*11320018SBarry Smith /* --------- Internal routines for SNES Package --------- */ 647*11320018SBarry Smith 648*11320018SBarry Smith /* 649*11320018SBarry Smith SNESComputeInitialGuess - Manages computation of initial approximation. 650*11320018SBarry Smith */ 651*11320018SBarry Smith int SNESComputeInitialGuess( SNES nlP,Vec x ) 652*11320018SBarry Smith { 653*11320018SBarry Smith int ierr; 654*11320018SBarry Smith Scalar zero = 0.0; 655*11320018SBarry Smith if (nlP->ComputeInitialGuess) { 656*11320018SBarry Smith ierr = (*nlP->ComputeInitialGuess)( x, nlP->gusP); CHKERR(ierr); 657*11320018SBarry Smith } 658*11320018SBarry Smith else VecSet(&zero, x ); 659*11320018SBarry Smith return 0; 660*11320018SBarry Smith } 661*11320018SBarry Smith 662*11320018SBarry Smith /* ------------------------------------------------------------------ */ 663*11320018SBarry Smith 664*11320018SBarry Smith 665*11320018SBarry Smith #include "sys/nreg.h" 666*11320018SBarry Smith NRList *__NLList; 667*11320018SBarry Smith 668*11320018SBarry Smith /*@ 669*11320018SBarry Smith SNESSetMethod - Sets the method for the nonlinear solver. 670*11320018SBarry Smith 671*11320018SBarry Smith Input Parameters: 672*11320018SBarry Smith . snes - the SNES context 673*11320018SBarry Smith . method - choose from 674*11320018SBarry Smith 675*11320018SBarry Smith Possible methods: 676*11320018SBarry Smith $ SNES_NLS - Newton's method with line search 677*11320018SBarry Smith $ SNES_NTR - Newton's method with trust region 678*11320018SBarry Smith @*/ 679*11320018SBarry Smith int SNESSetMethod( SNES snes, SNESMETHOD method) 680*11320018SBarry Smith { 681*11320018SBarry Smith int (*r)(SNES); 682*11320018SBarry Smith VALIDHEADER(snes,SNES_COOKIE); 683*11320018SBarry Smith /* Get the function pointers for the iterative method requested */ 684*11320018SBarry Smith if (!__NLList) {SNESRegisterAll();} 685*11320018SBarry Smith if (!__NLList) {SETERR(1,"Could not acquire list of SNES methods"); } 686*11320018SBarry Smith r = (int (*)(SNES))NRFindRoutine( __NLList, (int)method, (char *)0 ); 687*11320018SBarry Smith if (!r) {SETERR(1,"Unknown SNES method");} 688*11320018SBarry Smith return (*r)(snes); 689*11320018SBarry Smith } 690*11320018SBarry Smith 691*11320018SBarry Smith /* --------------------------------------------------------------------- */ 692*11320018SBarry Smith /*@ 693*11320018SBarry Smith SNESRegister - Adds the method to the nonlinear solver package, given 694*11320018SBarry Smith a function pointer and a nonlinear solver name of the type SNESMETHOD. 695*11320018SBarry Smith 696*11320018SBarry Smith Input Parameters: 697*11320018SBarry Smith . name - for instance SNES_NLS, SNES_NTR, ... 698*11320018SBarry Smith . sname - corresponding string for name 699*11320018SBarry Smith . create - routine to create method context 700*11320018SBarry Smith 701*11320018SBarry Smith .keywords: SNES, nonlinear, register 702*11320018SBarry Smith 703*11320018SBarry Smith .seealso: SNESRegisterAll(), SNESRegisterDestroy() 704*11320018SBarry Smith @*/ 705*11320018SBarry Smith int SNESRegister(int name, char *sname, int (*create)(SNES)) 706*11320018SBarry Smith { 707*11320018SBarry Smith int ierr; 708*11320018SBarry Smith if (!__NLList) {ierr = NRCreate(&__NLList); CHKERR(ierr);} 709*11320018SBarry Smith NRRegister( __NLList, name, sname, (int (*)(void*))create ); 710*11320018SBarry Smith return 0; 711*11320018SBarry Smith } 712*11320018SBarry Smith /* --------------------------------------------------------------------- */ 713*11320018SBarry Smith /*@ 714*11320018SBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 715*11320018SBarry Smith registered by SNESRegister(). 716*11320018SBarry Smith 717*11320018SBarry Smith .keywords: SNES, nonlinear, register, destroy 718*11320018SBarry Smith 719*11320018SBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 720*11320018SBarry Smith @*/ 721*11320018SBarry Smith int SNESRegisterDestroy() 722*11320018SBarry Smith { 723*11320018SBarry Smith if (__NLList) { 724*11320018SBarry Smith NRDestroy( __NLList ); 725*11320018SBarry Smith __NLList = 0; 726*11320018SBarry Smith } 727*11320018SBarry Smith return 0; 728*11320018SBarry Smith } 729*11320018SBarry Smith #include "options.h" 730*11320018SBarry Smith /*@C 731*11320018SBarry Smith SNESGetMethodFromOptions - Sets the selected method from the options 732*11320018SBarry Smith database. 733*11320018SBarry Smith 734*11320018SBarry Smith Input parameters: 735*11320018SBarry Smith . ctx - the SNES context 736*11320018SBarry Smith 737*11320018SBarry Smith Output Parameter: 738*11320018SBarry Smith . method - solver method 739*11320018SBarry Smith 740*11320018SBarry Smith Returns: 741*11320018SBarry Smith Returns 1 if the method is found; 0 otherwise. 742*11320018SBarry Smith 743*11320018SBarry Smith Options Database Key: 744*11320018SBarry Smith $ -snes_method method 745*11320018SBarry Smith 746*11320018SBarry Smith .keywords: SNES, nonlinear, options, database, get, method 747*11320018SBarry Smith 748*11320018SBarry Smith .seealso: SNESGetMethodName() 749*11320018SBarry Smith @*/ 750*11320018SBarry Smith int SNESGetMethodFromOptions(SNES ctx,SNESMETHOD *method) 751*11320018SBarry Smith { 752*11320018SBarry Smith char sbuf[50]; 753*11320018SBarry Smith if (OptionsGetString(0,ctx->prefix,"-snes_method", sbuf, 50 )) { 754*11320018SBarry Smith if (!__NLList) SNESRegisterAll(); 755*11320018SBarry Smith *method = (SNESMETHOD)NRFindID( __NLList, sbuf ); 756*11320018SBarry Smith return 1; 757*11320018SBarry Smith } 758*11320018SBarry Smith return 0; 759*11320018SBarry Smith } 760*11320018SBarry Smith 761*11320018SBarry Smith /*@C 762*11320018SBarry Smith SNESGetMethodName - Gets the SNES method name (as a string) from 763*11320018SBarry Smith the method type. 764*11320018SBarry Smith 765*11320018SBarry Smith Input Parameter: 766*11320018SBarry Smith . method - SNES method 767*11320018SBarry Smith 768*11320018SBarry Smith Output Parameter: 769*11320018SBarry Smith . name - name of SNES method 770*11320018SBarry Smith 771*11320018SBarry Smith .keywords: SNES, nonlinear, get, method, name 772*11320018SBarry Smith 773*11320018SBarry Smith .seealso: SNESGetMethodFromOptions() 774*11320018SBarry Smith @*/ 775*11320018SBarry Smith int SNESGetMethodName(SNESMETHOD method,char **name) 776*11320018SBarry Smith { 777*11320018SBarry Smith if (!__NLList) SNESRegisterAll(); 778*11320018SBarry Smith *name = NRFindName( __NLList, (int) method ); 779*11320018SBarry Smith return 0; 780*11320018SBarry Smith } 781*11320018SBarry Smith 782*11320018SBarry Smith #include <stdio.h> 783*11320018SBarry Smith /*@C 784*11320018SBarry Smith SNESPrintMethods - Prints the SNES methods available from the options 785*11320018SBarry Smith database. 786*11320018SBarry Smith 787*11320018SBarry Smith Input Parameters: 788*11320018SBarry Smith . prefix - prefix (usually "-") 789*11320018SBarry Smith . name - the options database name (by default "snesmethod") 790*11320018SBarry Smith 791*11320018SBarry Smith .keywords: SNES, nonlinear, print, methods, options, database 792*11320018SBarry Smith 793*11320018SBarry Smith .seealso: SNESPrintHelp() 794*11320018SBarry Smith @*/ 795*11320018SBarry Smith int SNESPrintMethods(char* prefix,char *name) 796*11320018SBarry Smith { 797*11320018SBarry Smith FuncList *entry; 798*11320018SBarry Smith if (!__NLList) {SNESRegisterAll();} 799*11320018SBarry Smith entry = __NLList->head; 800*11320018SBarry Smith fprintf(stderr," %s%s (one of)",prefix,name); 801*11320018SBarry Smith while (entry) { 802*11320018SBarry Smith fprintf(stderr," %s",entry->name); 803*11320018SBarry Smith entry = entry->next; 804*11320018SBarry Smith } 805*11320018SBarry Smith fprintf(stderr,"\n"); 806*11320018SBarry Smith return 0; 807*11320018SBarry Smith } 808*11320018SBarry Smith 809*11320018SBarry Smith /*@ 810*11320018SBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 811*11320018SBarry Smith stored. 812*11320018SBarry Smith 813*11320018SBarry Smith Input Parameter: 814*11320018SBarry Smith . snes - the SNES context 815*11320018SBarry Smith 816*11320018SBarry Smith Output Parameter: 817*11320018SBarry Smith . x - the solution 818*11320018SBarry Smith 819*11320018SBarry Smith .keywords: SNES, nonlinear, get, solution 820*11320018SBarry Smith 821*11320018SBarry Smith .seealso: SNESSetSolution(), SNESGetFunction() 822*11320018SBarry Smith @*/ 823*11320018SBarry Smith int SNESGetSolution(SNES snes,Vec *x) 824*11320018SBarry Smith { 825*11320018SBarry Smith VALIDHEADER(snes,SNES_COOKIE); 826*11320018SBarry Smith *x = snes->vec_sol; 827*11320018SBarry Smith return 0; 828*11320018SBarry Smith } 829*11320018SBarry Smith 830*11320018SBarry Smith /*@ 831*11320018SBarry Smith SNESGetFunction - Returns the vector where the residual is 832*11320018SBarry Smith stored. Actually usually returns the vector where the negative of 833*11320018SBarry Smith the residual is stored. 834*11320018SBarry Smith 835*11320018SBarry Smith Input Parameter: 836*11320018SBarry Smith . snes - the SNES context 837*11320018SBarry Smith 838*11320018SBarry Smith Output Parameter: 839*11320018SBarry Smith . r - the residual (or its negative) 840*11320018SBarry Smith 841*11320018SBarry Smith .keywords: SNES, nonlinear, get residual 842*11320018SBarry Smith 843*11320018SBarry Smith .seealso: SNESSetFunction(), SNESGetSolution() 844*11320018SBarry Smith @*/ 845*11320018SBarry Smith int SNESGetFunction(SNES snes,Vec *r) 846*11320018SBarry Smith { 847*11320018SBarry Smith VALIDHEADER(snes,SNES_COOKIE); 848*11320018SBarry Smith *r = snes->vec_res; 849*11320018SBarry Smith return 0; 850*11320018SBarry Smith } 851*11320018SBarry Smith 852*11320018SBarry Smith 853*11320018SBarry Smith 854*11320018SBarry Smith 855*11320018SBarry Smith 856*11320018SBarry Smith 857