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:     if (snes->lagpreconditioner == -1) {
117:       PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");
118:     } else if (snes->lagpreconditioner > 1) {
119:       PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);
120:     }
121:     if (snes->lagjacobian == -1) {
122:       PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");
123:     } else if (snes->lagjacobian > 1) {
124:       PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D Newton iterations\n",snes->lagjacobian);
125:     }
126:   } else if (isstring) {
127:     SNESGetType(snes,&type);
128:     PetscViewerStringSPrintf(viewer," %-3.3s",type);
129:   }
130:   SNESGetKSP(snes,&ksp);
131:   PetscViewerASCIIPushTab(viewer);
132:   KSPView(ksp,viewer);
133:   PetscViewerASCIIPopTab(viewer);
134:   return(0);
135: }

137: /*
138:   We retain a list of functions that also take SNES command 
139:   line options. These are called at the end SNESSetFromOptions()
140: */
141: #define MAXSETFROMOPTIONS 5
142: static PetscInt numberofsetfromoptions;
143: static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);

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

150:   Not Collective

152:   Input Parameter:
153: . snescheck - function that checks for options

155:   Level: developer

157: .seealso: SNESSetFromOptions()
158: @*/
159: PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
160: {
162:   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
163:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
164:   }
165:   othersetfromoptions[numberofsetfromoptions++] = snescheck;
166:   return(0);
167: }

169: EXTERN PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);

173: static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscTruth hasOperator, PetscInt version)
174: {
175:   Mat            J;
176:   KSP            ksp;
177:   PC             pc;
178:   PetscTruth     match;


184:   if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
185:     Mat A = snes->jacobian, B = snes->jacobian_pre;
186:     MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);
187:   }

189:   if (version == 1) {
190:     MatCreateSNESMF(snes,&J);
191:     MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);
192:     MatMFFDSetFromOptions(J);
193:   } else if (version == 2) {
194:     if (!snes->vec_func) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
195: #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SCALAR_SINGLE) && !defined(PETSC_USE_SCALAR_MAT_SINGLE) && !defined(PETSC_USE_SCALAR_LONG_DOUBLE) && !defined(PETSC_USE_SCALAR_INT)
196:     SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);
197: #else
198:     SETERRQ(PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
199: #endif
200:   } else {
201:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
202:   }
203: 
204:   PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);
205:   if (hasOperator) {
206:     /* This version replaces the user provided Jacobian matrix with a
207:        matrix-free version but still employs the user-provided preconditioner matrix. */
208:     SNESSetJacobian(snes,J,0,0,0);
209:   } else {
210:     /* This version replaces both the user-provided Jacobian and the user-
211:        provided preconditioner matrix with the default matrix free version. */
212:     SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);
213:     /* Force no preconditioner */
214:     SNESGetKSP(snes,&ksp);
215:     KSPGetPC(ksp,&pc);
216:     PetscTypeCompare((PetscObject)pc,PCSHELL,&match);
217:     if (!match) {
218:       PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");
219:       PCSetType(pc,PCNONE);
220:     }
221:   }
222:   MatDestroy(J);

224:   return(0);
225: }

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

232:    Collective on SNES

234:    Input Parameter:
235: .  snes - the SNES context

237:    Options Database Keys:
238: +  -snes_type <type> - ls, tr, umls, umtr, test
239: .  -snes_stol - convergence tolerance in terms of the norm
240:                 of the change in the solution between steps
241: .  -snes_atol <abstol> - absolute tolerance of residual norm
242: .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
243: .  -snes_max_it <max_it> - maximum number of iterations
244: .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
245: .  -snes_max_fail <max_fail> - maximum number of failures
246: .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
247: .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
248: .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
249: .  -snes_trtol <trtol> - trust region tolerance
250: .  -snes_no_convergence_test - skip convergence test in nonlinear 
251:                                solver; hence iterations will continue until max_it
252:                                or some other criterion is reached. Saves expense
253:                                of convergence test
254: .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
255:                                        filename given prints to stdout
256: .  -snes_monitor_solution - plots solution at each iteration
257: .  -snes_monitor_residual - plots residual (not its norm) at each iteration
258: .  -snes_monitor_solution_update - plots update to solution at each iteration 
259: .  -snes_monitor_draw - plots residual norm at each iteration 
260: .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
261: .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
262: -  -snes_converged_reason - print the reason for convergence/divergence after each solve

264:     Options Database for Eisenstat-Walker method:
265: +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
266: .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
267: .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
268: .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
269: .  -snes_ksp_ew_gamma <gamma> - Sets gamma
270: .  -snes_ksp_ew_alpha <alpha> - Sets alpha
271: .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 
272: -  -snes_ksp_ew_threshold <threshold> - Sets threshold

274:    Notes:
275:    To see all options, run your program with the -help option or consult
276:    the users manual.

278:    Level: beginner

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

282: .seealso: SNESSetOptionsPrefix()
283: @*/
284: PetscErrorCode  SNESSetFromOptions(SNES snes)
285: {
286:   PetscTruth              flg,mf,mf_operator;
287:   PetscInt                i,indx,lag,mf_version;
288:   MatStructure            matflag;
289:   const char              *deft = SNESLS;
290:   const char              *convtests[] = {"default","skip"};
291:   SNESKSPEW               *kctx = NULL;
292:   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
293:   PetscViewerASCIIMonitor monviewer;
294:   PetscErrorCode          ierr;


299:   if (!SNESRegisterAllCalled) {SNESRegisterAll(PETSC_NULL);}
300:   PetscOptionsBegin(((PetscObject)snes)->comm,((PetscObject)snes)->prefix,"Nonlinear solver (SNES) options","SNES");
301:     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
302:     PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);
303:     if (flg) {
304:       SNESSetType(snes,type);
305:     } else if (!((PetscObject)snes)->type_name) {
306:       SNESSetType(snes,deft);
307:     }
308:     /* not used here, but called so will go into help messaage */
309:     PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);

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

314:     PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);
315:     PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);
316:     PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);
317:     PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);
318:     PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);

320:     PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);
321:     if (flg) {
322:       SNESSetLagPreconditioner(snes,lag);
323:     }
324:     PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);
325:     if (flg) {
326:       SNESSetLagJacobian(snes,lag);
327:     }

329:     PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);
330:     if (flg) {
331:       switch (indx) {
332:       case 0: SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL); break;
333:       case 1: SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);    break;
334:       }
335:     }

337:     PetscOptionsTruth("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);

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

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

343:     PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);
344:     PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);
345:     PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);
346:     PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);
347:     PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);
348:     PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);
349:     PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);

351:     flg  = PETSC_FALSE;
352:     PetscOptionsTruth("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);
353:     if (flg) {SNESMonitorCancel(snes);}

355:     PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
356:     if (flg) {
357:       PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,((PetscObject)snes)->tablevel,&monviewer);
358:       SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);
359:     }

361:     PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
362:     if (flg) {
363:       SNESMonitorSet(snes,SNESMonitorRange,0,0);
364:     }

366:     PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
367:     if (flg) {
368:       PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,((PetscObject)snes)->tablevel,&monviewer);
369:       SNESMonitorSetRatio(snes,monviewer);
370:     }

372:     PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
373:     if (flg) {
374:       PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,((PetscObject)snes)->tablevel,&monviewer);
375:       SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);
376:     }

