Actual source code: snes.c

  1: #define PETSCSNES_DLL

 3:  #include private/snesimpl.h

  5: PetscTruth SNESRegisterAllCalled = PETSC_FALSE;
  6: PetscFList SNESList              = PETSC_NULL;

  8: /* Logging support */
  9: PetscCookie  SNES_COOKIE;
 10: PetscLogEvent  SNES_Solve, SNES_LineSearch, SNES_FunctionEval, SNES_JacobianEval;

 14: /*@
 15:    SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not
 16:      in the functions domain. For example, negative pressure.

 18:    Collective on SNES

 20:    Input Parameters:
 21: .  SNES - the SNES context

 23:    Level: advanced

 25: .keywords: SNES, view

 27: .seealso: SNESCreate(), SNESSetFunction()
 28: @*/
 29: PetscErrorCode  SNESSetFunctionDomainError(SNES snes)
 30: {
 33:   snes->domainerror = PETSC_TRUE;
 34:   return(0);
 35: }

 39: /*@C
 40:    SNESView - Prints the SNES data structure.

 42:    Collective on SNES

 44:    Input Parameters:
 45: +  SNES - the SNES context
 46: -  viewer - visualization context

 48:    Options Database Key:
 49: .  -snes_view - Calls SNESView() at end of SNESSolve()

 51:    Notes:
 52:    The available visualization contexts include
 53: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
 54: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
 55:          output where only the first processor opens
 56:          the file.  All other processors send their 
 57:          data to the first processor to print. 

 59:    The user can open an alternative visualization context with
 60:    PetscViewerASCIIOpen() - output to a specified file.

 62:    Level: beginner

 64: .keywords: SNES, view

 66: .seealso: PetscViewerASCIIOpen()
 67: @*/
 68: PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
 69: {
 70:   SNESKSPEW           *kctx;
 71:   PetscErrorCode      ierr;
 72:   KSP                 ksp;
 73:   const SNESType      type;
 74:   PetscTruth          iascii,isstring;

 78:   if (!viewer) {
 79:     PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);
 80:   }

 84:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
 85:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);
 86:   if (iascii) {
 87:     if (((PetscObject)snes)->prefix) {
 88:       PetscViewerASCIIPrintf(viewer,"SNES Object:(%s)\n",((PetscObject)snes)->prefix);
 89:     } else {
 90:       PetscViewerASCIIPrintf(viewer,"SNES Object:\n");
 91:     }
 92:     SNESGetType(snes,&type);
 93:     if (type) {
 94:       PetscViewerASCIIPrintf(viewer,"  type: %s\n",type);
 95:     } else {
 96:       PetscViewerASCIIPrintf(viewer,"  type: not set yet\n");
 97:     }
 98:     if (snes->ops->view) {
 99:       PetscViewerASCIIPushTab(viewer);
100:       (*snes->ops->view)(snes,viewer);
101:       PetscViewerASCIIPopTab(viewer);
102:     }
103:     PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);
104:     PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%G, absolute=%G, solution=%G\n",
105:                  snes->rtol,snes->abstol,snes->xtol);
106:     PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);
107:     PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);
108:     if (snes->ksp_ewconv) {
109:       kctx = (SNESKSPEW *)snes->kspconvctx;
110:       if (kctx) {
111:         PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);
112:         PetscViewerASCIIPrintf(viewer,"    rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);
113:         PetscViewerASCIIPrintf(viewer,"    gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);
114:       }
115:     }
116:   } else if (isstring) {
117:     SNESGetType(snes,&type);
118:     PetscViewerStringSPrintf(viewer," %-3.3s",type);
119:   }
120:   SNESGetKSP(snes,&ksp);
121:   PetscViewerASCIIPushTab(viewer);
122:   KSPView(ksp,viewer);
123:   PetscViewerASCIIPopTab(viewer);
124:   return(0);
125: }

127: /*
128:   We retain a list of functions that also take SNES command 
129:   line options. These are called at the end SNESSetFromOptions()
130: */
131: #define MAXSETFROMOPTIONS 5
132: static PetscInt numberofsetfromoptions;
133: static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);

137: /*@C
138:   SNESAddOptionsChecker - Adds an additional function to check for SNES options.

140:   Not Collective

142:   Input Parameter:
143: . snescheck - function that checks for options

145:   Level: developer

147: .seealso: SNESSetFromOptions()
148: @*/
149: PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
150: {
152:   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
153:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
154:   }
155:   othersetfromoptions[numberofsetfromoptions++] = snescheck;
156:   return(0);
157: }

161: /*@
162:    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.

164:    Collective on SNES

166:    Input Parameter:
167: .  snes - the SNES context

169:    Options Database Keys:
170: +  -snes_type <type> - ls, tr, umls, umtr, test
171: .  -snes_stol - convergence tolerance in terms of the norm
172:                 of the change in the solution between steps
173: .  -snes_atol <abstol> - absolute tolerance of residual norm
174: .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
175: .  -snes_max_it <max_it> - maximum number of iterations
176: .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
177: .  -snes_max_fail <max_fail> - maximum number of failures
178: .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
179: .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
180: .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
181: .  -snes_trtol <trtol> - trust region tolerance
182: .  -snes_no_convergence_test - skip convergence test in nonlinear 
183:                                solver; hence iterations will continue until max_it
184:                                or some other criterion is reached. Saves expense
185:                                of convergence test
186: .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
187:                                        filename given prints to stdout
188: .  -snes_monitor_solution - plots solution at each iteration
189: .  -snes_monitor_residual - plots residual (not its norm) at each iteration
190: .  -snes_monitor_solution_update - plots update to solution at each iteration 
191: .  -snes_monitor_draw - plots residual norm at each iteration 
192: .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
193: .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
194: -  -snes_converged_reason - print the reason for convergence/divergence after each solve

196:     Options Database for Eisenstat-Walker method:
197: +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
198: .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
199: .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
200: .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
201: .  -snes_ksp_ew_gamma <gamma> - Sets gamma
202: .  -snes_ksp_ew_alpha <alpha> - Sets alpha
203: .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 
204: -  -snes_ksp_ew_threshold <threshold> - Sets threshold

206:    Notes:
207:    To see all options, run your program with the -help option or consult
208:    the users manual.

210:    Level: beginner

212: .keywords: SNES, nonlinear, set, options, database

214: .seealso: SNESSetOptionsPrefix()
215: @*/
216: PetscErrorCode  SNESSetFromOptions(SNES snes)
217: {
218:   PetscTruth              flg;
219:   PetscInt                i,indx,lag;
220:   const char              *deft = SNESLS;
221:   const char              *convtests[] = {"default","skip"};
222:   SNESKSPEW               *kctx = NULL;
223:   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
224:   PetscViewerASCIIMonitor monviewer;
225:   PetscErrorCode          ierr;


230:   if (!SNESRegisterAllCalled) {SNESRegisterAll(PETSC_NULL);}
231:   PetscOptionsBegin(((PetscObject)snes)->comm,((PetscObject)snes)->prefix,"Nonlinear solver (SNES) options","SNES");
232:     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
233:     PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);
234:     if (flg) {
235:       SNESSetType(snes,type);
236:     } else if (!((PetscObject)snes)->type_name) {
237:       SNESSetType(snes,deft);
238:     }
239:     PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);

241:     PetscOptionsReal("-snes_stol","Stop if step length less then","SNESSetTolerances",snes->xtol,&snes->xtol,0);
242:     PetscOptionsReal("-snes_atol","Stop if function norm less then","SNESSetTolerances",snes->abstol,&snes->abstol,0);

244:     PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less then","SNESSetTolerances",snes->rtol,&snes->rtol,0);
245:     PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);
246:     PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);
247:     PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);
248:     PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);

250:     PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);
251:     if (flg) {
252:       SNESSetLagPreconditioner(snes,lag);
253:     }
254:     PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);
255:     if (flg) {
256:       SNESSetLagJacobian(snes,lag);
257:     }

259:     PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);
260:     if (flg) {
261:       switch (indx) {
262:       case 0: SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL); break;
263:       case 1: SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);    break;
264:       }
265:     }

267:     PetscOptionsName("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",&flg);
268:     if (flg) {
269:       snes->printreason = PETSC_TRUE;
270:     }

272:     kctx = (SNESKSPEW *)snes->kspconvctx;

274:     PetscOptionsTruth("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);

276:     PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);
277:     PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);
278:     PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);
279:     PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);
280:     PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);
281:     PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);
282:     PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);

284:     PetscOptionsName("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",&flg);
285:     if (flg) {SNESMonitorCancel(snes);}

287:     PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
288:     if (flg) {
289:       PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,((PetscObject)snes)->tablevel,&monviewer);
290:       SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);
291:     }

293:     PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
294:     if (flg) {
295:       SNESMonitorSet(snes,SNESMonitorRange,0,0);
296:     }

298:     PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
299:     if (flg) {
300:       PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,((PetscObject)snes)->tablevel,&monviewer);
301:       SNESMonitorSetRatio(snes,monviewer);
302:     }

304:     PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
305:     if (flg) {
306:       PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,((PetscObject)snes)->tablevel,&monviewer);
307:       SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);
308:     }