378:     flg  = PETSC_FALSE;
379:     PetscOptionsTruth("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);
380:     if (flg) {SNESMonitorSet(snes,SNESMonitorSolution,0,0);}
381:     flg  = PETSC_FALSE;
382:     PetscOptionsTruth("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);
383:     if (flg) {SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);}
384:     flg  = PETSC_FALSE;
385:     PetscOptionsTruth("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);
386:     if (flg) {SNESMonitorSet(snes,SNESMonitorResidual,0,0);}
387:     flg  = PETSC_FALSE;
388:     PetscOptionsTruth("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);
389:     if (flg) {SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);}
390:     flg  = PETSC_FALSE;
391:     PetscOptionsTruth("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);
392:     if (flg) {SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);}

394:     flg  = PETSC_FALSE;
395:     PetscOptionsTruth("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);
396:     if (flg) {
397:       SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);
398:       PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");
399:     }

401:     mf = mf_operator = PETSC_FALSE;
402:     flg = PETSC_FALSE;
403:     PetscOptionsTruth("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);
404:     if (flg && mf_operator) mf = PETSC_TRUE;
405:     flg = PETSC_FALSE;
406:     PetscOptionsTruth("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);
407:     if (!flg && mf_operator) mf = PETSC_TRUE;
408:     mf_version = 1;
409:     PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);

411:     for(i = 0; i < numberofsetfromoptions; i++) {
412:       (*othersetfromoptions[i])(snes);
413:     }

415:     if (snes->ops->setfromoptions) {
416:       (*snes->ops->setfromoptions)(snes);
417:     }
418:   PetscOptionsEnd();

420:   if (mf) { SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version); }
421: 
422:   if (!snes->ksp) {SNESGetKSP(snes,&snes->ksp);}
423:   KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
424:   KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);
425:   KSPSetFromOptions(snes->ksp);

427:   return(0);
428: }


433: /*@
434:    SNESSetApplicationContext - Sets the optional user-defined context for 
435:    the nonlinear solvers.  

437:    Collective on SNES

439:    Input Parameters:
440: +  snes - the SNES context
441: -  usrP - optional user context

443:    Level: intermediate

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

447: .seealso: SNESGetApplicationContext()
448: @*/
449: PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
450: {
453:   snes->user                = usrP;
454:   return(0);
455: }

459: /*@C
460:    SNESGetApplicationContext - Gets the user-defined context for the 
461:    nonlinear solvers.  

463:    Not Collective

465:    Input Parameter:
466: .  snes - SNES context

468:    Output Parameter:
469: .  usrP - user context

471:    Level: intermediate

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

475: .seealso: SNESSetApplicationContext()
476: @*/
477: PetscErrorCode  SNESGetApplicationContext(SNES snes,void **usrP)
478: {
481:   *usrP = snes->user;
482:   return(0);
483: }

487: /*@
488:    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
489:    at this time.

491:    Not Collective

493:    Input Parameter:
494: .  snes - SNES context

496:    Output Parameter:
497: .  iter - iteration number

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

502:    This is useful for using lagged Jacobians (where one does not recompute the 
503:    Jacobian at each SNES iteration). For example, the code
504: .vb
505:       SNESGetIterationNumber(snes,&it);
506:       if (!(it % 2)) {
507:         [compute Jacobian here]
508:       }
509: .ve
510:    can be used in your ComputeJacobian() function to cause the Jacobian to be
511:    recomputed every second SNES iteration.

513:    Level: intermediate

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

517: .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
518: @*/
519: PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
520: {
524:   *iter = snes->iter;
525:   return(0);
526: }

530: /*@
531:    SNESGetFunctionNorm - Gets the norm of the current function that was set
532:    with SNESSSetFunction().

534:    Collective on SNES

536:    Input Parameter:
537: .  snes - SNES context

539:    Output Parameter:
540: .  fnorm - 2-norm of function

542:    Level: intermediate

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

546: .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
547: @*/
548: PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
549: {
553:   *fnorm = snes->norm;
554:   return(0);
555: }

559: /*@
560:    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
561:    attempted by the nonlinear solver.

563:    Not Collective

565:    Input Parameter:
566: .  snes - SNES context

568:    Output Parameter:
569: .  nfails - number of unsuccessful steps attempted

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

574:    Level: intermediate

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

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

592: /*@
593:    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
594:    attempted by the nonlinear solver before it gives up.

596:    Not Collective

598:    Input Parameters:
599: +  snes     - SNES context
600: -  maxFails - maximum of unsuccessful steps

602:    Level: intermediate

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

606: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
607:           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
608: @*/
609: PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
610: {
613:   snes->maxFailures = maxFails;
614:   return(0);
615: }

619: /*@
620:    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
621:    attempted by the nonlinear solver before it gives up.

623:    Not Collective

625:    Input Parameter:
626: .  snes     - SNES context

628:    Output Parameter:
629: .  maxFails - maximum of unsuccessful steps

631:    Level: intermediate

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

635: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
636:           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
637:  
638: @*/
639: PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
640: {
644:   *maxFails = snes->maxFailures;
645:   return(0);
646: }

650: /*@
651:    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
652:      done by SNES.

654:    Not Collective

656:    Input Parameter:
657: .  snes     - SNES context

659:    Output Parameter:
660: .  nfuncs - number of evaluations

662:    Level: intermediate

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

666: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
667: @*/
668: PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
669: {
673:   *nfuncs = snes->nfuncs;
674:   return(0);
675: }

679: /*@
680:    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
681:    linear solvers.

683:    Not Collective

685:    Input Parameter:
686: .  snes - SNES context

688:    Output Parameter:
689: .  nfails - number of failed solves

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

694:    Level: intermediate

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

698: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
699: @*/
700: PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
701: {
705:   *nfails = snes->numLinearSolveFailures;
706:   return(0);
707: }

711: /*@
712:    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
713:    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE

715:    Collective on SNES

717:    Input Parameters:
718: +  snes     - SNES context
719: -  maxFails - maximum allowed linear solve failures

721:    Level: intermediate

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

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

727: .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
728: @*/
729: PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
730: {
733:   snes->maxLinearSolveFailures = maxFails;
734:   return(0);
735: }

739: /*@
740:    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
741:      are allowed before SNES terminates

743:    Not Collective

745:    Input Parameter:
746: .  snes     - SNES context

748:    Output Parameter:
749: .  maxFails - maximum of unsuccessful solves allowed

751:    Level: intermediate

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

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

757: .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
758: @*/
759: PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
760: {
764:   *maxFails = snes->maxLinearSolveFailures;
765:   return(0);
766: }

770: /*@
771:    SNESGetLinearSolveIterations - Gets the total number of linear iterations
772:    used by the nonlinear solver.

774:    Not Collective

776:    Input Parameter:
777: .  snes - SNES context

779:    Output Parameter:
780: .  lits - number of linear iterations

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

785:    Level: intermediate

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

789: .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
790: @*/
791: PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
792: {
796:   *lits = snes->linear_its;
797:   return(0);
798: }

802: /*@
803:    SNESGetKSP - Returns the KSP context for a SNES solver.

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

807:    Input Parameter:
808: .  snes - the SNES context

810:    Output Parameter:
811: .  ksp - the KSP context

813:    Notes:
814:    The user can then directly manipulate the KSP context to set various
815:    options, etc.  Likewise, the user can then extract and manipulate the 
816:    PC contexts as well.

818:    Level: beginner

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

822: .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
823: @*/
824: PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
825: {


832:   if (!snes->ksp) {
833:     KSPCreate(((PetscObject)snes)->comm,&snes->ksp);
834:     PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);
835:     PetscLogObjectParent(snes,snes->ksp);
836:   }
837:   *ksp = snes->ksp;
838:   return(0);
839: }

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

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

848:    Input Parameters:
849: +  snes - the SNES context
850: -  ksp - the KSP context

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

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

859:    Level: developer

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

863: .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
864: @*/
865: PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
866: {

873:   PetscObjectReference((PetscObject)ksp);
874:   if (snes->ksp) {PetscObjectDereference((PetscObject)snes->ksp);}
875:   snes->ksp = ksp;
876:   return(0);
877: }

879: #if 0
882: static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
883: {
885:   return(0);
886: }
887: #endif

889: /* -----------------------------------------------------------*/
892: /*@
893:    SNESCreate - Creates a nonlinear solver context.

895:    Collective on MPI_Comm

897:    Input Parameters:
898: .  comm - MPI communicator

900:    Output Parameter:
901: .  outsnes - the new SNES context

903:    Options Database Keys:
904: +   -snes_mf - Activates default matrix-free Jacobian-vector products,
905:                and no preconditioning matrix
906: .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
907:                products, and a user-provided preconditioning matrix
908:                as set by SNESSetJacobian()
909: -   -snes_fd - Uses (slow!) finite differences to compute Jacobian

911:    Level: beginner

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

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

917: @*/
918: PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
919: {
920:   PetscErrorCode      ierr;
921:   SNES                snes;
922:   SNESKSPEW           *kctx;

926:   *outsnes = PETSC_NULL;
927: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
928:   SNESInitializePackage(PETSC_NULL);
929: #endif

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

933:   snes->ops->converged    = SNESDefaultConverged;
934:   snes->max_its           = 50;
935:   snes->max_funcs          = 10000;
936:   snes->norm                  = 0.0;
937:   snes->rtol                  = 1.e-8;
938:   snes->ttol              = 0.0;
939:   snes->abstol                  = 1.e-50;
940:   snes->xtol                  = 1.e-8;
941:   snes->deltatol          = 1.e-12;
942:   snes->nfuncs            = 0;
943:   snes->numFailures       = 0;
944:   snes->maxFailures       = 1;
945:   snes->linear_its        = 0;
946:   snes->lagjacobian       = 1;
947:   snes->lagpreconditioner = 1;
948:   snes->numbermonitors    = 0;
949:   snes->data              = 0;
950:   snes->setupcalled       = PETSC_FALSE;
951:   snes->ksp_ewconv        = PETSC_FALSE;
952:   snes->vwork             = 0;
953:   snes->nwork             = 0;
954:   snes->conv_hist_len     = 0;
955:   snes->conv_hist_max     = 0;
956:   snes->conv_hist         = PETSC_NULL;
957:   snes->conv_hist_its     = PETSC_NULL;
958:   snes->conv_hist_reset   = PETSC_TRUE;
959:   snes->reason            = SNES_CONVERGED_ITERATING;

961:   snes->numLinearSolveFailures = 0;
962:   snes->maxLinearSolveFailures = 1;

964:   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
965:   PetscNewLog(snes,SNESKSPEW,&kctx);
966:   snes->kspconvctx  = (void*)kctx;
967:   kctx->version     = 2;
968:   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 
969:                              this was too large for some test cases */
970:   kctx->rtol_last   = 0.0;
971:   kctx->rtol_max    = .9;
972:   kctx->gamma       = 1.0;
973:   kctx->alpha       = .5*(1.0 + sqrt(5.0));
974:   kctx->alpha2      = kctx->alpha;
975:   kctx->threshold   = .1;
976:   kctx->lresid_last = 0.0;
977:   kctx->norm_last   = 0.0;

979:   *outsnes = snes;
980:   PetscPublishAll(snes);
981:   return(0);
982: }

986: /*@C
987:    SNESSetFunction - Sets the function evaluation routine and function 
988:    vector for use by the SNES routines in solving systems of nonlinear
989:    equations.

991:    Collective on SNES

993:    Input Parameters:
994: +  snes - the SNES context
995: .  r - vector to store function value
996: .  func - function evaluation routine
997: -  ctx - [optional] user-defined context for private data for the 
998:          function evaluation routine (may be PETSC_NULL)

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

1003: .  f - function vector
1004: -  ctx - optional user-defined function context 

1006:    Notes:
1007:    The Newton-like methods typically solve linear systems of the form
1008: $      f'(x) x = -f(x),
1009:    where f'(x) denotes the Jacobian matrix and f(x) is the function.

1011:    Level: beginner

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

1015: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1016: @*/
1017: PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
1018: {
1024:   PetscObjectReference((PetscObject)r);
1025:   if (snes->vec_func) { VecDestroy(snes->vec_func); }
1026:   snes->ops->computefunction = func;
1027:   snes->vec_func             = r;
1028:   snes->funP                 = ctx;
1029:   return(0);
1030: }

1032: /* --------------------------------------------------------------- */
1035: /*@C
1036:    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
1037:    it assumes a zero right hand side.

1039:    Collective on SNES

1041:    Input Parameter:
1042: .  snes - the SNES context

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

1047:    Level: intermediate

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

1051: .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
1052: @*/
1053: PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
1054: {
1058:   *rhs = snes->vec_rhs;
1059:   return(0);
1060: }

1064: /*@
1065:    SNESComputeFunction - Calls the function that has been set with
1066:                          SNESSetFunction().  

1068:    Collective on SNES

1070:    Input Parameters:
1071: +  snes - the SNES context
1072: -  x - input vector

1074:    Output Parameter:
1075: .  y - function vector, as set by SNESSetFunction()

1077:    Notes:
1078:    SNESComputeFunction() is typically used within nonlinear solvers
1079:    implementations, so most users would not generally call this routine
1080:    themselves.

1082:    Level: developer

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

1086: .seealso: SNESSetFunction(), SNESGetFunction()
1087: @*/
1088: PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
1089: {


1099:   PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);
1100:   if (snes->ops->computefunction) {
1101:     PetscStackPush("SNES user function");
1102:     CHKMEMQ;
1103:     (*snes->ops->computefunction)(snes,x,y,snes->funP);
1104:     CHKMEMQ;
1105:     PetscStackPop;
1106:     if (PetscExceptionValue(ierr)) {
1107:       PetscErrorCode pPetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(pierr);
1108:     }
1109: 
1110:   } else if (snes->vec_rhs) {
1111:     MatMult(snes->jacobian, x, y);
1112:   } else {
1113:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() before SNESComputeFunction(), likely called from SNESSolve().");
1114:   }
1115:   if (snes->vec_rhs) {
1116:     VecAXPY(y,-1.0,snes->vec_rhs);
1117:   }
1118:   snes->nfuncs++;
1119:   PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);
1120:   return(0);
1121: }

1125: /*@
1126:    SNESComputeJacobian - Computes the Jacobian matrix that has been
1127:    set with SNESSetJacobian().

1129:    Collective on SNES and Mat

1131:    Input Parameters:
1132: +  snes - the SNES context
1133: -  x - input vector

1135:    Output Parameters:
1136: +  A - Jacobian matrix
1137: .  B - optional preconditioning matrix
1138: -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)

1140:   Options Database Keys: 
1141: +    -snes_lag_preconditioner <lag>
1142: -    -snes_lag_jacobian <lag>

1144:    Notes: 
1145:    Most users should not need to explicitly call this routine, as it 
1146:    is used internally within the nonlinear solvers. 

1148:    See KSPSetOperators() for important information about setting the
1149:    flag parameter.

1151:    Level: developer

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

1155: .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
1156: @*/
1157: PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
1158: {
1160:   PetscTruth     flag;

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

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

1171:   if (snes->lagjacobian == -2) {
1172:     snes->lagjacobian = -1;
1173:     PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");
1174:   } else if (snes->lagjacobian == -1) {
1175:     *flg = SAME_PRECONDITIONER;
1176:     PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");
1177:     PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);
1178:     if (flag) {
1179:       MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);
1180:       MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);
1181:     }
1182:     return(0);
1183:   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
1184:     *flg = SAME_PRECONDITIONER;
1185:     PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);
1186:     PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);
1187:     if (flag) {
1188:       MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);
1189:       MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);
1190:     }
1191:     return(0);
1192:   }

1194:   *flg = DIFFERENT_NONZERO_PATTERN;
1195:   PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);
1196:   PetscStackPush("SNES user Jacobian function");
1197:   CHKMEMQ;
1198:   (*snes->ops->computejacobian)(snes,X,A,B,flg,snes->jacP);
1199:   CHKMEMQ;
1200:   PetscStackPop;
1201:   PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);

1203:   if (snes->lagpreconditioner == -2) {
1204:     PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");
1205:     snes->lagpreconditioner = -1;
1206:   } else if (snes->lagpreconditioner == -1) {
1207:     *flg = SAME_PRECONDITIONER;
1208:     PetscInfo(snes,"Reusing preconditioner because lag is -1\n");
1209:   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
1210:     *flg = SAME_PRECONDITIONER;
1211:     PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);
1212:   }

1214:   /* make sure user returned a correct Jacobian and preconditioner */
1217:   return(0);
1218: }