310:     PetscOptionsName("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",&flg);
311:     if (flg) {SNESMonitorSet(snes,SNESMonitorSolution,0,0);}
312:     PetscOptionsName("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",&flg);
313:     if (flg) {SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);}
314:     PetscOptionsName("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",&flg);
315:     if (flg) {SNESMonitorSet(snes,SNESMonitorResidual,0,0);}
316:     PetscOptionsName("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",&flg);
317:     if (flg) {SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);}
318:     PetscOptionsName("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",&flg);
319:     if (flg) {SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);}

321:     PetscOptionsName("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",&flg);
322:     if (flg) {
323:       SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);
324:       PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");
325:     }

327:     for(i = 0; i < numberofsetfromoptions; i++) {
328:       (*othersetfromoptions[i])(snes);
329:     }

331:     if (snes->ops->setfromoptions) {
332:       (*snes->ops->setfromoptions)(snes);
333:     }
334:   PetscOptionsEnd();

336: 
337:   if (!snes->ksp) {SNESGetKSP(snes,&snes->ksp);}
338:   KSPSetFromOptions(snes->ksp);

340:   return(0);
341: }


346: /*@
347:    SNESSetApplicationContext - Sets the optional user-defined context for 
348:    the nonlinear solvers.  

350:    Collective on SNES

352:    Input Parameters:
353: +  snes - the SNES context
354: -  usrP - optional user context

356:    Level: intermediate

358: .keywords: SNES, nonlinear, set, application, context

360: .seealso: SNESGetApplicationContext()
361: @*/
362: PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
363: {
366:   snes->user                = usrP;
367:   return(0);
368: }

372: /*@C
373:    SNESGetApplicationContext - Gets the user-defined context for the 
374:    nonlinear solvers.  

376:    Not Collective

378:    Input Parameter:
379: .  snes - SNES context

381:    Output Parameter:
382: .  usrP - user context

384:    Level: intermediate

386: .keywords: SNES, nonlinear, get, application, context

388: .seealso: SNESSetApplicationContext()
389: @*/
390: PetscErrorCode  SNESGetApplicationContext(SNES snes,void **usrP)
391: {
394:   *usrP = snes->user;
395:   return(0);
396: }

400: /*@
401:    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
402:    at this time.

404:    Not Collective

406:    Input Parameter:
407: .  snes - SNES context

409:    Output Parameter:
410: .  iter - iteration number

412:    Notes:
413:    For example, during the computation of iteration 2 this would return 1.

415:    This is useful for using lagged Jacobians (where one does not recompute the 
416:    Jacobian at each SNES iteration). For example, the code
417: .vb
418:       SNESGetIterationNumber(snes,&it);
419:       if (!(it % 2)) {
420:         [compute Jacobian here]
421:       }
422: .ve
423:    can be used in your ComputeJacobian() function to cause the Jacobian to be
424:    recomputed every second SNES iteration.

426:    Level: intermediate

428: .keywords: SNES, nonlinear, get, iteration, number, 

430: .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
431: @*/
432: PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
433: {
437:   *iter = snes->iter;
438:   return(0);
439: }

443: /*@
444:    SNESGetFunctionNorm - Gets the norm of the current function that was set
445:    with SNESSSetFunction().

447:    Collective on SNES

449:    Input Parameter:
450: .  snes - SNES context

452:    Output Parameter:
453: .  fnorm - 2-norm of function

455:    Level: intermediate

457: .keywords: SNES, nonlinear, get, function, norm

459: .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
460: @*/
461: PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
462: {
466:   *fnorm = snes->norm;
467:   return(0);
468: }

472: /*@
473:    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
474:    attempted by the nonlinear solver.

476:    Not Collective

478:    Input Parameter:
479: .  snes - SNES context

481:    Output Parameter:
482: .  nfails - number of unsuccessful steps attempted

484:    Notes:
485:    This counter is reset to zero for each successive call to SNESSolve().

487:    Level: intermediate

489: .keywords: SNES, nonlinear, get, number, unsuccessful, steps

491: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
492:           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
493: @*/
494: PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
495: {
499:   *nfails = snes->numFailures;
500:   return(0);
501: }

505: /*@
506:    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
507:    attempted by the nonlinear solver before it gives up.

509:    Not Collective

511:    Input Parameters:
512: +  snes     - SNES context
513: -  maxFails - maximum of unsuccessful steps

515:    Level: intermediate

517: .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps

519: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
520:           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
521: @*/
522: PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
523: {
526:   snes->maxFailures = maxFails;
527:   return(0);
528: }

532: /*@
533:    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
534:    attempted by the nonlinear solver before it gives up.

536:    Not Collective

538:    Input Parameter:
539: .  snes     - SNES context

541:    Output Parameter:
542: .  maxFails - maximum of unsuccessful steps

544:    Level: intermediate

546: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps

548: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
549:           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
550:  
551: @*/
552: PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
553: {
557:   *maxFails = snes->maxFailures;
558:   return(0);
559: }

563: /*@
564:    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
565:      done by SNES.

567:    Not Collective

569:    Input Parameter:
570: .  snes     - SNES context

572:    Output Parameter:
573: .  nfuncs - number of evaluations

575:    Level: intermediate

577: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps

579: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
580: @*/
581: PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
582: {
586:   *nfuncs = snes->nfuncs;
587:   return(0);
588: }

592: /*@
593:    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
594:    linear solvers.

596:    Not Collective

598:    Input Parameter:
599: .  snes - SNES context

601:    Output Parameter:
602: .  nfails - number of failed solves

604:    Notes:
605:    This counter is reset to zero for each successive call to SNESSolve().

607:    Level: intermediate

609: .keywords: SNES, nonlinear, get, number, unsuccessful, steps

611: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
612: @*/
613: PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
614: {
618:   *nfails = snes->numLinearSolveFailures;
619:   return(0);
620: }

624: /*@
625:    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
626:    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE

628:    Collective on SNES

630:    Input Parameters:
631: +  snes     - SNES context
632: -  maxFails - maximum allowed linear solve failures

634:    Level: intermediate

636:    Notes: By default this is 0; that is SNES returns on the first failed linear solve

638: .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps

640: .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
641: @*/
642: PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
643: {
646:   snes->maxLinearSolveFailures = maxFails;
647:   return(0);
648: }

652: /*@
653:    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
654:      are allowed before SNES terminates

656:    Not Collective

658:    Input Parameter:
659: .  snes     - SNES context

661:    Output Parameter:
662: .  maxFails - maximum of unsuccessful solves allowed

664:    Level: intermediate

666:    Notes: By default this is 1; that is SNES returns on the first failed linear solve

668: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps

670: .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
671: @*/
672: PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
673: {
677:   *maxFails = snes->maxLinearSolveFailures;
678:   return(0);
679: }

683: /*@
684:    SNESGetLinearSolveIterations - Gets the total number of linear iterations
685:    used by the nonlinear solver.

687:    Not Collective

689:    Input Parameter:
690: .  snes - SNES context

692:    Output Parameter:
693: .  lits - number of linear iterations

695:    Notes:
696:    This counter is reset to zero for each successive call to SNESSolve().

698:    Level: intermediate

700: .keywords: SNES, nonlinear, get, number, linear, iterations

702: .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm()S, NESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
703: @*/
704: PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
705: {
709:   *lits = snes->linear_its;
710:   return(0);
711: }

715: /*@
716:    SNESGetKSP - Returns the KSP context for a SNES solver.

718:    Not Collective, but if SNES object is parallel, then KSP object is parallel

720:    Input Parameter:
721: .  snes - the SNES context

723:    Output Parameter:
724: .  ksp - the KSP context

726:    Notes:
727:    The user can then directly manipulate the KSP context to set various
728:    options, etc.  Likewise, the user can then extract and manipulate the 
729:    PC contexts as well.

731:    Level: beginner

733: .keywords: SNES, nonlinear, get, KSP, context

735: .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
736: @*/
737: PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
738: {


745:   if (!snes->ksp) {
746:     KSPCreate(((PetscObject)snes)->comm,&snes->ksp);
747:     PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);
748:     PetscLogObjectParent(snes,snes->ksp);
749:   }
750:   *ksp = snes->ksp;
751:   return(0);
752: }

756: /*@
757:    SNESSetKSP - Sets a KSP context for the SNES object to use

759:    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm

761:    Input Parameters:
762: +  snes - the SNES context
763: -  ksp - the KSP context

765:    Notes:
766:    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
767:    so this routine is rarely needed.

769:    The KSP object that is already in the SNES object has its reference count
770:    decreased by one.

772:    Level: developer

774: .keywords: SNES, nonlinear, get, KSP, context

776: .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
777: @*/
778: PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
779: {

786:   PetscObjectReference((PetscObject)ksp);
787:   if (snes->ksp) {PetscObjectDereference((PetscObject)snes->ksp);}
788:   snes->ksp = ksp;
789:   return(0);
790: }

792: #if 0
795: static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
796: {
798:   return(0);
799: }
800: #endif

802: /* -----------------------------------------------------------*/
805: /*@
806:    SNESCreate - Creates a nonlinear solver context.

808:    Collective on MPI_Comm

810:    Input Parameters:
811: .  comm - MPI communicator

813:    Output Parameter:
814: .  outsnes - the new SNES context

816:    Options Database Keys:
817: +   -snes_mf - Activates default matrix-free Jacobian-vector products,
818:                and no preconditioning matrix
819: .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
820:                products, and a user-provided preconditioning matrix
821:                as set by SNESSetJacobian()
822: -   -snes_fd - Uses (slow!) finite differences to compute Jacobian

824:    Level: beginner

826: .keywords: SNES, nonlinear, create, context

828: .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()

830: @*/
831: PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
832: {
833:   PetscErrorCode      ierr;
834:   SNES                snes;
835:   SNESKSPEW           *kctx;

839:   *outsnes = PETSC_NULL;
840: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
841:   SNESInitializePackage(PETSC_NULL);
842: #endif

844:   PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_COOKIE,0,"SNES",comm,SNESDestroy,SNESView);