1222: /*@C
1223:    SNESSetJacobian - Sets the function to compute Jacobian as well as the
1224:    location to store the matrix.

1226:    Collective on SNES and Mat

1228:    Input Parameters:
1229: +  snes - the SNES context
1230: .  A - Jacobian matrix
1231: .  B - preconditioner matrix (usually same as the Jacobian)
1232: .  func - Jacobian evaluation routine
1233: -  ctx - [optional] user-defined context for private data for the 
1234:          Jacobian evaluation routine (may be PETSC_NULL)

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

1239: +  x - input vector
1240: .  A - Jacobian matrix
1241: .  B - preconditioner matrix, usually the same as A
1242: .  flag - flag indicating information about the preconditioner matrix
1243:    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
1244: -  ctx - [optional] user-defined Jacobian context

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

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

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

1259:    Level: beginner

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

1263: .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
1264: @*/
1265: PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
1266: {

1275:   if (func) snes->ops->computejacobian = func;
1276:   if (ctx)  snes->jacP                 = ctx;
1277:   if (A) {
1278:     PetscObjectReference((PetscObject)A);
1279:     if (snes->jacobian) {MatDestroy(snes->jacobian);}
1280:     snes->jacobian = A;
1281:   }
1282:   if (B) {
1283:     PetscObjectReference((PetscObject)B);
1284:     if (snes->jacobian_pre) {MatDestroy(snes->jacobian_pre);}
1285:     snes->jacobian_pre = B;
1286:   }
1287:   return(0);
1288: }

1292: /*@C
1293:    SNESGetJacobian - Returns the Jacobian matrix and optionally the user 
1294:    provided context for evaluating the Jacobian.

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

1298:    Input Parameter:
1299: .  snes - the nonlinear solver context

1301:    Output Parameters:
1302: +  A - location to stash Jacobian matrix (or PETSC_NULL)
1303: .  B - location to stash preconditioner matrix (or PETSC_NULL)
1304: .  func - location to put Jacobian function (or PETSC_NULL)
1305: -  ctx - location to stash Jacobian ctx (or PETSC_NULL)

1307:    Level: advanced

1309: .seealso: SNESSetJacobian(), SNESComputeJacobian()
1310: @*/
1311: PetscErrorCode  SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
1312: {
1315:   if (A)    *A    = snes->jacobian;
1316:   if (B)    *B    = snes->jacobian_pre;
1317:   if (func) *func = snes->ops->computejacobian;
1318:   if (ctx)  *ctx  = snes->jacP;
1319:   return(0);
1320: }

1322: /* ----- Routines to initialize and destroy a nonlinear solver ---- */

1326: /*@
1327:    SNESSetUp - Sets up the internal data structures for the later use
1328:    of a nonlinear solver.

1330:    Collective on SNES

1332:    Input Parameters:
1333: .  snes - the SNES context

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

1342:    Level: advanced

1344: .keywords: SNES, nonlinear, setup

1346: .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
1347: @*/
1348: PetscErrorCode  SNESSetUp(SNES snes)
1349: {

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

1356:   if (!((PetscObject)snes)->type_name) {
1357:     SNESSetType(snes,SNESLS);
1358:   }

1360:   if (!snes->vec_func && !snes->vec_rhs) {
1361:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
1362:   }
1363:   if (!snes->ops->computefunction && !snes->vec_rhs) {
1364:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
1365:   }
1366:   if (snes->vec_func == snes->vec_sol) {
1367:     SETERRQ(PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
1368:   }
1369: 
1370:   if (!snes->ksp) {SNESGetKSP(snes, &snes->ksp);}
1371: 
1372:   if (snes->ops->setup) {
1373:     (*snes->ops->setup)(snes);
1374:   }
1375:   snes->setupcalled = PETSC_TRUE;
1376:   return(0);
1377: }

1381: /*@
1382:    SNESDestroy - Destroys the nonlinear solver context that was created
1383:    with SNESCreate().

1385:    Collective on SNES

1387:    Input Parameter:
1388: .  snes - the SNES context

1390:    Level: beginner

1392: .keywords: SNES, nonlinear, destroy

1394: .seealso: SNESCreate(), SNESSolve()
1395: @*/
1396: PetscErrorCode  SNESDestroy(SNES snes)
1397: {

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

1404:   /* if memory was published with AMS then destroy it */
1405:   PetscObjectDepublish(snes);
1406:   if (snes->ops->destroy) {(*(snes)->ops->destroy)(snes);}
1407: 
1408:   if (snes->vec_rhs) {VecDestroy(snes->vec_rhs);}
1409:   if (snes->vec_sol) {VecDestroy(snes->vec_sol);}
1410:   if (snes->vec_func) {VecDestroy(snes->vec_func);}
1411:   if (snes->jacobian) {MatDestroy(snes->jacobian);}
1412:   if (snes->jacobian_pre) {MatDestroy(snes->jacobian_pre);}
1413:   if (snes->ksp) {KSPDestroy(snes->ksp);}
1414:   PetscFree(snes->kspconvctx);
1415:   if (snes->vwork) {VecDestroyVecs(snes->vwork,snes->nvwork);}
1416:   SNESMonitorCancel(snes);
1417:   if (snes->ops->convergeddestroy) {(*snes->ops->convergeddestroy)(snes->cnvP);}
1418:   PetscHeaderDestroy(snes);
1419:   return(0);
1420: }

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

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

1429:    Collective on SNES

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

1436:    Options Database Keys: 
1437: .    -snes_lag_preconditioner <lag>

1439:    Notes:
1440:    The default is 1
1441:    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1442:    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use

1444:    Level: intermediate

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

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

1450: @*/
1451: PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
1452: {
1455:   if (lag < -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
1456:   if (!lag) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
1457:   snes->lagpreconditioner = lag;
1458:   return(0);
1459: }

1463: /*@
1464:    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt

1466:    Collective on SNES

1468:    Input Parameter:
1469: .  snes - the SNES context
1470:  
1471:    Output Parameter:
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 indicates rebuild preconditioner at next chance but then never rebuild after that

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

1478:    Notes:
1479:    The default is 1
1480:    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1

1482:    Level: intermediate

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

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

1488: @*/
1489: PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
1490: {
1493:   *lag = snes->lagpreconditioner;
1494:   return(0);
1495: }

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

1503:    Collective on SNES

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

1510:    Options Database Keys: 
1511: .    -snes_lag_jacobian <lag>

1513:    Notes:
1514:    The default is 1
1515:    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1516:    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
1517:    at the next Newton step but never again (unless it is reset to another value)

1519:    Level: intermediate

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

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

1525: @*/
1526: PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
1527: {
1530:   if (lag < -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
1531:   if (!lag) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
1532:   snes->lagjacobian = lag;
1533:   return(0);
1534: }

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

1541:    Collective on SNES

1543:    Input Parameter:
1544: .  snes - the SNES context
1545:  
1546:    Output Parameter:
1547: .   lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
1548:          the Jacobian is built etc.

1550:    Options Database Keys: 
1551: .    -snes_lag_jacobian <lag>

1553:    Notes:
1554:    The default is 1
1555:    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1

1557:    Level: intermediate

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

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

1563: @*/
1564: PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
1565: {
1568:   *lag = snes->lagjacobian;
1569:   return(0);
1570: }

1574: /*@
1575:    SNESSetTolerances - Sets various parameters used in convergence tests.

1577:    Collective on SNES

1579:    Input Parameters:
1580: +  snes - the SNES context
1581: .  abstol - absolute convergence tolerance
1582: .  rtol - relative convergence tolerance
1583: .  stol -  convergence tolerance in terms of the norm
1584:            of the change in the solution between steps
1585: .  maxit - maximum number of iterations
1586: -  maxf - maximum number of function evaluations

1588:    Options Database Keys: 
1589: +    -snes_atol <abstol> - Sets abstol
1590: .    -snes_rtol <rtol> - Sets rtol
1591: .    -snes_stol <stol> - Sets stol
1592: .    -snes_max_it <maxit> - Sets maxit
1593: -    -snes_max_funcs <maxf> - Sets maxf

1595:    Notes:
1596:    The default maximum number of iterations is 50.
1597:    The default maximum number of function evaluations is 1000.

1599:    Level: intermediate

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

1603: .seealso: SNESSetTrustRegionTolerance()
1604: @*/
1605: PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
1606: {
1609:   if (abstol != PETSC_DEFAULT)  snes->abstol      = abstol;
1610:   if (rtol != PETSC_DEFAULT)  snes->rtol      = rtol;
1611:   if (stol != PETSC_DEFAULT)  snes->xtol      = stol;
1612:   if (maxit != PETSC_DEFAULT) snes->max_its   = maxit;
1613:   if (maxf != PETSC_DEFAULT)  snes->max_funcs = maxf;
1614:   return(0);
1615: }

1619: /*@
1620:    SNESGetTolerances - Gets various parameters used in convergence tests.

1622:    Not Collective

1624:    Input Parameters:
1625: +  snes - the SNES context
1626: .  atol - absolute convergence tolerance
1627: .  rtol - relative convergence tolerance
1628: .  stol -  convergence tolerance in terms of the norm
1629:            of the change in the solution between steps
1630: .  maxit - maximum number of iterations
1631: -  maxf - maximum number of function evaluations

1633:    Notes:
1634:    The user can specify PETSC_NULL for any parameter that is not needed.

1636:    Level: intermediate

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

1640: .seealso: SNESSetTolerances()
1641: @*/
1642: PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
1643: {
1646:   if (atol)  *atol  = snes->abstol;
1647:   if (rtol)  *rtol  = snes->rtol;
1648:   if (stol)  *stol  = snes->xtol;
1649:   if (maxit) *maxit = snes->max_its;
1650:   if (maxf)  *maxf  = snes->max_funcs;
1651:   return(0);
1652: }

1656: /*@
1657:    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.  

1659:    Collective on SNES

1661:    Input Parameters:
1662: +  snes - the SNES context
1663: -  tol - tolerance
1664:    
1665:    Options Database Key: 
1666: .  -snes_trtol <tol> - Sets tol

1668:    Level: intermediate

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

1672: .seealso: SNESSetTolerances()
1673: @*/
1674: PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
1675: {
1678:   snes->deltatol = tol;
1679:   return(0);
1680: }

1682: /* 
1683:    Duplicate the lg monitors for SNES from KSP; for some reason with 
1684:    dynamic libraries things don't work under Sun4 if we just use 
1685:    macros instead of functions
1686: */
1689: PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
1690: {

1695:   KSPMonitorLG((KSP)snes,it,norm,ctx);
1696:   return(0);
1697: }

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

1706:   KSPMonitorLGCreate(host,label,x,y,m,n,draw);
1707:   return(0);
1708: }

1712: PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG draw)
1713: {

1717:   KSPMonitorLGDestroy(draw);
1718:   return(0);
1719: }

1724: PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
1725: {
1726:   PetscDrawLG      lg;
1727:   PetscErrorCode   ierr;
1728:   PetscReal        x,y,per;
1729:   PetscViewer      v = (PetscViewer)monctx;
1730:   static PetscReal prev; /* should be in the context */
1731:   PetscDraw        draw;
1733:   if (!monctx) {
1734:     MPI_Comm    comm;

1736:     PetscObjectGetComm((PetscObject)snes,&comm);
1737:     v      = PETSC_VIEWER_DRAW_(comm);
1738:   }
1739:   PetscViewerDrawGetDrawLG(v,0,&lg);
1740:   if (!n) {PetscDrawLGReset(lg);}
1741:   PetscDrawLGGetDraw(lg,&draw);
1742:   PetscDrawSetTitle(draw,"Residual norm");
1743:   x = (PetscReal) n;
1744:   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
1745:   PetscDrawLGAddPoint(lg,&x,&y);
1746:   if (n < 20 || !(n % 5)) {
1747:     PetscDrawLGDraw(lg);
1748:   }

1750:   PetscViewerDrawGetDrawLG(v,1,&lg);
1751:   if (!n) {PetscDrawLGReset(lg);}
1752:   PetscDrawLGGetDraw(lg,&draw);
1753:   PetscDrawSetTitle(draw,"% elemts > .2*max elemt");
1754:    SNESMonitorRange_Private(snes,n,&per);
1755:   x = (PetscReal) n;
1756:   y = 100.0*per;
1757:   PetscDrawLGAddPoint(lg,&x,&y);
1758:   if (n < 20 || !(n % 5)) {
1759:     PetscDrawLGDraw(lg);
1760:   }

1762:   PetscViewerDrawGetDrawLG(v,2,&lg);
1763:   if (!n) {prev = rnorm;PetscDrawLGReset(lg);}
1764:   PetscDrawLGGetDraw(lg,&draw);
1765:   PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");
1766:   x = (PetscReal) n;
1767:   y = (prev - rnorm)/prev;
1768:   PetscDrawLGAddPoint(lg,&x,&y);
1769:   if (n < 20 || !(n % 5)) {
1770:     PetscDrawLGDraw(lg);
1771:   }

1773:   PetscViewerDrawGetDrawLG(v,3,&lg);
1774:   if (!n) {PetscDrawLGReset(lg);}
1775:   PetscDrawLGGetDraw(lg,&draw);
1776:   PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");
1777:   x = (PetscReal) n;
1778:   y = (prev - rnorm)/(prev*per);
1779:   if (n > 2) { /*skip initial crazy value */
1780:     PetscDrawLGAddPoint(lg,&x,&y);
1781:   }
1782:   if (n < 20 || !(n % 5)) {
1783:     PetscDrawLGDraw(lg);
1784:   }
1785:   prev = rnorm;
1786:   return(0);
1787: }

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

1796:   KSPMonitorLGCreate(host,label,x,y,m,n,draw);
1797:   return(0);
1798: }

1802: PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG draw)
1803: {

1807:   KSPMonitorLGDestroy(draw);
1808:   return(0);
1809: }

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

1815: /*@C
1816:    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
1817:    iteration of the nonlinear solver to display the iteration's 
1818:    progress.   

1820:    Collective on SNES

1822:    Input Parameters:
1823: +  snes - the SNES context
1824: .  func - monitoring routine
1825: .  mctx - [optional] user-defined context for private data for the 
1826:           monitor routine (use PETSC_NULL if no context is desired)
1827: -  monitordestroy - [optional] routine that frees monitor context
1828:           (may be PETSC_NULL)

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

1833: +    snes - the SNES context
1834: .    its - iteration number
1835: .    norm - 2-norm function value (may be estimated)
1836: -    mctx - [optional] monitoring context

1838:    Options Database Keys:
1839: +    -snes_monitor        - sets SNESMonitorDefault()
1840: .    -snes_monitor_draw    - sets line graph monitor,
1841:                             uses SNESMonitorLGCreate()
1842: _    -snes_monitor_cancel - cancels all monitors that have
1843:                             been hardwired into a code by 
1844:                             calls to SNESMonitorSet(), but
1845:                             does not cancel those set via
1846:                             the options database.

1848:    Notes: 
1849:    Several different monitoring routines may be set by calling
1850:    SNESMonitorSet() multiple times; all will be called in the 
1851:    order in which they were set.

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

1855:    Level: intermediate

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

1859: .seealso: SNESMonitorDefault(), SNESMonitorCancel()
1860: @*/
1861: PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void*))
1862: {
1863:   PetscInt i;

1867:   if (snes->numbermonitors >= MAXSNESMONITORS) {
1868:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
1869:   }
1870:   for (i=0; i<snes->numbermonitors;i++) {
1871:     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) return(0);

1873:     /* check if both default monitors that share common ASCII viewer */
1874:     if (monitor == snes->monitor[i] && monitor == SNESMonitorDefault) {
1875:       if (mctx && snes->monitorcontext[i]) {
1876:         PetscErrorCode          ierr;
1877:         PetscViewerASCIIMonitor viewer1 = (PetscViewerASCIIMonitor) mctx;
1878:         PetscViewerASCIIMonitor viewer2 = (PetscViewerASCIIMonitor) snes->monitorcontext[i];
1879:         if (viewer1->viewer == viewer2->viewer) {
1880:           (*monitordestroy)(mctx);
1881:           return(0);
1882:         }
1883:       }
1884:     }
1885:   }
1886:   snes->monitor[snes->numbermonitors]           = monitor;
1887:   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
1888:   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
1889:   return(0);
1890: }

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