846:   snes->ops->converged    = SNESDefaultConverged;
847:   snes->max_its           = 50;
848:   snes->max_funcs          = 10000;
849:   snes->norm                  = 0.0;
850:   snes->rtol                  = 1.e-8;
851:   snes->ttol              = 0.0;
852:   snes->abstol                  = 1.e-50;
853:   snes->xtol                  = 1.e-8;
854:   snes->deltatol          = 1.e-12;
855:   snes->nfuncs            = 0;
856:   snes->numFailures       = 0;
857:   snes->maxFailures       = 1;
858:   snes->linear_its        = 0;
859:   snes->lagjacobian       = 1;
860:   snes->lagpreconditioner = 1;
861:   snes->numbermonitors    = 0;
862:   snes->data              = 0;
863:   snes->setupcalled       = PETSC_FALSE;
864:   snes->ksp_ewconv        = PETSC_FALSE;
865:   snes->vwork             = 0;
866:   snes->nwork             = 0;
867:   snes->conv_hist_len     = 0;
868:   snes->conv_hist_max     = 0;
869:   snes->conv_hist         = PETSC_NULL;
870:   snes->conv_hist_its     = PETSC_NULL;
871:   snes->conv_hist_reset   = PETSC_TRUE;
872:   snes->reason            = SNES_CONVERGED_ITERATING;

874:   snes->numLinearSolveFailures = 0;
875:   snes->maxLinearSolveFailures = 1;

877:   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
878:   PetscNewLog(snes,SNESKSPEW,&kctx);
879:   snes->kspconvctx  = (void*)kctx;
880:   kctx->version     = 2;
881:   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 
882:                              this was too large for some test cases */
883:   kctx->rtol_last   = 0;
884:   kctx->rtol_max    = .9;
885:   kctx->gamma       = 1.0;
886:   kctx->alpha       = .5*(1.0 + sqrt(5.0));
887:   kctx->alpha2      = kctx->alpha;
888:   kctx->threshold   = .1;
889:   kctx->lresid_last = 0;
890:   kctx->norm_last   = 0;

892:   *outsnes = snes;
893:   PetscPublishAll(snes);
894:   return(0);
895: }

899: /*@C
900:    SNESSetFunction - Sets the function evaluation routine and function 
901:    vector for use by the SNES routines in solving systems of nonlinear
902:    equations.

904:    Collective on SNES

906:    Input Parameters:
907: +  snes - the SNES context
908: .  r - vector to store function value
909: .  func - function evaluation routine
910: -  ctx - [optional] user-defined context for private data for the 
911:          function evaluation routine (may be PETSC_NULL)

913:    Calling sequence of func:
914: $    func (SNES snes,Vec x,Vec f,void *ctx);

916: .  f - function vector
917: -  ctx - optional user-defined function context 

919:    Notes:
920:    The Newton-like methods typically solve linear systems of the form
921: $      f'(x) x = -f(x),
922:    where f'(x) denotes the Jacobian matrix and f(x) is the function.

924:    Level: beginner

926: .keywords: SNES, nonlinear, set, function

928: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
929: @*/
930: PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
931: {
937:   PetscObjectReference((PetscObject)r);
938:   if (snes->vec_func) { VecDestroy(snes->vec_func); }
939:   snes->ops->computefunction = func;
940:   snes->vec_func             = r;
941:   snes->funP                 = ctx;
942:   return(0);
943: }

945: /* --------------------------------------------------------------- */
948: /*@C
949:    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
950:    it assumes a zero right hand side.

952:    Collective on SNES

954:    Input Parameter:
955: .  snes - the SNES context

957:    Output Parameter:
958: .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null

960:    Level: intermediate

962: .keywords: SNES, nonlinear, get, function, right hand side

964: .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
965: @*/
966: PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
967: {
971:   *rhs = snes->vec_rhs;
972:   return(0);
973: }

977: /*@
978:    SNESComputeFunction - Calls the function that has been set with
979:                          SNESSetFunction().  

981:    Collective on SNES

983:    Input Parameters:
984: +  snes - the SNES context
985: -  x - input vector

987:    Output Parameter:
988: .  y - function vector, as set by SNESSetFunction()

990:    Notes:
991:    SNESComputeFunction() is typically used within nonlinear solvers
992:    implementations, so most users would not generally call this routine
993:    themselves.

995:    Level: developer

997: .keywords: SNES, nonlinear, compute, function

999: .seealso: SNESSetFunction(), SNESGetFunction()
1000: @*/
1001: PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
1002: {


1012:   PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);
1013:   if (snes->ops->computefunction) {
1014:     PetscStackPush("SNES user function");
1015:     CHKMEMQ;
1016:     (*snes->ops->computefunction)(snes,x,y,snes->funP);
1017:     CHKMEMQ;
1018:     PetscStackPop;
1019:     if (PetscExceptionValue(ierr)) {
1020:       PetscErrorCode pPetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(pierr);
1021:     }
1022: 
1023:   } else if (snes->vec_rhs) {
1024:     MatMult(snes->jacobian, x, y);
1025:   } else {
1026:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() before SNESComputeFunction(), likely called from SNESSolve().");
1027:   }
1028:   if (snes->vec_rhs) {
1029:     VecAXPY(y,-1.0,snes->vec_rhs);
1030:   }
1031:   snes->nfuncs++;
1032:   PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);
1033:   return(0);
1034: }

1038: /*@
1039:    SNESComputeJacobian - Computes the Jacobian matrix that has been
1040:    set with SNESSetJacobian().

1042:    Collective on SNES and Mat

1044:    Input Parameters:
1045: +  snes - the SNES context
1046: -  x - input vector

1048:    Output Parameters:
1049: +  A - Jacobian matrix
1050: .  B - optional preconditioning matrix
1051: -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)

1053:   Options Database Keys: 
1054: +    -snes_lag_preconditioner <lag>
1055: -    -snes_lag_jacobian <lag>

1057:    Notes: 
1058:    Most users should not need to explicitly call this routine, as it 
1059:    is used internally within the nonlinear solvers. 

1061:    See KSPSetOperators() for important information about setting the
1062:    flag parameter.

1064:    Level: developer

1066: .keywords: SNES, compute, Jacobian, matrix

1068: .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
1069: @*/
1070: PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
1071: {
1073:   PetscTruth     flag;

1080:   if (!snes->ops->computejacobian) return(0);

1082:   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */

1084:   if (snes->lagjacobian == -2) {
1085:     snes->lagjacobian = -1;
1086:     PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");
1087:   } else if (snes->lagjacobian == -1) {
1088:     *flg = SAME_PRECONDITIONER;
1089:     PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");
1090:     PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);
1091:     if (flag) {
1092:       MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);
1093:       MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);
1094:     }
1095:     return(0);
1096:   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
1097:     *flg = SAME_PRECONDITIONER;
1098:     PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);
1099:     PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);
1100:     if (flag) {
1101:       MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);
1102:       MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);
1103:     }
1104:     return(0);
1105:   }

1107:   *flg = DIFFERENT_NONZERO_PATTERN;
1108:   PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);
1109:   PetscStackPush("SNES user Jacobian function");
1110:   CHKMEMQ;
1111:   (*snes->ops->computejacobian)(snes,X,A,B,flg,snes->jacP);
1112:   CHKMEMQ;
1113:   PetscStackPop;
1114:   PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);

1116:   if (snes->lagpreconditioner == -2) {
1117:     PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");
1118:     snes->lagpreconditioner = -1;
1119:   } else if (snes->lagpreconditioner == -1) {
1120:     *flg = SAME_PRECONDITIONER;
1121:     PetscInfo(snes,"Reusing preconditioner because lag is -1\n");
1122:   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
1123:     *flg = SAME_PRECONDITIONER;
1124:     PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);
1125:   }

1127:   /* make sure user returned a correct Jacobian and preconditioner */
1130:   return(0);
1131: }

1135: /*@C
1136:    SNESSetJacobian - Sets the function to compute Jacobian as well as the
1137:    location to store the matrix.

1139:    Collective on SNES and Mat

1141:    Input Parameters:
1142: +  snes - the SNES context
1143: .  A - Jacobian matrix
1144: .  B - preconditioner matrix (usually same as the Jacobian)
1145: .  func - Jacobian evaluation routine
1146: -  ctx - [optional] user-defined context for private data for the 
1147:          Jacobian evaluation routine (may be PETSC_NULL)

1149:    Calling sequence of func:
1150: $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);

1152: +  x - input vector
1153: .  A - Jacobian matrix
1154: .  B - preconditioner matrix, usually the same as A
1155: .  flag - flag indicating information about the preconditioner matrix
1156:    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
1157: -  ctx - [optional] user-defined Jacobian context

1159:    Notes: 
1160:    See KSPSetOperators() for important information about setting the flag
1161:    output parameter in the routine func().  Be sure to read this information!

1163:    The routine func() takes Mat * as the matrix arguments rather than Mat.  
1164:    This allows the Jacobian evaluation routine to replace A and/or B with a 
1165:    completely new new matrix structure (not just different matrix elements)
1166:    when appropriate, for instance, if the nonzero structure is changing
1167:    throughout the global iterations.

1169:    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
1170:    each matrix.

1172:    Level: beginner

1174: .keywords: SNES, nonlinear, set, Jacobian, matrix

1176: .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
1177: @*/
1178: PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
1179: {

1188:   if (func) snes->ops->computejacobian = func;
1189:   if (ctx)  snes->jacP                 = ctx;
1190:   if (A) {
1191:     PetscObjectReference((PetscObject)A);
1192:     if (snes->jacobian) {MatDestroy(snes->jacobian);}
1193:     snes->jacobian = A;
1194:   }
1195:   if (B) {
1196:     PetscObjectReference((PetscObject)B);
1197:     if (snes->jacobian_pre) {MatDestroy(snes->jacobian_pre);}
1198:     snes->jacobian_pre = B;
1199:   }
1200:   return(0);
1201: }