1897:    Collective on SNES

1899:    Input Parameters:
1900: .  snes - the SNES context

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

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

1910:    Level: intermediate

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

1914: .seealso: SNESMonitorDefault(), SNESMonitorSet()
1915: @*/
1916: PetscErrorCode  SNESMonitorCancel(SNES snes)
1917: {
1919:   PetscInt       i;

1923:   for (i=0; i<snes->numbermonitors; i++) {
1924:     if (snes->monitordestroy[i]) {
1925:       (*snes->monitordestroy[i])(snes->monitorcontext[i]);
1926:     }
1927:   }
1928:   snes->numbermonitors = 0;
1929:   return(0);
1930: }

1934: /*@C
1935:    SNESSetConvergenceTest - Sets the function that is to be used 
1936:    to test for convergence of the nonlinear iterative solution.   

1938:    Collective on SNES

1940:    Input Parameters:
1941: +  snes - the SNES context
1942: .  func - routine to test for convergence
1943: .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
1944: -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)

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

1949: +    snes - the SNES context
1950: .    it - current iteration (0 is the first and is before any Newton step)
1951: .    cctx - [optional] convergence context
1952: .    reason - reason for convergence/divergence
1953: .    xnorm - 2-norm of current iterate
1954: .    gnorm - 2-norm of current step
1955: -    f - 2-norm of function

1957:    Level: advanced

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

1961: .seealso: SNESDefaultConverged(), SNESSkipConverged()
1962: @*/
1963: PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
1964: {

1969:   if (!func) func = SNESSkipConverged;
1970:   if (snes->ops->convergeddestroy) {
1971:     (*snes->ops->convergeddestroy)(snes->cnvP);
1972:   }
1973:   snes->ops->converged        = func;
1974:   snes->ops->convergeddestroy = destroy;
1975:   snes->cnvP                  = cctx;
1976:   return(0);
1977: }

1981: /*@
1982:    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.

1984:    Not Collective

1986:    Input Parameter:
1987: .  snes - the SNES context

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

1993:    Level: intermediate

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

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

1999: .seealso: SNESSetConvergenceTest(), SNESConvergedReason
2000: @*/
2001: PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
2002: {
2006:   *reason = snes->reason;
2007:   return(0);
2008: }

2012: /*@
2013:    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.

2015:    Collective on SNES

2017:    Input Parameters:
2018: +  snes - iterative context obtained from SNESCreate()
2019: .  a   - array to hold history, this array will contain the function norms computed at each step
2020: .  its - integer array holds the number of linear iterations for each solve.
2021: .  na  - size of a and its
2022: -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
2023:            else it continues storing new values for new nonlinear solves after the old ones

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

2029:    Level: intermediate

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

2033: .seealso: SNESGetConvergenceHistory()

2035: @*/
2036: PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscTruth reset)
2037: {
2042:   snes->conv_hist       = a;
2043:   snes->conv_hist_its   = its;
2044:   snes->conv_hist_max   = na;
2045:   snes->conv_hist_len   = 0;
2046:   snes->conv_hist_reset = reset;
2047:   return(0);
2048: }

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

2055:    Collective on SNES

2057:    Input Parameter:
2058: .  snes - iterative context obtained from SNESCreate()

2060:    Output Parameters:
2061: .  a   - array to hold history
2062: .  its - integer array holds the number of linear iterations (or
2063:          negative if not converged) for each solve.
2064: -  na  - size of a and its

2066:    Notes:
2067:     The calling sequence for this routine in Fortran is
2068: $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)

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

2074:    Level: intermediate

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

2078: .seealso: SNESSetConvergencHistory()

2080: @*/
2081: PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
2082: {
2085:   if (a)   *a   = snes->conv_hist;
2086:   if (its) *its = snes->conv_hist_its;
2087:   if (na)  *na  = snes->conv_hist_len;
2088:   return(0);
2089: }

2093: /*@C
2094:   SNESSetUpdate - Sets the general-purpose update function called
2095:   at the beginning o every iteration of the nonlinear solve. Specifically
2096:   it is called just before the Jacobian is "evaluated".

2098:   Collective on SNES

2100:   Input Parameters:
2101: . snes - The nonlinear solver context
2102: . func - The function

2104:   Calling sequence of func:
2105: . func (SNES snes, PetscInt step);

2107: . step - The current step of the iteration

2109:   Level: advanced

2111:   Note: This is NOT what one uses to update the ghost points before a function evaluation, that should be done at the beginning of your FormFunction()
2112:         This is not used by most users.

2114: .keywords: SNES, update

2116: .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
2117: @*/
2118: PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
2119: {
2122:   snes->ops->update = func;
2123:   return(0);
2124: }

2128: /*@
2129:   SNESDefaultUpdate - The default update function which does nothing.

2131:   Not collective

2133:   Input Parameters:
2134: . snes - The nonlinear solver context
2135: . step - The current step of the iteration

2137:   Level: intermediate

2139: .keywords: SNES, update
2140: .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
2141: @*/
2142: PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
2143: {
2145:   return(0);
2146: }

2150: /*
2151:    SNESScaleStep_Private - Scales a step so that its length is less than the
2152:    positive parameter delta.

2154:     Input Parameters:
2155: +   snes - the SNES context
2156: .   y - approximate solution of linear system
2157: .   fnorm - 2-norm of current function
2158: -   delta - trust region size

2160:     Output Parameters:
2161: +   gpnorm - predicted function norm at the new point, assuming local 
2162:     linearization.  The value is zero if the step lies within the trust 
2163:     region, and exceeds zero otherwise.
2164: -   ynorm - 2-norm of the step

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

2170: .keywords: SNES, nonlinear, scale, step
2171: */
2172: PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
2173: {
2174:   PetscReal      nrm;
2175:   PetscScalar    cnorm;


2183:   VecNorm(y,NORM_2,&nrm);
2184:   if (nrm > *delta) {
2185:      nrm = *delta/nrm;
2186:      *gpnorm = (1.0 - nrm)*(*fnorm);
2187:      cnorm = nrm;
2188:      VecScale(y,cnorm);
2189:      *ynorm = *delta;
2190:   } else {
2191:      *gpnorm = 0.0;
2192:      *ynorm = nrm;
2193:   }
2194:   return(0);
2195: }

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

2203:    Collective on SNES

2205:    Input Parameters:
2206: +  snes - the SNES context
2207: .  b - the constant part of the equation, or PETSC_NULL to use zero.
2208: -  x - the solution vector.

2210:    Notes:
2211:    The user should initialize the vector,x, with the initial guess
2212:    for the nonlinear solve prior to calling SNESSolve.  In particular,
2213:    to employ an initial guess of zero, the user should explicitly set
2214:    this vector to zero by calling VecSet().

2216:    Level: beginner

2218: .keywords: SNES, nonlinear, solve

2220: .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian()
2221: @*/
2222: PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
2223: {
2225:   PetscTruth     flg;
2226:   char           filename[PETSC_MAX_PATH_LEN];
2227:   PetscViewer    viewer;


2236:   /* set solution vector */
2237:   PetscObjectReference((PetscObject)x);
2238:   if (snes->vec_sol) { VecDestroy(snes->vec_sol); }
2239:   snes->vec_sol = x;
2240:   /* set afine vector if provided */
2241:   if (b) { PetscObjectReference((PetscObject)b); }
2242:   if (snes->vec_rhs) { VecDestroy(snes->vec_rhs); }
2243:   snes->vec_rhs = b;
2244: 
2245:   if (!snes->vec_func && snes->vec_rhs) {
2246:     VecDuplicate(b, &snes->vec_func);
2247:   }

2249:   SNESSetUp(snes);

2251:   if (snes->conv_hist_reset) snes->conv_hist_len = 0;
2252:   snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;

2254:   PetscLogEventBegin(SNES_Solve,snes,0,0,0);
2255:   (*snes->ops->solve)(snes);
2256:   PetscLogEventEnd(SNES_Solve,snes,0,0,0);
2257:   if (snes->domainerror){
2258:     snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
2259:     snes->domainerror = PETSC_FALSE;
2260:   }

2262:   if (!snes->reason) {
2263:     SETERRQ(PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
2264:   }
2265: 
2266:   PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);
2267:   if (flg && !PetscPreLoadingOn) {
2268:     PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);
2269:     SNESView(snes,viewer);
2270:     PetscViewerDestroy(viewer);
2271:   }