1205: /*@C
1206:    SNESGetJacobian - Returns the Jacobian matrix and optionally the user 
1207:    provided context for evaluating the Jacobian.

1209:    Not Collective, but Mat object will be parallel if SNES object is

1211:    Input Parameter:
1212: .  snes - the nonlinear solver context

1214:    Output Parameters:
1215: +  A - location to stash Jacobian matrix (or PETSC_NULL)
1216: .  B - location to stash preconditioner matrix (or PETSC_NULL)
1217: .  func - location to put Jacobian function (or PETSC_NULL)
1218: -  ctx - location to stash Jacobian ctx (or PETSC_NULL)

1220:    Level: advanced

1222: .seealso: SNESSetJacobian(), SNESComputeJacobian()
1223: @*/
1224: PetscErrorCode  SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
1225: {
1228:   if (A)    *A    = snes->jacobian;
1229:   if (B)    *B    = snes->jacobian_pre;
1230:   if (func) *func = snes->ops->computejacobian;
1231:   if (ctx)  *ctx  = snes->jacP;
1232:   return(0);
1233: }

1235: /* ----- Routines to initialize and destroy a nonlinear solver ---- */
1236: EXTERN PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);

1240: /*@
1241:    SNESSetUp - Sets up the internal data structures for the later use
1242:    of a nonlinear solver.

1244:    Collective on SNES

1246:    Input Parameters:
1247: .  snes - the SNES context

1249:    Notes:
1250:    For basic use of the SNES solvers the user need not explicitly call
1251:    SNESSetUp(), since these actions will automatically occur during
1252:    the call to SNESSolve().  However, if one wishes to control this
1253:    phase separately, SNESSetUp() should be called after SNESCreate()
1254:    and optional routines of the form SNESSetXXX(), but before SNESSolve().  

1256:    Level: advanced

1258: .keywords: SNES, nonlinear, setup

1260: .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
1261: @*/
1262: PetscErrorCode  SNESSetUp(SNES snes)
1263: {
1265:   PetscTruth     flg;

1269:   if (snes->setupcalled) return(0);

1271:   if (!((PetscObject)snes)->type_name) {
1272:     SNESSetType(snes,SNESLS);
1273:   }

1275:   PetscOptionsHasName(((PetscObject)snes)->prefix,"-snes_mf_operator",&flg);
1276:   /*
1277:       This version replaces the user provided Jacobian matrix with a
1278:       matrix-free version but still employs the user-provided preconditioner matrix
1279:   */
1280:   if (flg) {
1281:     Mat J;
1282:     MatCreateSNESMF(snes,&J);
1283:     MatMFFDSetFromOptions(J);
1284:     PetscInfo(snes,"Setting default matrix-free operator routines\n");
1285:     SNESSetJacobian(snes,J,0,0,0);
1286:     MatDestroy(J);
1287:   }

1289: #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_MAT_SINGLE) && !defined(PETSC_USE_LONG_DOUBLE) && !defined(PETSC_USE_INT)
1290:   PetscOptionsHasName(((PetscObject)snes)->prefix,"-snes_mf_operator2",&flg);
1291:   if (flg) {
1292:     Mat J;
1293:     SNESDefaultMatrixFreeCreate2(snes,snes->vec_sol,&J);
1294:     PetscInfo(snes,"Setting default matrix-free operator routines (version 2)\n");
1295:     SNESSetJacobian(snes,J,0,0,0);
1296:     MatDestroy(J);
1297:   }
1298: #endif

1300:   PetscOptionsHasName(((PetscObject)snes)->prefix,"-snes_mf",&flg);
1301:   /*
1302:       This version replaces both the user-provided Jacobian and the user-
1303:       provided preconditioner matrix with the default matrix free version.
1304:    */
1305:   if (flg) {
1306:     Mat  J;
1307:     KSP ksp;
1308:     PC   pc;
1309:     /* create and set matrix-free operator */
1310:     MatCreateSNESMF(snes,&J);
1311:     MatMFFDSetFromOptions(J);
1312:     PetscInfo(snes,"Setting default matrix-free operator routines\n");
1313:     SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);
1314:     MatDestroy(J);
1315:     /* force no preconditioner */
1316:     SNESGetKSP(snes,&ksp);
1317:     KSPGetPC(ksp,&pc);
1318:     PetscTypeCompare((PetscObject)pc,PCSHELL,&flg);
1319:     if (!flg) {
1320:       PetscInfo(snes,"Setting default matrix-free preconditioner routines;\nThat is no preconditioner is being used\n");
1321:       PCSetType(pc,PCNONE);
1322:     }
1323:   }

1325:   if (!snes->vec_func && !snes->vec_rhs) {
1326:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
1327:   }
1328:   if (!snes->ops->computefunction && !snes->vec_rhs) {
1329:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
1330:   }
1331:   if (snes->vec_func == snes->vec_sol) {
1332:     SETERRQ(PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
1333:   }
1334: 
1335:   if (!snes->ksp) {SNESGetKSP(snes, &snes->ksp);}
1336: 
1337:   if (snes->ops->setup) {
1338:     (*snes->ops->setup)(snes);
1339:   }
1340:   snes->setupcalled = PETSC_TRUE;
1341:   return(0);
1342: }

1346: /*@
1347:    SNESDestroy - Destroys the nonlinear solver context that was created
1348:    with SNESCreate().

1350:    Collective on SNES

1352:    Input Parameter:
1353: .  snes - the SNES context

1355:    Level: beginner

1357: .keywords: SNES, nonlinear, destroy

1359: .seealso: SNESCreate(), SNESSolve()
1360: @*/
1361: PetscErrorCode  SNESDestroy(SNES snes)
1362: {

1367:   if (--((PetscObject)snes)->refct > 0) return(0);

1369:   /* if memory was published with AMS then destroy it */
1370:   PetscObjectDepublish(snes);
1371:   if (snes->ops->destroy) {(*(snes)->ops->destroy)(snes);}
1372: 
1373:   if (snes->vec_rhs) {VecDestroy(snes->vec_rhs);}
1374:   if (snes->vec_sol) {VecDestroy(snes->vec_sol);}
1375:   if (snes->vec_func) {VecDestroy(snes->vec_func);}
1376:   if (snes->jacobian) {MatDestroy(snes->jacobian);}
1377:   if (snes->jacobian_pre) {MatDestroy(snes->jacobian_pre);}
1378:   if (snes->ksp) {KSPDestroy(snes->ksp);}
1379:   PetscFree(snes->kspconvctx);
1380:   if (snes->vwork) {VecDestroyVecs(snes->vwork,snes->nvwork);}
1381:   SNESMonitorCancel(snes);
1382:   if (snes->ops->convergeddestroy) {(*snes->ops->convergeddestroy)(snes->cnvP);}
1383:   PetscHeaderDestroy(snes);
1384:   return(0);
1385: }

1387: /* ----------- Routines to set solver parameters ---------- */

1391: /*@
1392:    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.

1394:    Collective on SNES

1396:    Input Parameters:
1397: +  snes - the SNES context
1398: -  lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
1399:          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that

1401:    Options Database Keys: 
1402: .    -snes_lag_preconditioner <lag>

1404:    Notes:
1405:    The default is 1
1406:    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1407:    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use

1409:    Level: intermediate

1411: .keywords: SNES, nonlinear, set, convergence, tolerances

1413: .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()

1415: @*/
1416: PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
1417: {
1420:   if (lag < -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
1421:   if (!lag) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
1422:   snes->lagpreconditioner = lag;
1423:   return(0);
1424: }

1428: /*@
1429:    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt

1431:    Collective on SNES

1433:    Input Parameter:
1434: .  snes - the SNES context
1435:  
1436:    Output Parameter:
1437: .   lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
1438:          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that

1440:    Options Database Keys: 
1441: .    -snes_lag_preconditioner <lag>

1443:    Notes:
1444:    The default is 1
1445:    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1

1447:    Level: intermediate

1449: .keywords: SNES, nonlinear, set, convergence, tolerances

1451: .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()

1453: @*/
1454: PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
1455: {
1458:   *lag = snes->lagpreconditioner;
1459:   return(0);
1460: }

1464: /*@
1465:    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
1466:      often the preconditioner is rebuilt.

1468:    Collective on SNES

1470:    Input Parameters:
1471: +  snes - the SNES context
1472: -  lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
1473:          the Jacobian is built etc. -2 means rebuild at next chance but then never again

1475:    Options Database Keys: 
1476: .    -snes_lag_jacobian <lag>

1478:    Notes:
1479:    The default is 1
1480:    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1481:    If  -1 is used before the very first nonlinear solve the CODE WILL FAIL! because no Jacobian is used, use -2 to indicate you want it recomputed
1482:    at the next Newton step but never again (unless it is reset to another value)

1484:    Level: intermediate

1486: .keywords: SNES, nonlinear, set, convergence, tolerances

1488: .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()

1490: @*/
1491: PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
1492: {
1495:   if (lag < -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
1496:   if (!lag) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
1497:   snes->lagjacobian = lag;
1498:   return(0);
1499: }

1503: /*@
1504:    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt

1506:    Collective on SNES

1508:    Input Parameter:
1509: .  snes - the SNES context
1510:  
1511:    Output Parameter:
1512: .   lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
1513:          the Jacobian is built etc.

1515:    Options Database Keys: 
1516: .    -snes_lag_jacobian <lag>

1518:    Notes:
1519:    The default is 1
1520:    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1

1522:    Level: intermediate

1524: .keywords: SNES, nonlinear, set, convergence, tolerances

1526: .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()

1528: @*/
1529: PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
1530: {
1533:   *lag = snes->lagjacobian;
1534:   return(0);
1535: }

1539: /*@
1540:    SNESSetTolerances - Sets various parameters used in convergence tests.

1542:    Collective on SNES

1544:    Input Parameters:
1545: +  snes - the SNES context
1546: .  abstol - absolute convergence tolerance
1547: .  rtol - relative convergence tolerance
1548: .  stol -  convergence tolerance in terms of the norm
1549:            of the change in the solution between steps
1550: .  maxit - maximum number of iterations
1551: -  maxf - maximum number of function evaluations

1553:    Options Database Keys: 
1554: +    -snes_atol <abstol> - Sets abstol
1555: .    -snes_rtol <rtol> - Sets rtol
1556: .    -snes_stol <stol> - Sets stol
1557: .    -snes_max_it <maxit> - Sets maxit
1558: -    -snes_max_funcs <maxf> - Sets maxf

1560:    Notes:
1561:    The default maximum number of iterations is 50.
1562:    The default maximum number of function evaluations is 1000.

1564:    Level: intermediate

1566: .keywords: SNES, nonlinear, set, convergence, tolerances

1568: .seealso: SNESSetTrustRegionTolerance()
1569: @*/
1570: PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
1571: {
1574:   if (abstol != PETSC_DEFAULT)  snes->abstol      = abstol;
1575:   if (rtol != PETSC_DEFAULT)  snes->rtol      = rtol;
1576:   if (stol != PETSC_DEFAULT)  snes->xtol      = stol;
1577:   if (maxit != PETSC_DEFAULT) snes->max_its   = maxit;
1578:   if (maxf != PETSC_DEFAULT)  snes->max_funcs = maxf;
1579:   return(0);
1580: }

1584: /*@
1585:    SNESGetTolerances - Gets various parameters used in convergence tests.

1587:    Not Collective

1589:    Input Parameters:
1590: +  snes - the SNES context
1591: .  atol - absolute convergence tolerance
1592: .  rtol - relative convergence tolerance
1593: .  stol -  convergence tolerance in terms of the norm
1594:            of the change in the solution between steps
1595: .  maxit - maximum number of iterations
1596: -  maxf - maximum number of function evaluations

1598:    Notes:
1599:    The user can specify PETSC_NULL for any parameter that is not needed.

1601:    Level: intermediate

1603: .keywords: SNES, nonlinear, get, convergence, tolerances

1605: .seealso: SNESSetTolerances()
1606: @*/
1607: PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
1608: {
1611:   if (atol)  *atol  = snes->abstol;
1612:   if (rtol)  *rtol  = snes->rtol;
1613:   if (stol)  *stol  = snes->xtol;
1614:   if (maxit) *maxit = snes->max_its;
1615:   if (maxf)  *maxf  = snes->max_funcs;
1616:   return(0);
1617: }

1621: /*@
1622:    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.  

1624:    Collective on SNES

1626:    Input Parameters:
1627: +  snes - the SNES context
1628: -  tol - tolerance
1629:    
1630:    Options Database Key: 
1631: .  -snes_trtol <tol> - Sets tol

1633:    Level: intermediate

1635: .keywords: SNES, nonlinear, set, trust region, tolerance

1637: .seealso: SNESSetTolerances()
1638: @*/
1639: PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
1640: {
1643:   snes->deltatol = tol;
1644:   return(0);
1645: }

1647: /* 
1648:    Duplicate the lg monitors for SNES from KSP; for some reason with 
1649:    dynamic libraries things don't work under Sun4 if we just use 
1650:    macros instead of functions
1651: */
1654: PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
1655: {

1660:   KSPMonitorLG((KSP)snes,it,norm,ctx);
1661:   return(0);
1662: }

1666: PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
1667: {

1671:   KSPMonitorLGCreate(host,label,x,y,m,n,draw);
1672:   return(0);
1673: }

1677: PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG draw)
1678: {

1682:   KSPMonitorLGDestroy(draw);
1683:   return(0);
1684: }

1689: PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
1690: {
1691:   PetscDrawLG      lg;
1692:   PetscErrorCode   ierr;
1693:   PetscReal        x,y,per;
1694:   PetscViewer      v = (PetscViewer)monctx;
1695:   static PetscReal prev; /* should be in the context */
1696:   PetscDraw        draw;
1698:   if (!monctx) {
1699:     MPI_Comm    comm;

1701:     PetscObjectGetComm((PetscObject)snes,&comm);
1702:     v      = PETSC_VIEWER_DRAW_(comm);
1703:   }
1704:   PetscViewerDrawGetDrawLG(v,0,&lg);
1705:   if (!n) {PetscDrawLGReset(lg);}
1706:   PetscDrawLGGetDraw(lg,&draw);
1707:   PetscDrawSetTitle(draw,"Residual norm");
1708:   x = (PetscReal) n;
1709:   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
1710:   PetscDrawLGAddPoint(lg,&x,&y);
1711:   if (n < 20 || !(n % 5)) {
1712:     PetscDrawLGDraw(lg);
1713:   }

1715:   PetscViewerDrawGetDrawLG(v,1,&lg);
1716:   if (!n) {PetscDrawLGReset(lg);}
1717:   PetscDrawLGGetDraw(lg,&draw);
1718:   PetscDrawSetTitle(draw,"% elemts > .2*max elemt");
1719:    SNESMonitorRange_Private(snes,n,&per);
1720:   x = (PetscReal) n;
1721:   y = 100.0*per;
1722:   PetscDrawLGAddPoint(lg,&x,&y);
1723:   if (n < 20 || !(n % 5)) {
1724:     PetscDrawLGDraw(lg);
1725:   }

1727:   PetscViewerDrawGetDrawLG(v,2,&lg);
1728:   if (!n) {prev = rnorm;PetscDrawLGReset(lg);}
1729:   PetscDrawLGGetDraw(lg,&draw);
1730:   PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");
1731:   x = (PetscReal) n;
1732:   y = (prev - rnorm)/prev;
1733:   PetscDrawLGAddPoint(lg,&x,&y);
1734:   if (n < 20 || !(n % 5)) {
1735:     PetscDrawLGDraw(lg);
1736:   }

1738:   PetscViewerDrawGetDrawLG(v,3,&lg);
1739:   if (!n) {PetscDrawLGReset(lg);}
1740:   PetscDrawLGGetDraw(lg,&draw);
1741:   PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");
1742:   x = (PetscReal) n;
1743:   y = (prev - rnorm)/(prev*per);
1744:   if (n > 2) { /*skip initial crazy value */
1745:     PetscDrawLGAddPoint(lg,&x,&y);
1746:   }
1747:   if (n < 20 || !(n % 5)) {
1748:     PetscDrawLGDraw(lg);
1749:   }
1750:   prev = rnorm;
1751:   return(0);
1752: }

1756: PetscErrorCode  SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
1757: {

1761:   KSPMonitorLGCreate(host,label,x,y,m,n,draw);
1762:   return(0);
1763: }

1767: PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG draw)
1768: {

1772:   KSPMonitorLGDestroy(draw);
1773:   return(0);
1774: }

1776: /* ------------ Routines to set performance monitoring options ----------- */