2273:   flg  = PETSC_FALSE;
2274:   PetscOptionsGetTruth(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);
2275:   if (flg && !PetscPreLoadingOn) { SNESTestLocalMin(snes); }
2276:   if (snes->printreason) {
2277:     if (snes->reason > 0) {
2278:       PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);
2279:     } else {
2280:       PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);
2281:     }
2282:   }

2284:   return(0);
2285: }

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

2291: /*@C
2292:    SNESSetType - Sets the method for the nonlinear solver.  

2294:    Collective on SNES

2296:    Input Parameters:
2297: +  snes - the SNES context
2298: -  type - a known method

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

2304:    Notes:
2305:    See "petsc/include/petscsnes.h" for available methods (for instance)
2306: +    SNESLS - Newton's method with line search
2307:      (systems of nonlinear equations)
2308: .    SNESTR - Newton's method with trust region
2309:      (systems of nonlinear equations)

2311:   Normally, it is best to use the SNESSetFromOptions() command and then
2312:   set the SNES solver type from the options database rather than by using
2313:   this routine.  Using the options database provides the user with
2314:   maximum flexibility in evaluating the many nonlinear solvers.
2315:   The SNESSetType() routine is provided for those situations where it
2316:   is necessary to set the nonlinear solver independently of the command
2317:   line or options database.  This might be the case, for example, when
2318:   the choice of solver changes during the execution of the program,
2319:   and the user's application is taking responsibility for choosing the
2320:   appropriate method.

2322:   Level: intermediate

2324: .keywords: SNES, set, type

2326: .seealso: SNESType, SNESCreate()

2328: @*/
2329: PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
2330: {
2331:   PetscErrorCode ierr,(*r)(SNES);
2332:   PetscTruth     match;


2338:   PetscTypeCompare((PetscObject)snes,type,&match);
2339:   if (match) return(0);

2341:    PetscFListFind(SNESList,((PetscObject)snes)->comm,type,(void (**)(void)) &r);
2342:   if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
2343:   /* Destroy the previous private SNES context */
2344:   if (snes->ops->destroy) { (*(snes)->ops->destroy)(snes); }
2345:   /* Reinitialize function pointers in SNESOps structure */
2346:   snes->ops->setup          = 0;
2347:   snes->ops->solve          = 0;
2348:   snes->ops->view           = 0;
2349:   snes->ops->setfromoptions = 0;
2350:   snes->ops->destroy        = 0;
2351:   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
2352:   snes->setupcalled = PETSC_FALSE;
2353:   (*r)(snes);
2354:   PetscObjectChangeTypeName((PetscObject)snes,type);
2355:   return(0);
2356: }


2359: /* --------------------------------------------------------------------- */
2362: /*@
2363:    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
2364:    registered by SNESRegisterDynamic().

2366:    Not Collective

2368:    Level: advanced

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

2372: .seealso: SNESRegisterAll(), SNESRegisterAll()
2373: @*/
2374: PetscErrorCode  SNESRegisterDestroy(void)
2375: {

2379:   PetscFListDestroy(&SNESList);
2380:   SNESRegisterAllCalled = PETSC_FALSE;
2381:   return(0);
2382: }

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

2389:    Not Collective

2391:    Input Parameter:
2392: .  snes - nonlinear solver context

2394:    Output Parameter:
2395: .  type - SNES method (a character string)

2397:    Level: intermediate

2399: .keywords: SNES, nonlinear, get, type, name
2400: @*/
2401: PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
2402: {
2406:   *type = ((PetscObject)snes)->type_name;
2407:   return(0);
2408: }

2412: /*@
2413:    SNESGetSolution - Returns the vector where the approximate solution is
2414:    stored.

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

2418:    Input Parameter:
2419: .  snes - the SNES context

2421:    Output Parameter:
2422: .  x - the solution

2424:    Level: intermediate

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

2428: .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
2429: @*/
2430: PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
2431: {
2435:   *x = snes->vec_sol;
2436:   return(0);
2437: }

2441: /*@
2442:    SNESGetSolutionUpdate - Returns the vector where the solution update is
2443:    stored. 

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

2447:    Input Parameter:
2448: .  snes - the SNES context

2450:    Output Parameter:
2451: .  x - the solution update

2453:    Level: advanced

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

2457: .seealso: SNESGetSolution(), SNESGetFunction()
2458: @*/
2459: PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
2460: {
2464:   *x = snes->vec_sol_update;
2465:   return(0);
2466: }

2470: /*@C
2471:    SNESGetFunction - Returns the vector where the function is stored.

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

2475:    Input Parameter:
2476: .  snes - the SNES context

2478:    Output Parameter:
2479: +  r - the function (or PETSC_NULL)
2480: .  func - the function (or PETSC_NULL)
2481: -  ctx - the function context (or PETSC_NULL)

2483:    Level: advanced

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

2487: .seealso: SNESSetFunction(), SNESGetSolution()
2488: @*/
2489: PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
2490: {
2493:   if (r)    *r    = snes->vec_func;
2494:   if (func) *func = snes->ops->computefunction;
2495:   if (ctx)  *ctx  = snes->funP;
2496:   return(0);
2497: }

2501: /*@C
2502:    SNESSetOptionsPrefix - Sets the prefix used for searching for all 
2503:    SNES options in the database.

2505:    Collective on SNES

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

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

2515:    Level: advanced

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

2519: .seealso: SNESSetFromOptions()
2520: @*/
2521: PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
2522: {

2527:   PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);
2528:   if (!snes->ksp) {SNESGetKSP(snes,&snes->ksp);}
2529:   KSPSetOptionsPrefix(snes->ksp,prefix);
2530:   return(0);
2531: }

2535: /*@C
2536:    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 
2537:    SNES options in the database.

2539:    Collective on SNES

2541:    Input Parameters:
2542: +  snes - the SNES context
2543: -  prefix - the prefix to prepend to all option names

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

2549:    Level: advanced

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

2553: .seealso: SNESGetOptionsPrefix()
2554: @*/
2555: PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
2556: {
2558: 
2561:   PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);
2562:   if (!snes->ksp) {SNESGetKSP(snes,&snes->ksp);}
2563:   KSPAppendOptionsPrefix(snes->ksp,prefix);
2564:   return(0);
2565: }

2569: /*@C
2570:    SNESGetOptionsPrefix - Sets the prefix used for searching for all 
2571:    SNES options in the database.

2573:    Not Collective

2575:    Input Parameter:
2576: .  snes - the SNES context

2578:    Output Parameter:
2579: .  prefix - pointer to the prefix string used

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

2584:    Level: advanced

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

2588: .seealso: SNESAppendOptionsPrefix()
2589: @*/
2590: PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
2591: {

2596:   PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);
2597:   return(0);
2598: }


2603: /*@C
2604:   SNESRegister - See SNESRegisterDynamic()

2606:   Level: advanced
2607: @*/
2608: PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
2609: {
2610:   char           fullname[PETSC_MAX_PATH_LEN];

2614:   PetscFListConcat(path,name,fullname);
2615:   PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);
2616:   return(0);
2617: }

2621: PetscErrorCode  SNESTestLocalMin(SNES snes)
2622: {
2624:   PetscInt       N,i,j;
2625:   Vec            u,uh,fh;
2626:   PetscScalar    value;
2627:   PetscReal      norm;

2630:   SNESGetSolution(snes,&u);
2631:   VecDuplicate(u,&uh);
2632:   VecDuplicate(u,&fh);

2634:   /* currently only works for sequential */
2635:   PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
2636:   VecGetSize(u,&N);
2637:   for (i=0; i<N; i++) {
2638:     VecCopy(u,uh);
2639:     PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);
2640:     for (j=-10; j<11; j++) {
2641:       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
2642:       VecSetValue(uh,i,value,ADD_VALUES);
2643:       SNESComputeFunction(snes,uh,fh);
2644:       VecNorm(fh,NORM_2,&norm);
2645:       PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);
2646:       value = -value;
2647:       VecSetValue(uh,i,value,ADD_VALUES);
2648:     }
2649:   }
2650:   VecDestroy(uh);
2651:   VecDestroy(fh);
2652:   return(0);
2653: }

2657: /*@
2658:    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
2659:    computing relative tolerance for linear solvers within an inexact
2660:    Newton method.

2662:    Collective on SNES

2664:    Input Parameters:
2665: +  snes - SNES context
2666: -  flag - PETSC_TRUE or PETSC_FALSE

2668:     Options Database:
2669: +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
2670: .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
2671: .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
2672: .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
2673: .  -snes_ksp_ew_gamma <gamma> - Sets gamma
2674: .  -snes_ksp_ew_alpha <alpha> - Sets alpha
2675: .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 
2676: -  -snes_ksp_ew_threshold <threshold> - Sets threshold

2678:    Notes:
2679:    Currently, the default is to use a constant relative tolerance for 
2680:    the inner linear solvers.  Alternatively, one can use the 
2681:    Eisenstat-Walker method, where the relative convergence tolerance 
2682:    is reset at each Newton iteration according progress of the nonlinear 
2683:    solver. 

2685:    Level: advanced

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

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

2693: .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
2694: @*/
2695: PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscTruth flag)
2696: {
2699:   snes->ksp_ewconv = flag;
2700:   return(0);
2701: }

2705: /*@
2706:    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
2707:    for computing relative tolerance for linear solvers within an
2708:    inexact Newton method.

2710:    Not Collective

2712:    Input Parameter:
2713: .  snes - SNES context

2715:    Output Parameter:
2716: .  flag - PETSC_TRUE or PETSC_FALSE

2718:    Notes:
2719:    Currently, the default is to use a constant relative tolerance for 
2720:    the inner linear solvers.  Alternatively, one can use the 
2721:    Eisenstat-Walker method, where the relative convergence tolerance 
2722:    is reset at each Newton iteration according progress of the nonlinear 
2723:    solver. 

2725:    Level: advanced

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

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

2733: .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
2734: @*/
2735: PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscTruth *flag)
2736: {
2740:   *flag = snes->ksp_ewconv;
2741:   return(0);
2742: }

2746: /*@
2747:    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
2748:    convergence criteria for the linear solvers within an inexact
2749:    Newton method.

2751:    Collective on SNES
2752:  
2753:    Input Parameters:
2754: +    snes - SNES context
2755: .    version - version 1, 2 (default is 2) or 3
2756: .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
2757: .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
2758: .    gamma - multiplicative factor for version 2 rtol computation
2759:              (0 <= gamma2 <= 1)
2760: .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
2761: .    alpha2 - power for safeguard
2762: -    threshold - threshold for imposing safeguard (0 < threshold < 1)

2764:    Note:
2765:    Version 3 was contributed by Luis Chacon, June 2006.

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

2769:    Level: advanced

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

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

2778: .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
2779: @*/
2780: PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
2781:                                                             PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
2782: {
2783:   SNESKSPEW *kctx;
2786:   kctx = (SNESKSPEW*)snes->kspconvctx;
2787:   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");

2789:   if (version != PETSC_DEFAULT)   kctx->version   = version;
2790:   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
2791:   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
2792:   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
2793:   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
2794:   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
2795:   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
2796: 
2797:   if (kctx->version < 1 || kctx->version > 3) {
2798:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
2799:   }
2800:   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
2801:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
2802:   }
2803:   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
2804:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
2805:   }
2806:   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
2807:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
2808:   }
2809:   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
2810:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
2811:   }
2812:   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
2813:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
2814:   }
2815:   return(0);
2816: }

2820: /*@
2821:    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
2822:    convergence criteria for the linear solvers within an inexact
2823:    Newton method.

2825:    Not Collective
2826:  
2827:    Input Parameters:
2828:      snes - SNES context

2830:    Output Parameters:
2831: +    version - version 1, 2 (default is 2) or 3
2832: .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
2833: .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
2834: .    gamma - multiplicative factor for version 2 rtol computation
2835:              (0 <= gamma2 <= 1)
2836: .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
2837: .    alpha2 - power for safeguard
2838: -    threshold - threshold for imposing safeguard (0 < threshold < 1)

2840:    Level: advanced

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

2844: .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
2845: @*/
2846: PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
2847:                                                             PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
2848: {
2849:   SNESKSPEW *kctx;
2852:   kctx = (SNESKSPEW*)snes->kspconvctx;
2853:   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
2854:   if(version)   *version   = kctx->version;
2855:   if(rtol_0)    *rtol_0    = kctx->rtol_0;
2856:   if(rtol_max)  *rtol_max  = kctx->rtol_max;
2857:   if(gamma)     *gamma     = kctx->gamma;
2858:   if(alpha)     *alpha     = kctx->alpha;
2859:   if(alpha2)    *alpha2    = kctx->alpha2;
2860:   if(threshold) *threshold = kctx->threshold;
2861:   return(0);
2862: }

2866: static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
2867: {
2869:   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
2870:   PetscReal      rtol=PETSC_DEFAULT,stol;

2873:   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
2874:   if (!snes->iter) { /* first time in, so use the original user rtol */
2875:     rtol = kctx->rtol_0;
2876:   } else {
2877:     if (kctx->version == 1) {
2878:       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
2879:       if (rtol < 0.0) rtol = -rtol;
2880:       stol = pow(kctx->rtol_last,kctx->alpha2);
2881:       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
2882:     } else if (kctx->version == 2) {
2883:       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
2884:       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
2885:       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
2886:     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
2887:       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
2888:       /* safeguard: avoid sharp decrease of rtol */
2889:       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
2890:       stol = PetscMax(rtol,stol);
2891:       rtol = PetscMin(kctx->rtol_0,stol);
2892:       /* safeguard: avoid oversolving */
2893:       stol = kctx->gamma*(snes->ttol)/snes->norm;
2894:       stol = PetscMax(rtol,stol);
2895:       rtol = PetscMin(kctx->rtol_0,stol);
2896:     } else SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
2897:   }
2898:   /* safeguard: avoid rtol greater than one */
2899:   rtol = PetscMin(rtol,kctx->rtol_max);
2900:   KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);
2901:   PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);
2902:   return(0);
2903: }

2907: static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
2908: {
2910:   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
2911:   PCSide         pcside;
2912:   Vec            lres;

2915:   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
2916:   KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);
2917:   SNESGetFunctionNorm(snes,&kctx->norm_last);
2918:   if (kctx->version == 1) {
2919:     KSPGetPreconditionerSide(ksp,&pcside);
2920:     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
2921:       /* KSP residual is true linear residual */
2922:       KSPGetResidualNorm(ksp,&kctx->lresid_last);
2923:     } else {
2924:       /* KSP residual is preconditioned residual */
2925:       /* compute true linear residual norm */
2926:       VecDuplicate(b,&lres);
2927:       MatMult(snes->jacobian,x,lres);
2928:       VecAYPX(lres,-1.0,b);
2929:       VecNorm(lres,NORM_2,&kctx->lresid_last);
2930:       VecDestroy(lres);
2931:     }
2932:   }
2933:   return(0);
2934: }

2938: PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
2939: {

2943:   if (snes->ksp_ewconv) { SNESKSPEW_PreSolve(snes,ksp,b,x);  }
2944:   KSPSolve(ksp,b,x);
2945:   if (snes->ksp_ewconv) { SNESKSPEW_PostSolve(snes,ksp,b,x); }
2946:   return(0);
2947: }