1780: /*@C
1781:    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
1782:    iteration of the nonlinear solver to display the iteration's 
1783:    progress.   

1785:    Collective on SNES

1787:    Input Parameters:
1788: +  snes - the SNES context
1789: .  func - monitoring routine
1790: .  mctx - [optional] user-defined context for private data for the 
1791:           monitor routine (use PETSC_NULL if no context is desired)
1792: -  monitordestroy - [optional] routine that frees monitor context
1793:           (may be PETSC_NULL)

1795:    Calling sequence of func:
1796: $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)

1798: +    snes - the SNES context
1799: .    its - iteration number
1800: .    norm - 2-norm function value (may be estimated)
1801: -    mctx - [optional] monitoring context

1803:    Options Database Keys:
1804: +    -snes_monitor        - sets SNESMonitorDefault()
1805: .    -snes_monitor_draw    - sets line graph monitor,
1806:                             uses SNESMonitorLGCreate()
1807: _    -snes_monitor_cancel - cancels all monitors that have
1808:                             been hardwired into a code by 
1809:                             calls to SNESMonitorSet(), but
1810:                             does not cancel those set via
1811:                             the options database.

1813:    Notes: 
1814:    Several different monitoring routines may be set by calling
1815:    SNESMonitorSet() multiple times; all will be called in the 
1816:    order in which they were set.

1818:    Fortran notes: Only a single monitor function can be set for each SNES object

1820:    Level: intermediate

1822: .keywords: SNES, nonlinear, set, monitor

1824: .seealso: SNESMonitorDefault(), SNESMonitorCancel()
1825: @*/
1826: PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void*))
1827: {
1828:   PetscInt i;

1832:   if (snes->numbermonitors >= MAXSNESMONITORS) {
1833:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
1834:   }
1835:   for (i=0; i<snes->numbermonitors;i++) {
1836:     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) return(0);

1838:     /* check if both default monitors that share common ASCII viewer */
1839:     if (monitor == snes->monitor[i] && monitor == SNESMonitorDefault) {
1840:       if (mctx && snes->monitorcontext[i]) {
1841:         PetscErrorCode          ierr;
1842:         PetscViewerASCIIMonitor viewer1 = (PetscViewerASCIIMonitor) mctx;
1843:         PetscViewerASCIIMonitor viewer2 = (PetscViewerASCIIMonitor) snes->monitorcontext[i];
1844:         if (viewer1->viewer == viewer2->viewer) {
1845:           (*monitordestroy)(mctx);
1846:           return(0);
1847:         }
1848:       }
1849:     }
1850:   }
1851:   snes->monitor[snes->numbermonitors]           = monitor;
1852:   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
1853:   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
1854:   return(0);
1855: }

1859: /*@C
1860:    SNESMonitorCancel - Clears all the monitor functions for a SNES object.

1862:    Collective on SNES

1864:    Input Parameters:
1865: .  snes - the SNES context

1867:    Options Database Key:
1868: .  -snes_monitor_cancel - cancels all monitors that have been hardwired
1869:     into a code by calls to SNESMonitorSet(), but does not cancel those 
1870:     set via the options database

1872:    Notes: 
1873:    There is no way to clear one specific monitor from a SNES object.

1875:    Level: intermediate

1877: .keywords: SNES, nonlinear, set, monitor

1879: .seealso: SNESMonitorDefault(), SNESMonitorSet()
1880: @*/
1881: PetscErrorCode  SNESMonitorCancel(SNES snes)
1882: {
1884:   PetscInt       i;

1888:   for (i=0; i<snes->numbermonitors; i++) {
1889:     if (snes->monitordestroy[i]) {
1890:       (*snes->monitordestroy[i])(snes->monitorcontext[i]);
1891:     }
1892:   }
1893:   snes->numbermonitors = 0;
1894:   return(0);
1895: }

1899: /*@C
1900:    SNESSetConvergenceTest - Sets the function that is to be used 
1901:    to test for convergence of the nonlinear iterative solution.   

1903:    Collective on SNES

1905:    Input Parameters:
1906: +  snes - the SNES context
1907: .  func - routine to test for convergence
1908: .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
1909: -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)

1911:    Calling sequence of func:
1912: $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)

1914: +    snes - the SNES context
1915: .    it - current iteration (0 is the first and is before any Newton step)
1916: .    cctx - [optional] convergence context
1917: .    reason - reason for convergence/divergence
1918: .    xnorm - 2-norm of current iterate
1919: .    gnorm - 2-norm of current step
1920: -    f - 2-norm of function

1922:    Level: advanced

1924: .keywords: SNES, nonlinear, set, convergence, test

1926: .seealso: SNESDefaultConverged(), SNESSkipConverged()
1927: @*/
1928: PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
1929: {

1934:   if (!func) func = SNESSkipConverged;
1935:   if (snes->ops->convergeddestroy) {
1936:     (*snes->ops->convergeddestroy)(snes->cnvP);
1937:   }
1938:   snes->ops->converged        = func;
1939:   snes->ops->convergeddestroy = destroy;
1940:   snes->cnvP                  = cctx;
1941:   return(0);
1942: }

1946: /*@
1947:    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.

1949:    Not Collective

1951:    Input Parameter:
1952: .  snes - the SNES context

1954:    Output Parameter:
1955: .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 
1956:             manual pages for the individual convergence tests for complete lists

1958:    Level: intermediate

1960:    Notes: Can only be called after the call the SNESSolve() is complete.

1962: .keywords: SNES, nonlinear, set, convergence, test

1964: .seealso: SNESSetConvergenceTest(), SNESConvergedReason
1965: @*/
1966: PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
1967: {
1971:   *reason = snes->reason;
1972:   return(0);
1973: }

1977: /*@
1978:    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.

1980:    Collective on SNES

1982:    Input Parameters:
1983: +  snes - iterative context obtained from SNESCreate()
1984: .  a   - array to hold history
1985: .  its - integer array holds the number of linear iterations for each solve.
1986: .  na  - size of a and its
1987: -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
1988:            else it continues storing new values for new nonlinear solves after the old ones

1990:    Notes:
1991:    If set, this array will contain the function norms computed
1992:    at each step.

1994:    This routine is useful, e.g., when running a code for purposes
1995:    of accurate performance monitoring, when no I/O should be done
1996:    during the section of code that is being timed.

1998:    Level: intermediate

2000: .keywords: SNES, set, convergence, history

2002: .seealso: SNESGetConvergenceHistory()

2004: @*/
2005: PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscTruth reset)
2006: {
2011:   snes->conv_hist       = a;
2012:   snes->conv_hist_its   = its;
2013:   snes->conv_hist_max   = na;
2014:   snes->conv_hist_len   = 0;
2015:   snes->conv_hist_reset = reset;
2016:   return(0);
2017: }

2021: /*@C
2022:    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.

2024:    Collective on SNES

2026:    Input Parameter:
2027: .  snes - iterative context obtained from SNESCreate()

2029:    Output Parameters:
2030: .  a   - array to hold history
2031: .  its - integer array holds the number of linear iterations (or
2032:          negative if not converged) for each solve.
2033: -  na  - size of a and its

2035:    Notes:
2036:     The calling sequence for this routine in Fortran is
2037: $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)

2039:    This routine is useful, e.g., when running a code for purposes
2040:    of accurate performance monitoring, when no I/O should be done
2041:    during the section of code that is being timed.

2043:    Level: intermediate

2045: .keywords: SNES, get, convergence, history

2047: .seealso: SNESSetConvergencHistory()

2049: @*/
2050: PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
2051: {
2054:   if (a)   *a   = snes->conv_hist;
2055:   if (its) *its = snes->conv_hist_its;
2056:   if (na)  *na  = snes->conv_hist_len;
2057:   return(0);
2058: }

2062: /*@C
2063:   SNESSetUpdate - Sets the general-purpose update function called
2064:   at the beginning o every iteration of the nonlinear solve. Specifically
2065:   it is called just before the Jacobian is "evaluated".

2067:   Collective on SNES

2069:   Input Parameters:
2070: . snes - The nonlinear solver context
2071: . func - The function

2073:   Calling sequence of func:
2074: . func (SNES snes, PetscInt step);

2076: . step - The current step of the iteration

2078:   Level: intermediate

2080: .keywords: SNES, update

2082: .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
2083: @*/
2084: PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
2085: {
2088:   snes->ops->update = func;
2089:   return(0);
2090: }

2094: /*@
2095:   SNESDefaultUpdate - The default update function which does nothing.

2097:   Not collective

2099:   Input Parameters:
2100: . snes - The nonlinear solver context
2101: . step - The current step of the iteration

2103:   Level: intermediate

2105: .keywords: SNES, update
2106: .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
2107: @*/
2108: PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
2109: {
2111:   return(0);
2112: }

2116: /*
2117:    SNESScaleStep_Private - Scales a step so that its length is less than the
2118:    positive parameter delta.

2120:     Input Parameters:
2121: +   snes - the SNES context
2122: .   y - approximate solution of linear system
2123: .   fnorm - 2-norm of current function
2124: -   delta - trust region size

2126:     Output Parameters:
2127: +   gpnorm - predicted function norm at the new point, assuming local 
2128:     linearization.  The value is zero if the step lies within the trust 
2129:     region, and exceeds zero otherwise.
2130: -   ynorm - 2-norm of the step

2132:     Note:
2133:     For non-trust region methods such as SNESLS, the parameter delta 
2134:     is set to be the maximum allowable step size.  

2136: .keywords: SNES, nonlinear, scale, step
2137: */
2138: PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
2139: {
2140:   PetscReal      nrm;
2141:   PetscScalar    cnorm;


2149:   VecNorm(y,NORM_2,&nrm);
2150:   if (nrm > *delta) {
2151:      nrm = *delta/nrm;
2152:      *gpnorm = (1.0 - nrm)*(*fnorm);
2153:      cnorm = nrm;
2154:      VecScale(y,cnorm);
2155:      *ynorm = *delta;
2156:   } else {
2157:      *gpnorm = 0.0;
2158:      *ynorm = nrm;
2159:   }
2160:   return(0);
2161: }

2165: /*@C
2166:    SNESSolve - Solves a nonlinear system F(x) = b.
2167:    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().

2169:    Collective on SNES

2171:    Input Parameters:
2172: +  snes - the SNES context
2173: .  b - the constant part of the equation, or PETSC_NULL to use zero.
2174: -  x - the solution vector.

2176:    Notes:
2177:    The user should initialize the vector,x, with the initial guess
2178:    for the nonlinear solve prior to calling SNESSolve.  In particular,
2179:    to employ an initial guess of zero, the user should explicitly set
2180:    this vector to zero by calling VecSet().

2182:    Level: beginner

2184: .keywords: SNES, nonlinear, solve

2186: .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian()
2187: @*/
2188: PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
2189: {
2191:   PetscTruth     flg;
2192:   char           filename[PETSC_MAX_PATH_LEN];
2193:   PetscViewer    viewer;


2202:   /* set solution vector */
2203:   PetscObjectReference((PetscObject)x);
2204:   if (snes->vec_sol) { VecDestroy(snes->vec_sol); }
2205:   snes->vec_sol = x;
2206:   /* set afine vector if provided */
2207:   if (b) { PetscObjectReference((PetscObject)b); }
2208:   if (snes->vec_rhs) { VecDestroy(snes->vec_rhs); }
2209:   snes->vec_rhs = b;
2210: 
2211:   if (!snes->vec_func && snes->vec_rhs) {
2212:     VecDuplicate(b, &snes->vec_func);
2213:   }

2215:   SNESSetUp(snes);

2217:   if (snes->conv_hist_reset) snes->conv_hist_len = 0;
2218:   snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;

2220:   PetscLogEventBegin(SNES_Solve,snes,0,0,0);
2221:   (*snes->ops->solve)(snes);
2222:   PetscLogEventEnd(SNES_Solve,snes,0,0,0);
2223:   if (snes->domainerror){
2224:     snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
2225:     snes->domainerror = PETSC_FALSE;
2226:   }

2228:   if (!snes->reason) {
2229:     SETERRQ(PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
2230:   }
2231: 
2232:   PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);
2233:   if (flg && !PetscPreLoadingOn) {
2234:     PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);
2235:     SNESView(snes,viewer);
2236:     PetscViewerDestroy(viewer);
2237:   }

2239:   PetscOptionsHasName(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg);
2240:   if (flg && !PetscPreLoadingOn) { SNESTestLocalMin(snes); }
2241:   if (snes->printreason) {
2242:     if (snes->reason > 0) {
2243:       PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);
2244:     } else {
2245:       PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);
2246:     }
2247:   }

2249:   return(0);
2250: }

2252: /* --------- Internal routines for SNES Package --------- */

2256: /*@C
2257:    SNESSetType - Sets the method for the nonlinear solver.  

2259:    Collective on SNES

2261:    Input Parameters:
2262: +  snes - the SNES context
2263: -  type - a known method

2265:    Options Database Key:
2266: .  -snes_type <type> - Sets the method; use -help for a list
2267:    of available methods (for instance, ls or tr)

2269:    Notes:
2270:    See "petsc/include/petscsnes.h" for available methods (for instance)
2271: +    SNESLS - Newton's method with line search
2272:      (systems of nonlinear equations)
2273: .    SNESTR - Newton's method with trust region
2274:      (systems of nonlinear equations)

2276:   Normally, it is best to use the SNESSetFromOptions() command and then
2277:   set the SNES solver type from the options database rather than by using
2278:   this routine.  Using the options database provides the user with
2279:   maximum flexibility in evaluating the many nonlinear solvers.
2280:   The SNESSetType() routine is provided for those situations where it
2281:   is necessary to set the nonlinear solver independently of the command
2282:   line or options database.  This might be the case, for example, when
2283:   the choice of solver changes during the execution of the program,
2284:   and the user's application is taking responsibility for choosing the
2285:   appropriate method.

2287:   Level: intermediate

2289: .keywords: SNES, set, type

2291: .seealso: SNESType, SNESCreate()

2293: @*/
2294: PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
2295: {
2296:   PetscErrorCode ierr,(*r)(SNES);
2297:   PetscTruth     match;


2303:   PetscTypeCompare((PetscObject)snes,type,&match);
2304:   if (match) return(0);

2306:    PetscFListFind(SNESList,((PetscObject)snes)->comm,type,(void (**)(void)) &r);
2307:   if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
2308:   /* Destroy the previous private SNES context */
2309:   if (snes->ops->destroy) { (*(snes)->ops->destroy)(snes); }
2310:   /* Reinitialize function pointers in SNESOps structure */
2311:   snes->ops->setup          = 0;
2312:   snes->ops->solve          = 0;
2313:   snes->ops->view           = 0;
2314:   snes->ops->setfromoptions = 0;
2315:   snes->ops->destroy        = 0;
2316:   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
2317:   snes->setupcalled = PETSC_FALSE;
2318:   (*r)(snes);
2319:   PetscObjectChangeTypeName((PetscObject)snes,type);
2320:   return(0);
2321: }


2324: /* --------------------------------------------------------------------- */
2327: /*@
2328:    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
2329:    registered by SNESRegisterDynamic().

2331:    Not Collective

2333:    Level: advanced

2335: .keywords: SNES, nonlinear, register, destroy

2337: .seealso: SNESRegisterAll(), SNESRegisterAll()
2338: @*/
2339: PetscErrorCode  SNESRegisterDestroy(void)
2340: {

2344:   PetscFListDestroy(&SNESList);
2345:   SNESRegisterAllCalled = PETSC_FALSE;
2346:   return(0);
2347: }

2351: /*@C
2352:    SNESGetType - Gets the SNES method type and name (as a string).

2354:    Not Collective

2356:    Input Parameter:
2357: .  snes - nonlinear solver context

2359:    Output Parameter:
2360: .  type - SNES method (a character string)

2362:    Level: intermediate

2364: .keywords: SNES, nonlinear, get, type, name
2365: @*/
2366: PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
2367: {
2371:   *type = ((PetscObject)snes)->type_name;
2372:   return(0);
2373: }

2377: /*@
2378:    SNESGetSolution - Returns the vector where the approximate solution is
2379:    stored.

2381:    Not Collective, but Vec is parallel if SNES is parallel

2383:    Input Parameter:
2384: .  snes - the SNES context

2386:    Output Parameter:
2387: .  x - the solution

2389:    Level: intermediate

2391: .keywords: SNES, nonlinear, get, solution

2393: .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
2394: @*/
2395: PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
2396: {
2400:   *x = snes->vec_sol;
2401:   return(0);
2402: }

2406: /*@
2407:    SNESGetSolutionUpdate - Returns the vector where the solution update is
2408:    stored. 

2410:    Not Collective, but Vec is parallel if SNES is parallel

2412:    Input Parameter:
2413: .  snes - the SNES context

2415:    Output Parameter:
2416: .  x - the solution update

2418:    Level: advanced

2420: .keywords: SNES, nonlinear, get, solution, update

2422: .seealso: SNESGetSolution(), SNESGetFunction()
2423: @*/
2424: PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
2425: {
2429:   *x = snes->vec_sol_update;
2430:   return(0);
2431: }

2435: /*@C
2436:    SNESGetFunction - Returns the vector where the function is stored.

2438:    Not Collective, but Vec is parallel if SNES is parallel

2440:    Input Parameter:
2441: .  snes - the SNES context

2443:    Output Parameter:
2444: +  r - the function (or PETSC_NULL)
2445: .  func - the function (or PETSC_NULL)
2446: -  ctx - the function context (or PETSC_NULL)

2448:    Level: advanced

2450: .keywords: SNES, nonlinear, get, function

2452: .seealso: SNESSetFunction(), SNESGetSolution()
2453: @*/
2454: PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
2455: {
2458:   if (r)    *r    = snes->vec_func;
2459:   if (func) *func = snes->ops->computefunction;
2460:   if (ctx)  *ctx  = snes->funP;
2461:   return(0);
2462: }

2466: /*@C
2467:    SNESSetOptionsPrefix - Sets the prefix used for searching for all 
2468:    SNES options in the database.

2470:    Collective on SNES

2472:    Input Parameter:
2473: +  snes - the SNES context
2474: -  prefix - the prefix to prepend to all option names

2476:    Notes:
2477:    A hyphen (-) must NOT be given at the beginning of the prefix name.
2478:    The first character of all runtime options is AUTOMATICALLY the hyphen.

2480:    Level: advanced

2482: .keywords: SNES, set, options, prefix, database

2484: .seealso: SNESSetFromOptions()
2485: @*/
2486: PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
2487: {

2492:   PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);
2493:   if (!snes->ksp) {SNESGetKSP(snes,&snes->ksp);}
2494:   KSPSetOptionsPrefix(snes->ksp,prefix);
2495:   return(0);
2496: }

2500: /*@C
2501:    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 
2502:    SNES options in the database.

2504:    Collective on SNES

2506:    Input Parameters:
2507: +  snes - the SNES context
2508: -  prefix - the prefix to prepend to all option names

2510:    Notes:
2511:    A hyphen (-) must NOT be given at the beginning of the prefix name.
2512:    The first character of all runtime options is AUTOMATICALLY the hyphen.

2514:    Level: advanced

2516: .keywords: SNES, append, options, prefix, database

2518: .seealso: SNESGetOptionsPrefix()
2519: @*/
2520: PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
2521: {
2523: 
2526:   PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);
2527:   if (!snes->ksp) {SNESGetKSP(snes,&snes->ksp);}
2528:   KSPAppendOptionsPrefix(snes->ksp,prefix);
2529:   return(0);
2530: }

2534: /*@C
2535:    SNESGetOptionsPrefix - Sets the prefix used for searching for all 
2536:    SNES options in the database.

2538:    Not Collective

2540:    Input Parameter:
2541: .  snes - the SNES context

2543:    Output Parameter:
2544: .  prefix - pointer to the prefix string used

2546:    Notes: On the fortran side, the user should pass in a string 'prefix' of
2547:    sufficient length to hold the prefix.

2549:    Level: advanced

2551: .keywords: SNES, get, options, prefix, database

2553: .seealso: SNESAppendOptionsPrefix()
2554: @*/
2555: PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
2556: {

2561:   PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);
2562:   return(0);
2563: }


2568: /*@C
2569:   SNESRegister - See SNESRegisterDynamic()

2571:   Level: advanced
2572: @*/
2573: PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
2574: {
2575:   char           fullname[PETSC_MAX_PATH_LEN];

2579:   PetscFListConcat(path,name,fullname);
2580:   PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);
2581:   return(0);
2582: }

2586: PetscErrorCode  SNESTestLocalMin(SNES snes)
2587: {
2589:   PetscInt       N,i,j;
2590:   Vec            u,uh,fh;
2591:   PetscScalar    value;
2592:   PetscReal      norm;

2595:   SNESGetSolution(snes,&u);
2596:   VecDuplicate(u,&uh);
2597:   VecDuplicate(u,&fh);

2599:   /* currently only works for sequential */
2600:   PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
2601:   VecGetSize(u,&N);
2602:   for (i=0; i<N; i++) {
2603:     VecCopy(u,uh);
2604:     PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);
2605:     for (j=-10; j<11; j++) {
2606:       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
2607:       VecSetValue(uh,i,value,ADD_VALUES);
2608:       SNESComputeFunction(snes,uh,fh);
2609:       VecNorm(fh,NORM_2,&norm);
2610:       PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);
2611:       value = -value;
2612:       VecSetValue(uh,i,value,ADD_VALUES);
2613:     }
2614:   }
2615:   VecDestroy(uh);
2616:   VecDestroy(fh);
2617:   return(0);
2618: }

2622: /*@
2623:    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
2624:    computing relative tolerance for linear solvers within an inexact
2625:    Newton method.

2627:    Collective on SNES

2629:    Input Parameters:
2630: +  snes - SNES context
2631: -  flag - PETSC_TRUE or PETSC_FALSE

2633:    Notes:
2634:    Currently, the default is to use a constant relative tolerance for 
2635:    the inner linear solvers.  Alternatively, one can use the 
2636:    Eisenstat-Walker method, where the relative convergence tolerance 
2637:    is reset at each Newton iteration according progress of the nonlinear 
2638:    solver. 

2640:    Level: advanced

2642:    Reference:
2643:    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 
2644:    inexact Newton method", SISC 17 (1), pp.16-32, 1996.

2646: .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton

2648: .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
2649: @*/
2650: PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscTruth flag)
2651: {
2654:   snes->ksp_ewconv = flag;
2655:   return(0);
2656: }

2660: /*@
2661:    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
2662:    for computing relative tolerance for linear solvers within an
2663:    inexact Newton method.

2665:    Not Collective

2667:    Input Parameter:
2668: .  snes - SNES context

2670:    Output Parameter:
2671: .  flag - PETSC_TRUE or PETSC_FALSE

2673:    Notes:
2674:    Currently, the default is to use a constant relative tolerance for 
2675:    the inner linear solvers.  Alternatively, one can use the 
2676:    Eisenstat-Walker method, where the relative convergence tolerance 
2677:    is reset at each Newton iteration according progress of the nonlinear 
2678:    solver. 

2680:    Level: advanced

2682:    Reference:
2683:    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 
2684:    inexact Newton method", SISC 17 (1), pp.16-32, 1996.

2686: .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton

2688: .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
2689: @*/
2690: PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscTruth *flag)
2691: {
2695:   *flag = snes->ksp_ewconv;
2696:   return(0);
2697: }

2701: /*@
2702:    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
2703:    convergence criteria for the linear solvers within an inexact
2704:    Newton method.

2706:    Collective on SNES
2707:  
2708:    Input Parameters:
2709: +    snes - SNES context
2710: .    version - version 1, 2 (default is 2) or 3
2711: .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
2712: .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
2713: .    gamma - multiplicative factor for version 2 rtol computation
2714:              (0 <= gamma2 <= 1)
2715: .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
2716: .    alpha2 - power for safeguard
2717: -    threshold - threshold for imposing safeguard (0 < threshold < 1)

2719:    Note:
2720:    Version 3 was contributed by Luis Chacon, June 2006.

2722:    Use PETSC_DEFAULT to retain the default for any of the parameters.

2724:    Level: advanced

2726:    Reference:
2727:    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 
2728:    inexact Newton method", Utah State University Math. Stat. Dept. Res. 
2729:    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 

2731: .keywords: SNES, KSP, Eisenstat, Walker, set, parameters

2733: .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
2734: @*/
2735: PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
2736:                                                             PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
2737: {
2738:   SNESKSPEW *kctx;
2741:   kctx = (SNESKSPEW*)snes->kspconvctx;
2742:   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");

2744:   if (version != PETSC_DEFAULT)   kctx->version   = version;
2745:   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
2746:   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
2747:   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
2748:   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
2749:   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
2750:   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
2751: 
2752:   if (kctx->version < 1 || kctx->version > 3) {
2753:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
2754:   }
2755:   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
2756:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
2757:   }
2758:   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
2759:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
2760:   }
2761:   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
2762:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
2763:   }
2764:   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
2765:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
2766:   }
2767:   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
2768:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
2769:   }
2770:   return(0);
2771: }

2775: /*@
2776:    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
2777:    convergence criteria for the linear solvers within an inexact
2778:    Newton method.

2780:    Not Collective
2781:  
2782:    Input Parameters:
2783:      snes - SNES context

2785:    Output Parameters:
2786: +    version - version 1, 2 (default is 2) or 3
2787: .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
2788: .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
2789: .    gamma - multiplicative factor for version 2 rtol computation
2790:              (0 <= gamma2 <= 1)
2791: .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
2792: .    alpha2 - power for safeguard
2793: -    threshold - threshold for imposing safeguard (0 < threshold < 1)

2795:    Level: advanced

2797: .keywords: SNES, KSP, Eisenstat, Walker, get, parameters

2799: .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
2800: @*/
2801: PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
2802:                                                             PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
2803: {
2804:   SNESKSPEW *kctx;
2807:   kctx = (SNESKSPEW*)snes->kspconvctx;
2808:   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
2809:   if(version)   *version   = kctx->version;
2810:   if(rtol_0)    *rtol_0    = kctx->rtol_0;
2811:   if(rtol_max)  *rtol_max  = kctx->rtol_max;
2812:   if(gamma)     *gamma     = kctx->gamma;
2813:   if(alpha)     *alpha     = kctx->alpha;
2814:   if(alpha2)    *alpha2    = kctx->alpha2;
2815:   if(threshold) *threshold = kctx->threshold;
2816:   return(0);
2817: }

2821: static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
2822: {
2824:   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
2825:   PetscReal      rtol=PETSC_DEFAULT,stol;

2828:   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
2829:   if (!snes->iter) { /* first time in, so use the original user rtol */
2830:     rtol = kctx->rtol_0;
2831:   } else {
2832:     if (kctx->version == 1) {
2833:       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
2834:       if (rtol < 0.0) rtol = -rtol;
2835:       stol = pow(kctx->rtol_last,kctx->alpha2);
2836:       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
2837:     } else if (kctx->version == 2) {
2838:       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
2839:       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
2840:       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
2841:     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
2842:       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
2843:       /* safeguard: avoid sharp decrease of rtol */
2844:       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
2845:       stol = PetscMax(rtol,stol);
2846:       rtol = PetscMin(kctx->rtol_0,stol);
2847:       /* safeguard: avoid oversolving */
2848:       stol = kctx->gamma*(snes->ttol)/snes->norm;
2849:       stol = PetscMax(rtol,stol);
2850:       rtol = PetscMin(kctx->rtol_0,stol);
2851:     } else SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
2852:   }
2853:   /* safeguard: avoid rtol greater than one */
2854:   rtol = PetscMin(rtol,kctx->rtol_max);
2855:   KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);
2856:   PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);
2857:   return(0);
2858: }

2862: static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
2863: {
2865:   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
2866:   PCSide         pcside;
2867:   Vec            lres;

2870:   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
2871:   KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);
2872:   SNESGetFunctionNorm(snes,&kctx->norm_last);
2873:   if (kctx->version == 1) {
2874:     KSPGetPreconditionerSide(ksp,&pcside);
2875:     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
2876:       /* KSP residual is true linear residual */
2877:       KSPGetResidualNorm(ksp,&kctx->lresid_last);
2878:     } else {
2879:       /* KSP residual is preconditioned residual */
2880:       /* compute true linear residual norm */
2881:       VecDuplicate(b,&lres);
2882:       MatMult(snes->jacobian,x,lres);
2883:       VecAYPX(lres,-1.0,b);
2884:       VecNorm(lres,NORM_2,&kctx->lresid_last);
2885:       VecDestroy(lres);
2886:     }
2887:   }
2888:   return(0);
2889: }

2893: PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
2894: {

2898:   if (snes->ksp_ewconv) { SNESKSPEW_PreSolve(snes,ksp,b,x);  }
2899:   KSPSolve(ksp,b,x);
2900:   if (snes->ksp_ewconv) { SNESKSPEW_PostSolve(snes,ksp,b,x); }
2901:   return(0);
2902: }