xref: /petsc/src/snes/interface/snes.c (revision fe97e370694949207a72f2d229e0cb264fc7a055)
163dd3a1aSKris Buschelman #define PETSCSNES_DLL
29b94acceSBarry Smith 
37c4f633dSBarry Smith #include "private/snesimpl.h"      /*I "petscsnes.h"  I*/
49b94acceSBarry Smith 
54c49b128SBarry Smith PetscTruth SNESRegisterAllCalled = PETSC_FALSE;
68ba1e511SMatthew Knepley PetscFList SNESList              = PETSC_NULL;
78ba1e511SMatthew Knepley 
88ba1e511SMatthew Knepley /* Logging support */
9166c7f25SBarry Smith PetscCookie PETSCSNES_DLLEXPORT SNES_COOKIE;
10166c7f25SBarry Smith PetscLogEvent  SNES_Solve, SNES_LineSearch, SNES_FunctionEval, SNES_JacobianEval;
11a09944afSBarry Smith 
12a09944afSBarry Smith #undef __FUNCT__
134936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError"
14e725d27bSBarry Smith /*@
154936397dSBarry Smith    SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not
164936397dSBarry Smith      in the functions domain. For example, negative pressure.
174936397dSBarry Smith 
184936397dSBarry Smith    Collective on SNES
194936397dSBarry Smith 
204936397dSBarry Smith    Input Parameters:
214936397dSBarry Smith .  SNES - the SNES context
224936397dSBarry Smith 
2328529972SSatish Balay    Level: advanced
244936397dSBarry Smith 
254936397dSBarry Smith .keywords: SNES, view
264936397dSBarry Smith 
274936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction()
284936397dSBarry Smith @*/
294936397dSBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESSetFunctionDomainError(SNES snes)
304936397dSBarry Smith {
314936397dSBarry Smith   PetscFunctionBegin;
324936397dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
334936397dSBarry Smith   snes->domainerror = PETSC_TRUE;
344936397dSBarry Smith   PetscFunctionReturn(0);
354936397dSBarry Smith }
364936397dSBarry Smith 
374936397dSBarry Smith #undef __FUNCT__
384a2ae208SSatish Balay #define __FUNCT__ "SNESView"
397e2c5f70SBarry Smith /*@C
409b94acceSBarry Smith    SNESView - Prints the SNES data structure.
419b94acceSBarry Smith 
424c49b128SBarry Smith    Collective on SNES
43fee21e36SBarry Smith 
44c7afd0dbSLois Curfman McInnes    Input Parameters:
45c7afd0dbSLois Curfman McInnes +  SNES - the SNES context
46c7afd0dbSLois Curfman McInnes -  viewer - visualization context
47c7afd0dbSLois Curfman McInnes 
489b94acceSBarry Smith    Options Database Key:
49c8a8ba5cSLois Curfman McInnes .  -snes_view - Calls SNESView() at end of SNESSolve()
509b94acceSBarry Smith 
519b94acceSBarry Smith    Notes:
529b94acceSBarry Smith    The available visualization contexts include
53b0a32e0cSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
54b0a32e0cSBarry Smith -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
55c8a8ba5cSLois Curfman McInnes          output where only the first processor opens
56c8a8ba5cSLois Curfman McInnes          the file.  All other processors send their
57c8a8ba5cSLois Curfman McInnes          data to the first processor to print.
589b94acceSBarry Smith 
593e081fefSLois Curfman McInnes    The user can open an alternative visualization context with
60b0a32e0cSBarry Smith    PetscViewerASCIIOpen() - output to a specified file.
619b94acceSBarry Smith 
6236851e7fSLois Curfman McInnes    Level: beginner
6336851e7fSLois Curfman McInnes 
649b94acceSBarry Smith .keywords: SNES, view
659b94acceSBarry Smith 
66b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen()
679b94acceSBarry Smith @*/
6863dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESView(SNES snes,PetscViewer viewer)
699b94acceSBarry Smith {
70fa9f3622SBarry Smith   SNESKSPEW           *kctx;
71dfbe8321SBarry Smith   PetscErrorCode      ierr;
7294b7f48cSBarry Smith   KSP                 ksp;
73a313700dSBarry Smith   const SNESType      type;
7432077d6dSBarry Smith   PetscTruth          iascii,isstring;
759b94acceSBarry Smith 
763a40ed3dSBarry Smith   PetscFunctionBegin;
774482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
783050cee2SBarry Smith   if (!viewer) {
797adad957SLisandro Dalcin     ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
803050cee2SBarry Smith   }
814482741eSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,2);
82c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,viewer,2);
8374679c65SBarry Smith 
8432077d6dSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
85b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);CHKERRQ(ierr);
8632077d6dSBarry Smith   if (iascii) {
877adad957SLisandro Dalcin     if (((PetscObject)snes)->prefix) {
887adad957SLisandro Dalcin       ierr = PetscViewerASCIIPrintf(viewer,"SNES Object:(%s)\n",((PetscObject)snes)->prefix);CHKERRQ(ierr);
893a7fca6bSBarry Smith     } else {
90b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"SNES Object:\n");CHKERRQ(ierr);
913a7fca6bSBarry Smith     }
92454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
93454a90a3SBarry Smith     if (type) {
94b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  type: %s\n",type);CHKERRQ(ierr);
95184914b5SBarry Smith     } else {
96b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  type: not set yet\n");CHKERRQ(ierr);
97184914b5SBarry Smith     }
98e7788613SBarry Smith     if (snes->ops->view) {
99b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
100e7788613SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
101b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1020ef38995SBarry Smith     }
10377431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr);
104a83599f4SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%G, absolute=%G, solution=%G\n",
10570441072SBarry Smith                  snes->rtol,snes->abstol,snes->xtol);CHKERRQ(ierr);
10677431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr);
10777431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr);
1089b94acceSBarry Smith     if (snes->ksp_ewconv) {
109fa9f3622SBarry Smith       kctx = (SNESKSPEW *)snes->kspconvctx;
1109b94acceSBarry Smith       if (kctx) {
11177431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr);
112a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr);
113a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr);
1149b94acceSBarry Smith       }
1159b94acceSBarry Smith     }
1160f5bd95cSBarry Smith   } else if (isstring) {
117454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
118b0a32e0cSBarry Smith     ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr);
11919bcc07fSBarry Smith   }
12094b7f48cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
121b0a32e0cSBarry Smith   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
12294b7f48cSBarry Smith   ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
123b0a32e0cSBarry Smith   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1243a40ed3dSBarry Smith   PetscFunctionReturn(0);
1259b94acceSBarry Smith }
1269b94acceSBarry Smith 
12776b2cf59SMatthew Knepley /*
12876b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
12976b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
13076b2cf59SMatthew Knepley */
13176b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
132a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
1336849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
13476b2cf59SMatthew Knepley 
135e74ef692SMatthew Knepley #undef __FUNCT__
136e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker"
137ac226902SBarry Smith /*@C
13876b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
13976b2cf59SMatthew Knepley 
14076b2cf59SMatthew Knepley   Not Collective
14176b2cf59SMatthew Knepley 
14276b2cf59SMatthew Knepley   Input Parameter:
14376b2cf59SMatthew Knepley . snescheck - function that checks for options
14476b2cf59SMatthew Knepley 
14576b2cf59SMatthew Knepley   Level: developer
14676b2cf59SMatthew Knepley 
14776b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
14876b2cf59SMatthew Knepley @*/
14963dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
15076b2cf59SMatthew Knepley {
15176b2cf59SMatthew Knepley   PetscFunctionBegin;
15276b2cf59SMatthew Knepley   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
15377431f27SBarry Smith     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
15476b2cf59SMatthew Knepley   }
15576b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
15676b2cf59SMatthew Knepley   PetscFunctionReturn(0);
15776b2cf59SMatthew Knepley }
15876b2cf59SMatthew Knepley 
159aa3661deSLisandro Dalcin EXTERN PetscErrorCode PETSCSNES_DLLEXPORT SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
160aa3661deSLisandro Dalcin 
161aa3661deSLisandro Dalcin #undef __FUNCT__
162aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private"
163d3462f78SMatthew Knepley static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscTruth hasOperator, PetscInt version)
164aa3661deSLisandro Dalcin {
165aa3661deSLisandro Dalcin   Mat            J;
166aa3661deSLisandro Dalcin   KSP            ksp;
167aa3661deSLisandro Dalcin   PC             pc;
168aa3661deSLisandro Dalcin   PetscTruth     match;
169aa3661deSLisandro Dalcin   PetscErrorCode ierr;
170aa3661deSLisandro Dalcin 
171aa3661deSLisandro Dalcin   PetscFunctionBegin;
172aa3661deSLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
173aa3661deSLisandro Dalcin 
17498613b67SLisandro Dalcin   if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
17598613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
17698613b67SLisandro Dalcin     ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr);
17798613b67SLisandro Dalcin   }
17898613b67SLisandro Dalcin 
179aa3661deSLisandro Dalcin   if (version == 1) {
180aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
18198613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
182aa3661deSLisandro Dalcin     ierr = MatMFFDSetFromOptions(J);CHKERRQ(ierr);
183aa3661deSLisandro Dalcin   } else if (version == 2) {
184aa3661deSLisandro Dalcin     if (!snes->vec_func) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
18565460251SBarry Smith #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)
186aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
187aa3661deSLisandro Dalcin #else
188aa3661deSLisandro Dalcin     SETERRQ(PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
189aa3661deSLisandro Dalcin #endif
190aa3661deSLisandro Dalcin   } else {
191aa3661deSLisandro Dalcin     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
192aa3661deSLisandro Dalcin   }
193aa3661deSLisandro Dalcin 
194aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
195d3462f78SMatthew Knepley   if (hasOperator) {
196aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
197aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
198aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
199aa3661deSLisandro Dalcin   } else {
200aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
201aa3661deSLisandro Dalcin        provided preconditioner matrix with the default matrix free version. */
202aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);CHKERRQ(ierr);
203aa3661deSLisandro Dalcin     /* Force no preconditioner */
204aa3661deSLisandro Dalcin     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
205aa3661deSLisandro Dalcin     ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
206aa3661deSLisandro Dalcin     ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
207aa3661deSLisandro Dalcin     if (!match) {
208aa3661deSLisandro Dalcin       ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
209aa3661deSLisandro Dalcin       ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
210aa3661deSLisandro Dalcin     }
211aa3661deSLisandro Dalcin   }
212aa3661deSLisandro Dalcin   ierr = MatDestroy(J);CHKERRQ(ierr);
213aa3661deSLisandro Dalcin 
214aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
215aa3661deSLisandro Dalcin }
216aa3661deSLisandro Dalcin 
2174a2ae208SSatish Balay #undef __FUNCT__
2184a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions"
2199b94acceSBarry Smith /*@
22094b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
2219b94acceSBarry Smith 
222c7afd0dbSLois Curfman McInnes    Collective on SNES
223c7afd0dbSLois Curfman McInnes 
2249b94acceSBarry Smith    Input Parameter:
2259b94acceSBarry Smith .  snes - the SNES context
2269b94acceSBarry Smith 
22736851e7fSLois Curfman McInnes    Options Database Keys:
2286831982aSBarry Smith +  -snes_type <type> - ls, tr, umls, umtr, test
22982738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
23082738288SBarry Smith                 of the change in the solution between steps
23170441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
232b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
233b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
234b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
23550ffb88aSMatthew Knepley .  -snes_max_fail <max_fail> - maximum number of failures
236ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
237a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
238e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
239b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
2402492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
24182738288SBarry Smith                                solver; hence iterations will continue until max_it
2421fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
24382738288SBarry Smith                                of convergence test
244e8105e01SRichard Katz .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
245e8105e01SRichard Katz                                        filename given prints to stdout
246a6570f20SBarry Smith .  -snes_monitor_solution - plots solution at each iteration
247a6570f20SBarry Smith .  -snes_monitor_residual - plots residual (not its norm) at each iteration
248a6570f20SBarry Smith .  -snes_monitor_solution_update - plots update to solution at each iteration
249a6570f20SBarry Smith .  -snes_monitor_draw - plots residual norm at each iteration
250e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
2515968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
252fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
25382738288SBarry Smith 
25482738288SBarry Smith     Options Database for Eisenstat-Walker method:
255fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
2564b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
25736851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
25836851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
25936851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
26036851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
26136851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
26236851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
26382738288SBarry Smith 
26411ca99fdSLois Curfman McInnes    Notes:
26511ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
26611ca99fdSLois Curfman McInnes    the users manual.
26783e2fdc7SBarry Smith 
26836851e7fSLois Curfman McInnes    Level: beginner
26936851e7fSLois Curfman McInnes 
2709b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
2719b94acceSBarry Smith 
27269ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
2739b94acceSBarry Smith @*/
27463dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESSetFromOptions(SNES snes)
2759b94acceSBarry Smith {
276aa3661deSLisandro Dalcin   PetscTruth              flg,mf,mf_operator;
277aa3661deSLisandro Dalcin   PetscInt                i,indx,lag,mf_version;
278aa3661deSLisandro Dalcin   MatStructure            matflag;
27985385478SLisandro Dalcin   const char              *deft = SNESLS;
28085385478SLisandro Dalcin   const char              *convtests[] = {"default","skip"};
28185385478SLisandro Dalcin   SNESKSPEW               *kctx = NULL;
282e8105e01SRichard Katz   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
28323d894e5SBarry Smith   PetscViewerASCIIMonitor monviewer;
28485385478SLisandro Dalcin   PetscErrorCode          ierr;
2859b94acceSBarry Smith 
2863a40ed3dSBarry Smith   PetscFunctionBegin;
2874482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
288ca161407SBarry Smith 
289186905e3SBarry Smith   if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
290cce0b1b2SLisandro Dalcin   ierr = PetscOptionsBegin(((PetscObject)snes)->comm,((PetscObject)snes)->prefix,"Nonlinear solver (SNES) options","SNES");CHKERRQ(ierr);
2917adad957SLisandro Dalcin     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
292b0a32e0cSBarry Smith     ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
293d64ed03dSBarry Smith     if (flg) {
294186905e3SBarry Smith       ierr = SNESSetType(snes,type);CHKERRQ(ierr);
2957adad957SLisandro Dalcin     } else if (!((PetscObject)snes)->type_name) {
296186905e3SBarry Smith       ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
297d64ed03dSBarry Smith     }
29890d69ab7SBarry Smith     /* not used here, but called so will go into help messaage */
299909c8a9fSBarry Smith     ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr);
30093c39befSBarry Smith 
30157034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->xtol,&snes->xtol,0);CHKERRQ(ierr);
30257034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr);
303186905e3SBarry Smith 
30457034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr);
305b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr);
306b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr);
30750ffb88aSMatthew Knepley     ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr);
308ddf469c8SBarry Smith     ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr);
30985385478SLisandro Dalcin 
310a8054027SBarry Smith     ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
311a8054027SBarry Smith     if (flg) {
312a8054027SBarry Smith       ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
313a8054027SBarry Smith     }
314e35cf81dSBarry Smith     ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
315e35cf81dSBarry Smith     if (flg) {
316e35cf81dSBarry Smith       ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
317e35cf81dSBarry Smith     }
318a8054027SBarry Smith 
31985385478SLisandro Dalcin     ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
32085385478SLisandro Dalcin     if (flg) {
32185385478SLisandro Dalcin       switch (indx) {
3227f7931b9SBarry Smith       case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break;
3237f7931b9SBarry Smith       case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);    break;
32485385478SLisandro Dalcin       }
32585385478SLisandro Dalcin     }
32685385478SLisandro Dalcin 
32790d69ab7SBarry Smith     ierr = PetscOptionsTruth("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr);
328186905e3SBarry Smith 
32985385478SLisandro Dalcin     kctx = (SNESKSPEW *)snes->kspconvctx;
33085385478SLisandro Dalcin 
331fa9f3622SBarry Smith     ierr = PetscOptionsTruth("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr);
332186905e3SBarry Smith 
333fa9f3622SBarry Smith     ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr);
334fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr);
335fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr);
336fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr);
337fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr);
338fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr);
339fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr);
340186905e3SBarry Smith 
34190d69ab7SBarry Smith     flg  = PETSC_FALSE;
34290d69ab7SBarry Smith     ierr = PetscOptionsTruth("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
343a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
344eabae89aSBarry Smith 
345a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
346e8105e01SRichard Katz     if (flg) {
347050a712dSBarry Smith       ierr = PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,((PetscObject)snes)->tablevel,&monviewer);CHKERRQ(ierr);
34823d894e5SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);CHKERRQ(ierr);
349e8105e01SRichard Katz     }
350eabae89aSBarry Smith 
351b271bb04SBarry Smith     ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
352b271bb04SBarry Smith     if (flg) {
353b271bb04SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr);
354b271bb04SBarry Smith     }
355b271bb04SBarry Smith 
356a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
357eabae89aSBarry Smith     if (flg) {
358050a712dSBarry Smith       ierr = PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,((PetscObject)snes)->tablevel,&monviewer);CHKERRQ(ierr);
359f1bef1bcSMatthew Knepley       ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr);
360e8105e01SRichard Katz     }
361eabae89aSBarry Smith 
362a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
363eabae89aSBarry Smith     if (flg) {
364050a712dSBarry Smith       ierr = PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,((PetscObject)snes)->tablevel,&monviewer);CHKERRQ(ierr);
36523d894e5SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);CHKERRQ(ierr);
366eabae89aSBarry Smith     }
367eabae89aSBarry Smith 
36890d69ab7SBarry Smith     flg  = PETSC_FALSE;
36990d69ab7SBarry Smith     ierr = PetscOptionsTruth("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
370a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
37190d69ab7SBarry Smith     flg  = PETSC_FALSE;
37290d69ab7SBarry Smith     ierr = PetscOptionsTruth("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
373a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
37490d69ab7SBarry Smith     flg  = PETSC_FALSE;
37590d69ab7SBarry Smith     ierr = PetscOptionsTruth("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
376a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
37790d69ab7SBarry Smith     flg  = PETSC_FALSE;
37890d69ab7SBarry Smith     ierr = PetscOptionsTruth("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
379a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
38090d69ab7SBarry Smith     flg  = PETSC_FALSE;
38190d69ab7SBarry Smith     ierr = PetscOptionsTruth("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
382b271bb04SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
383e24b481bSBarry Smith 
38490d69ab7SBarry Smith     flg  = PETSC_FALSE;
38590d69ab7SBarry Smith     ierr = PetscOptionsTruth("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
3864b27c08aSLois Curfman McInnes     if (flg) {
387186905e3SBarry Smith       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);CHKERRQ(ierr);
388ae15b995SBarry Smith       ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
3899b94acceSBarry Smith     }
390639f9d9dSBarry Smith 
391aa3661deSLisandro Dalcin     mf = mf_operator = PETSC_FALSE;
392aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
393aa3661deSLisandro Dalcin     ierr = PetscOptionsTruth("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr);
394aa3661deSLisandro Dalcin     if (flg && mf_operator) mf = PETSC_TRUE;
395aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
396aa3661deSLisandro Dalcin     ierr = PetscOptionsTruth("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr);
397aa3661deSLisandro Dalcin     if (!flg && mf_operator) mf = PETSC_TRUE;
398aa3661deSLisandro Dalcin     mf_version = 1;
399aa3661deSLisandro Dalcin     ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr);
400aa3661deSLisandro Dalcin 
40176b2cf59SMatthew Knepley     for(i = 0; i < numberofsetfromoptions; i++) {
40276b2cf59SMatthew Knepley       ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
40376b2cf59SMatthew Knepley     }
40476b2cf59SMatthew Knepley 
405e7788613SBarry Smith     if (snes->ops->setfromoptions) {
406e7788613SBarry Smith       ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr);
407639f9d9dSBarry Smith     }
408b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
4094bbc92c1SBarry Smith 
410aa3661deSLisandro Dalcin   if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); }
4111cee3971SBarry Smith 
4121cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
413aa3661deSLisandro Dalcin   ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
414aa3661deSLisandro Dalcin   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr);
41585385478SLisandro Dalcin   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
41693993e2dSLois Curfman McInnes 
4173a40ed3dSBarry Smith   PetscFunctionReturn(0);
4189b94acceSBarry Smith }
4199b94acceSBarry Smith 
420a847f771SSatish Balay 
4214a2ae208SSatish Balay #undef __FUNCT__
4224a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
4239b94acceSBarry Smith /*@
4249b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
4259b94acceSBarry Smith    the nonlinear solvers.
4269b94acceSBarry Smith 
427fee21e36SBarry Smith    Collective on SNES
428fee21e36SBarry Smith 
429c7afd0dbSLois Curfman McInnes    Input Parameters:
430c7afd0dbSLois Curfman McInnes +  snes - the SNES context
431c7afd0dbSLois Curfman McInnes -  usrP - optional user context
432c7afd0dbSLois Curfman McInnes 
43336851e7fSLois Curfman McInnes    Level: intermediate
43436851e7fSLois Curfman McInnes 
4359b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
4369b94acceSBarry Smith 
4379b94acceSBarry Smith .seealso: SNESGetApplicationContext()
4389b94acceSBarry Smith @*/
43963dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESSetApplicationContext(SNES snes,void *usrP)
4409b94acceSBarry Smith {
4413a40ed3dSBarry Smith   PetscFunctionBegin;
4424482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
4439b94acceSBarry Smith   snes->user		= usrP;
4443a40ed3dSBarry Smith   PetscFunctionReturn(0);
4459b94acceSBarry Smith }
44674679c65SBarry Smith 
4474a2ae208SSatish Balay #undef __FUNCT__
4484a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
4499b94acceSBarry Smith /*@C
4509b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
4519b94acceSBarry Smith    nonlinear solvers.
4529b94acceSBarry Smith 
453c7afd0dbSLois Curfman McInnes    Not Collective
454c7afd0dbSLois Curfman McInnes 
4559b94acceSBarry Smith    Input Parameter:
4569b94acceSBarry Smith .  snes - SNES context
4579b94acceSBarry Smith 
4589b94acceSBarry Smith    Output Parameter:
4599b94acceSBarry Smith .  usrP - user context
4609b94acceSBarry Smith 
46136851e7fSLois Curfman McInnes    Level: intermediate
46236851e7fSLois Curfman McInnes 
4639b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
4649b94acceSBarry Smith 
4659b94acceSBarry Smith .seealso: SNESSetApplicationContext()
4669b94acceSBarry Smith @*/
46763dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESGetApplicationContext(SNES snes,void **usrP)
4689b94acceSBarry Smith {
4693a40ed3dSBarry Smith   PetscFunctionBegin;
4704482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
4719b94acceSBarry Smith   *usrP = snes->user;
4723a40ed3dSBarry Smith   PetscFunctionReturn(0);
4739b94acceSBarry Smith }
47474679c65SBarry Smith 
4754a2ae208SSatish Balay #undef __FUNCT__
4764a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
4779b94acceSBarry Smith /*@
478c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
479c8228a4eSBarry Smith    at this time.
4809b94acceSBarry Smith 
481c7afd0dbSLois Curfman McInnes    Not Collective
482c7afd0dbSLois Curfman McInnes 
4839b94acceSBarry Smith    Input Parameter:
4849b94acceSBarry Smith .  snes - SNES context
4859b94acceSBarry Smith 
4869b94acceSBarry Smith    Output Parameter:
4879b94acceSBarry Smith .  iter - iteration number
4889b94acceSBarry Smith 
489c8228a4eSBarry Smith    Notes:
490c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
491c8228a4eSBarry Smith 
492c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
49308405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
49408405cd6SLois Curfman McInnes .vb
49508405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
49608405cd6SLois Curfman McInnes       if (!(it % 2)) {
49708405cd6SLois Curfman McInnes         [compute Jacobian here]
49808405cd6SLois Curfman McInnes       }
49908405cd6SLois Curfman McInnes .ve
500c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
50108405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
502c8228a4eSBarry Smith 
50336851e7fSLois Curfman McInnes    Level: intermediate
50436851e7fSLois Curfman McInnes 
5052b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
5062b668275SBarry Smith 
507b850b91aSLisandro Dalcin .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
5089b94acceSBarry Smith @*/
50963dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESGetIterationNumber(SNES snes,PetscInt* iter)
5109b94acceSBarry Smith {
5113a40ed3dSBarry Smith   PetscFunctionBegin;
5124482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
5134482741eSBarry Smith   PetscValidIntPointer(iter,2);
5149b94acceSBarry Smith   *iter = snes->iter;
5153a40ed3dSBarry Smith   PetscFunctionReturn(0);
5169b94acceSBarry Smith }
51774679c65SBarry Smith 
5184a2ae208SSatish Balay #undef __FUNCT__
5194a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm"
5209b94acceSBarry Smith /*@
5219b94acceSBarry Smith    SNESGetFunctionNorm - Gets the norm of the current function that was set
5229b94acceSBarry Smith    with SNESSSetFunction().
5239b94acceSBarry Smith 
524c7afd0dbSLois Curfman McInnes    Collective on SNES
525c7afd0dbSLois Curfman McInnes 
5269b94acceSBarry Smith    Input Parameter:
5279b94acceSBarry Smith .  snes - SNES context
5289b94acceSBarry Smith 
5299b94acceSBarry Smith    Output Parameter:
5309b94acceSBarry Smith .  fnorm - 2-norm of function
5319b94acceSBarry Smith 
53236851e7fSLois Curfman McInnes    Level: intermediate
53336851e7fSLois Curfman McInnes 
5349b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm
535a86d99e1SLois Curfman McInnes 
536b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
5379b94acceSBarry Smith @*/
53871f87433Sdalcinl PetscErrorCode PETSCSNES_DLLEXPORT SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
5399b94acceSBarry Smith {
5403a40ed3dSBarry Smith   PetscFunctionBegin;
5414482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
5424482741eSBarry Smith   PetscValidScalarPointer(fnorm,2);
5439b94acceSBarry Smith   *fnorm = snes->norm;
5443a40ed3dSBarry Smith   PetscFunctionReturn(0);
5459b94acceSBarry Smith }
54674679c65SBarry Smith 
5474a2ae208SSatish Balay #undef __FUNCT__
548b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
5499b94acceSBarry Smith /*@
550b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
5519b94acceSBarry Smith    attempted by the nonlinear solver.
5529b94acceSBarry Smith 
553c7afd0dbSLois Curfman McInnes    Not Collective
554c7afd0dbSLois Curfman McInnes 
5559b94acceSBarry Smith    Input Parameter:
5569b94acceSBarry Smith .  snes - SNES context
5579b94acceSBarry Smith 
5589b94acceSBarry Smith    Output Parameter:
5599b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
5609b94acceSBarry Smith 
561c96a6f78SLois Curfman McInnes    Notes:
562c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
563c96a6f78SLois Curfman McInnes 
56436851e7fSLois Curfman McInnes    Level: intermediate
56536851e7fSLois Curfman McInnes 
5669b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
56758ebbce7SBarry Smith 
568e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
56958ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
5709b94acceSBarry Smith @*/
571b850b91aSLisandro Dalcin PetscErrorCode PETSCSNES_DLLEXPORT SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
5729b94acceSBarry Smith {
5733a40ed3dSBarry Smith   PetscFunctionBegin;
5744482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
5754482741eSBarry Smith   PetscValidIntPointer(nfails,2);
57650ffb88aSMatthew Knepley   *nfails = snes->numFailures;
57750ffb88aSMatthew Knepley   PetscFunctionReturn(0);
57850ffb88aSMatthew Knepley }
57950ffb88aSMatthew Knepley 
58050ffb88aSMatthew Knepley #undef __FUNCT__
581b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
58250ffb88aSMatthew Knepley /*@
583b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
58450ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
58550ffb88aSMatthew Knepley 
58650ffb88aSMatthew Knepley    Not Collective
58750ffb88aSMatthew Knepley 
58850ffb88aSMatthew Knepley    Input Parameters:
58950ffb88aSMatthew Knepley +  snes     - SNES context
59050ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
59150ffb88aSMatthew Knepley 
59250ffb88aSMatthew Knepley    Level: intermediate
59350ffb88aSMatthew Knepley 
59450ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
59558ebbce7SBarry Smith 
596e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
59758ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
59850ffb88aSMatthew Knepley @*/
599b850b91aSLisandro Dalcin PetscErrorCode PETSCSNES_DLLEXPORT SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
60050ffb88aSMatthew Knepley {
60150ffb88aSMatthew Knepley   PetscFunctionBegin;
6024482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
60350ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
60450ffb88aSMatthew Knepley   PetscFunctionReturn(0);
60550ffb88aSMatthew Knepley }
60650ffb88aSMatthew Knepley 
60750ffb88aSMatthew Knepley #undef __FUNCT__
608b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
60950ffb88aSMatthew Knepley /*@
610b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
61150ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
61250ffb88aSMatthew Knepley 
61350ffb88aSMatthew Knepley    Not Collective
61450ffb88aSMatthew Knepley 
61550ffb88aSMatthew Knepley    Input Parameter:
61650ffb88aSMatthew Knepley .  snes     - SNES context
61750ffb88aSMatthew Knepley 
61850ffb88aSMatthew Knepley    Output Parameter:
61950ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
62050ffb88aSMatthew Knepley 
62150ffb88aSMatthew Knepley    Level: intermediate
62250ffb88aSMatthew Knepley 
62350ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
62458ebbce7SBarry Smith 
625e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
62658ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
62758ebbce7SBarry Smith 
62850ffb88aSMatthew Knepley @*/
629b850b91aSLisandro Dalcin PetscErrorCode PETSCSNES_DLLEXPORT SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
63050ffb88aSMatthew Knepley {
63150ffb88aSMatthew Knepley   PetscFunctionBegin;
6324482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
6334482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
63450ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
6353a40ed3dSBarry Smith   PetscFunctionReturn(0);
6369b94acceSBarry Smith }
637a847f771SSatish Balay 
6384a2ae208SSatish Balay #undef __FUNCT__
6392541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
6402541af92SBarry Smith /*@
6412541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
6422541af92SBarry Smith      done by SNES.
6432541af92SBarry Smith 
6442541af92SBarry Smith    Not Collective
6452541af92SBarry Smith 
6462541af92SBarry Smith    Input Parameter:
6472541af92SBarry Smith .  snes     - SNES context
6482541af92SBarry Smith 
6492541af92SBarry Smith    Output Parameter:
6502541af92SBarry Smith .  nfuncs - number of evaluations
6512541af92SBarry Smith 
6522541af92SBarry Smith    Level: intermediate
6532541af92SBarry Smith 
6542541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
65558ebbce7SBarry Smith 
656e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
6572541af92SBarry Smith @*/
6582541af92SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
6592541af92SBarry Smith {
6602541af92SBarry Smith   PetscFunctionBegin;
6612541af92SBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
6622541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
6632541af92SBarry Smith   *nfuncs = snes->nfuncs;
6642541af92SBarry Smith   PetscFunctionReturn(0);
6652541af92SBarry Smith }
6662541af92SBarry Smith 
6672541af92SBarry Smith #undef __FUNCT__
6683d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
6693d4c4710SBarry Smith /*@
6703d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
6713d4c4710SBarry Smith    linear solvers.
6723d4c4710SBarry Smith 
6733d4c4710SBarry Smith    Not Collective
6743d4c4710SBarry Smith 
6753d4c4710SBarry Smith    Input Parameter:
6763d4c4710SBarry Smith .  snes - SNES context
6773d4c4710SBarry Smith 
6783d4c4710SBarry Smith    Output Parameter:
6793d4c4710SBarry Smith .  nfails - number of failed solves
6803d4c4710SBarry Smith 
6813d4c4710SBarry Smith    Notes:
6823d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
6833d4c4710SBarry Smith 
6843d4c4710SBarry Smith    Level: intermediate
6853d4c4710SBarry Smith 
6863d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
68758ebbce7SBarry Smith 
688e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
6893d4c4710SBarry Smith @*/
6903d4c4710SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
6913d4c4710SBarry Smith {
6923d4c4710SBarry Smith   PetscFunctionBegin;
6933d4c4710SBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
6943d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
6953d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
6963d4c4710SBarry Smith   PetscFunctionReturn(0);
6973d4c4710SBarry Smith }
6983d4c4710SBarry Smith 
6993d4c4710SBarry Smith #undef __FUNCT__
7003d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
7013d4c4710SBarry Smith /*@
7023d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
7033d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
7043d4c4710SBarry Smith 
7053d4c4710SBarry Smith    Collective on SNES
7063d4c4710SBarry Smith 
7073d4c4710SBarry Smith    Input Parameters:
7083d4c4710SBarry Smith +  snes     - SNES context
7093d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
7103d4c4710SBarry Smith 
7113d4c4710SBarry Smith    Level: intermediate
7123d4c4710SBarry Smith 
713a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
7143d4c4710SBarry Smith 
7153d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
7163d4c4710SBarry Smith 
71758ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
7183d4c4710SBarry Smith @*/
7193d4c4710SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
7203d4c4710SBarry Smith {
7213d4c4710SBarry Smith   PetscFunctionBegin;
7223d4c4710SBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
7233d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
7243d4c4710SBarry Smith   PetscFunctionReturn(0);
7253d4c4710SBarry Smith }
7263d4c4710SBarry Smith 
7273d4c4710SBarry Smith #undef __FUNCT__
7283d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
7293d4c4710SBarry Smith /*@
7303d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
7313d4c4710SBarry Smith      are allowed before SNES terminates
7323d4c4710SBarry Smith 
7333d4c4710SBarry Smith    Not Collective
7343d4c4710SBarry Smith 
7353d4c4710SBarry Smith    Input Parameter:
7363d4c4710SBarry Smith .  snes     - SNES context
7373d4c4710SBarry Smith 
7383d4c4710SBarry Smith    Output Parameter:
7393d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
7403d4c4710SBarry Smith 
7413d4c4710SBarry Smith    Level: intermediate
7423d4c4710SBarry Smith 
7433d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
7443d4c4710SBarry Smith 
7453d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
7463d4c4710SBarry Smith 
747e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
7483d4c4710SBarry Smith @*/
7493d4c4710SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
7503d4c4710SBarry Smith {
7513d4c4710SBarry Smith   PetscFunctionBegin;
7523d4c4710SBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
7533d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
7543d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
7553d4c4710SBarry Smith   PetscFunctionReturn(0);
7563d4c4710SBarry Smith }
7573d4c4710SBarry Smith 
7583d4c4710SBarry Smith #undef __FUNCT__
759b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
760c96a6f78SLois Curfman McInnes /*@
761b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
762c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
763c96a6f78SLois Curfman McInnes 
764c7afd0dbSLois Curfman McInnes    Not Collective
765c7afd0dbSLois Curfman McInnes 
766c96a6f78SLois Curfman McInnes    Input Parameter:
767c96a6f78SLois Curfman McInnes .  snes - SNES context
768c96a6f78SLois Curfman McInnes 
769c96a6f78SLois Curfman McInnes    Output Parameter:
770c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
771c96a6f78SLois Curfman McInnes 
772c96a6f78SLois Curfman McInnes    Notes:
773c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
774c96a6f78SLois Curfman McInnes 
77536851e7fSLois Curfman McInnes    Level: intermediate
77636851e7fSLois Curfman McInnes 
777c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
7782b668275SBarry Smith 
7798c7482ecSBarry Smith .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
780c96a6f78SLois Curfman McInnes @*/
781b850b91aSLisandro Dalcin PetscErrorCode PETSCSNES_DLLEXPORT SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
782c96a6f78SLois Curfman McInnes {
7833a40ed3dSBarry Smith   PetscFunctionBegin;
7844482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
7854482741eSBarry Smith   PetscValidIntPointer(lits,2);
786c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
7873a40ed3dSBarry Smith   PetscFunctionReturn(0);
788c96a6f78SLois Curfman McInnes }
789c96a6f78SLois Curfman McInnes 
7904a2ae208SSatish Balay #undef __FUNCT__
79194b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP"
79252baeb72SSatish Balay /*@
79394b7f48cSBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
7949b94acceSBarry Smith 
79594b7f48cSBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
796c7afd0dbSLois Curfman McInnes 
7979b94acceSBarry Smith    Input Parameter:
7989b94acceSBarry Smith .  snes - the SNES context
7999b94acceSBarry Smith 
8009b94acceSBarry Smith    Output Parameter:
80194b7f48cSBarry Smith .  ksp - the KSP context
8029b94acceSBarry Smith 
8039b94acceSBarry Smith    Notes:
80494b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
8059b94acceSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
8062999313aSBarry Smith    PC contexts as well.
8079b94acceSBarry Smith 
80836851e7fSLois Curfman McInnes    Level: beginner
80936851e7fSLois Curfman McInnes 
81094b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
8119b94acceSBarry Smith 
8122999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
8139b94acceSBarry Smith @*/
81463dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESGetKSP(SNES snes,KSP *ksp)
8159b94acceSBarry Smith {
8161cee3971SBarry Smith   PetscErrorCode ierr;
8171cee3971SBarry Smith 
8183a40ed3dSBarry Smith   PetscFunctionBegin;
8194482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
8204482741eSBarry Smith   PetscValidPointer(ksp,2);
8211cee3971SBarry Smith 
8221cee3971SBarry Smith   if (!snes->ksp) {
8231cee3971SBarry Smith     ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr);
8241cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
8251cee3971SBarry Smith     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
8261cee3971SBarry Smith   }
82794b7f48cSBarry Smith   *ksp = snes->ksp;
8283a40ed3dSBarry Smith   PetscFunctionReturn(0);
8299b94acceSBarry Smith }
83082bf6240SBarry Smith 
8314a2ae208SSatish Balay #undef __FUNCT__
8322999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
8332999313aSBarry Smith /*@
8342999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
8352999313aSBarry Smith 
8362999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
8372999313aSBarry Smith 
8382999313aSBarry Smith    Input Parameters:
8392999313aSBarry Smith +  snes - the SNES context
8402999313aSBarry Smith -  ksp - the KSP context
8412999313aSBarry Smith 
8422999313aSBarry Smith    Notes:
8432999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
8442999313aSBarry Smith    so this routine is rarely needed.
8452999313aSBarry Smith 
8462999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
8472999313aSBarry Smith    decreased by one.
8482999313aSBarry Smith 
8492999313aSBarry Smith    Level: developer
8502999313aSBarry Smith 
8512999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
8522999313aSBarry Smith 
8532999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
8542999313aSBarry Smith @*/
8552999313aSBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESSetKSP(SNES snes,KSP ksp)
8562999313aSBarry Smith {
8572999313aSBarry Smith   PetscErrorCode ierr;
8582999313aSBarry Smith 
8592999313aSBarry Smith   PetscFunctionBegin;
8602999313aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
8612999313aSBarry Smith   PetscValidHeaderSpecific(ksp,KSP_COOKIE,2);
8622999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
8637dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
864906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
8652999313aSBarry Smith   snes->ksp = ksp;
8662999313aSBarry Smith   PetscFunctionReturn(0);
8672999313aSBarry Smith }
8682999313aSBarry Smith 
8697adad957SLisandro Dalcin #if 0
8702999313aSBarry Smith #undef __FUNCT__
8714a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc"
8726849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
873e24b481bSBarry Smith {
874e24b481bSBarry Smith   PetscFunctionBegin;
875e24b481bSBarry Smith   PetscFunctionReturn(0);
876e24b481bSBarry Smith }
8777adad957SLisandro Dalcin #endif
878e24b481bSBarry Smith 
8799b94acceSBarry Smith /* -----------------------------------------------------------*/
8804a2ae208SSatish Balay #undef __FUNCT__
8814a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
88252baeb72SSatish Balay /*@
8839b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
8849b94acceSBarry Smith 
885c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
886c7afd0dbSLois Curfman McInnes 
887c7afd0dbSLois Curfman McInnes    Input Parameters:
888906ed7ccSBarry Smith .  comm - MPI communicator
8899b94acceSBarry Smith 
8909b94acceSBarry Smith    Output Parameter:
8919b94acceSBarry Smith .  outsnes - the new SNES context
8929b94acceSBarry Smith 
893c7afd0dbSLois Curfman McInnes    Options Database Keys:
894c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
895c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
896c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
897c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
898c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
899c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
900c1f60f51SBarry Smith 
90136851e7fSLois Curfman McInnes    Level: beginner
90236851e7fSLois Curfman McInnes 
9039b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
9049b94acceSBarry Smith 
905a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
906a8054027SBarry Smith 
9079b94acceSBarry Smith @*/
90863dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESCreate(MPI_Comm comm,SNES *outsnes)
9099b94acceSBarry Smith {
910dfbe8321SBarry Smith   PetscErrorCode      ierr;
9119b94acceSBarry Smith   SNES                snes;
912fa9f3622SBarry Smith   SNESKSPEW           *kctx;
91337fcc0dbSBarry Smith 
9143a40ed3dSBarry Smith   PetscFunctionBegin;
915ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
9168ba1e511SMatthew Knepley   *outsnes = PETSC_NULL;
9178ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
9188ba1e511SMatthew Knepley   ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr);
9198ba1e511SMatthew Knepley #endif
9208ba1e511SMatthew Knepley 
921e7788613SBarry Smith   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_COOKIE,0,"SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
9227adad957SLisandro Dalcin 
92385385478SLisandro Dalcin   snes->ops->converged    = SNESDefaultConverged;
9249b94acceSBarry Smith   snes->max_its           = 50;
9259750a799SBarry Smith   snes->max_funcs	  = 10000;
9269b94acceSBarry Smith   snes->norm		  = 0.0;
927b4874afaSBarry Smith   snes->rtol		  = 1.e-8;
928b4874afaSBarry Smith   snes->ttol              = 0.0;
92970441072SBarry Smith   snes->abstol		  = 1.e-50;
9309b94acceSBarry Smith   snes->xtol		  = 1.e-8;
9314b27c08aSLois Curfman McInnes   snes->deltatol	  = 1.e-12;
9329b94acceSBarry Smith   snes->nfuncs            = 0;
93350ffb88aSMatthew Knepley   snes->numFailures       = 0;
93450ffb88aSMatthew Knepley   snes->maxFailures       = 1;
9357a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
936e35cf81dSBarry Smith   snes->lagjacobian       = 1;
937a8054027SBarry Smith   snes->lagpreconditioner = 1;
938639f9d9dSBarry Smith   snes->numbermonitors    = 0;
9399b94acceSBarry Smith   snes->data              = 0;
9404dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
941186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
9426f24a144SLois Curfman McInnes   snes->vwork             = 0;
9436f24a144SLois Curfman McInnes   snes->nwork             = 0;
944758f92a0SBarry Smith   snes->conv_hist_len     = 0;
945758f92a0SBarry Smith   snes->conv_hist_max     = 0;
946758f92a0SBarry Smith   snes->conv_hist         = PETSC_NULL;
947758f92a0SBarry Smith   snes->conv_hist_its     = PETSC_NULL;
948758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
949184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
9509b94acceSBarry Smith 
9513d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
9523d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
9533d4c4710SBarry Smith 
9549b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
95538f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr);
9569b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
9579b94acceSBarry Smith   kctx->version     = 2;
9589b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
9599b94acceSBarry Smith                              this was too large for some test cases */
96075567043SBarry Smith   kctx->rtol_last   = 0.0;
9619b94acceSBarry Smith   kctx->rtol_max    = .9;
9629b94acceSBarry Smith   kctx->gamma       = 1.0;
96371f87433Sdalcinl   kctx->alpha       = .5*(1.0 + sqrt(5.0));
96471f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
9659b94acceSBarry Smith   kctx->threshold   = .1;
96675567043SBarry Smith   kctx->lresid_last = 0.0;
96775567043SBarry Smith   kctx->norm_last   = 0.0;
9689b94acceSBarry Smith 
9699b94acceSBarry Smith   *outsnes = snes;
97000036973SBarry Smith   ierr = PetscPublishAll(snes);CHKERRQ(ierr);
9713a40ed3dSBarry Smith   PetscFunctionReturn(0);
9729b94acceSBarry Smith }
9739b94acceSBarry Smith 
9744a2ae208SSatish Balay #undef __FUNCT__
9754a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
9769b94acceSBarry Smith /*@C
9779b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
9789b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
9799b94acceSBarry Smith    equations.
9809b94acceSBarry Smith 
981fee21e36SBarry Smith    Collective on SNES
982fee21e36SBarry Smith 
983c7afd0dbSLois Curfman McInnes    Input Parameters:
984c7afd0dbSLois Curfman McInnes +  snes - the SNES context
985c7afd0dbSLois Curfman McInnes .  r - vector to store function value
986de044059SHong Zhang .  func - function evaluation routine
987c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
988c7afd0dbSLois Curfman McInnes          function evaluation routine (may be PETSC_NULL)
9899b94acceSBarry Smith 
990c7afd0dbSLois Curfman McInnes    Calling sequence of func:
9918d76a1e5SLois Curfman McInnes $    func (SNES snes,Vec x,Vec f,void *ctx);
992c7afd0dbSLois Curfman McInnes 
993313e4042SLois Curfman McInnes .  f - function vector
994c7afd0dbSLois Curfman McInnes -  ctx - optional user-defined function context
9959b94acceSBarry Smith 
9969b94acceSBarry Smith    Notes:
9979b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
9989b94acceSBarry Smith $      f'(x) x = -f(x),
999c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
10009b94acceSBarry Smith 
100136851e7fSLois Curfman McInnes    Level: beginner
100236851e7fSLois Curfman McInnes 
10039b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
10049b94acceSBarry Smith 
1005a86d99e1SLois Curfman McInnes .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
10069b94acceSBarry Smith @*/
100763dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
10089b94acceSBarry Smith {
100985385478SLisandro Dalcin   PetscErrorCode ierr;
10103a40ed3dSBarry Smith   PetscFunctionBegin;
10114482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
10124482741eSBarry Smith   PetscValidHeaderSpecific(r,VEC_COOKIE,2);
1013c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,r,2);
101485385478SLisandro Dalcin   ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
101585385478SLisandro Dalcin   if (snes->vec_func) { ierr = VecDestroy(snes->vec_func);CHKERRQ(ierr); }
1016e7788613SBarry Smith   snes->ops->computefunction = func;
101785385478SLisandro Dalcin   snes->vec_func             = r;
10189b94acceSBarry Smith   snes->funP                 = ctx;
10193a40ed3dSBarry Smith   PetscFunctionReturn(0);
10209b94acceSBarry Smith }
10219b94acceSBarry Smith 
10223ab0aad5SBarry Smith /* --------------------------------------------------------------- */
10233ab0aad5SBarry Smith #undef __FUNCT__
10241096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
10251096aae1SMatthew Knepley /*@C
10261096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
10271096aae1SMatthew Knepley    it assumes a zero right hand side.
10281096aae1SMatthew Knepley 
10291096aae1SMatthew Knepley    Collective on SNES
10301096aae1SMatthew Knepley 
10311096aae1SMatthew Knepley    Input Parameter:
10321096aae1SMatthew Knepley .  snes - the SNES context
10331096aae1SMatthew Knepley 
10341096aae1SMatthew Knepley    Output Parameter:
1035bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
10361096aae1SMatthew Knepley 
10371096aae1SMatthew Knepley    Level: intermediate
10381096aae1SMatthew Knepley 
10391096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
10401096aae1SMatthew Knepley 
104185385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
10421096aae1SMatthew Knepley @*/
10431096aae1SMatthew Knepley PetscErrorCode PETSCSNES_DLLEXPORT SNESGetRhs(SNES snes,Vec *rhs)
10441096aae1SMatthew Knepley {
10451096aae1SMatthew Knepley   PetscFunctionBegin;
10461096aae1SMatthew Knepley   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
10471096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
104885385478SLisandro Dalcin   *rhs = snes->vec_rhs;
10491096aae1SMatthew Knepley   PetscFunctionReturn(0);
10501096aae1SMatthew Knepley }
10511096aae1SMatthew Knepley 
10521096aae1SMatthew Knepley #undef __FUNCT__
10534a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
10549b94acceSBarry Smith /*@
105536851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
10569b94acceSBarry Smith                          SNESSetFunction().
10579b94acceSBarry Smith 
1058c7afd0dbSLois Curfman McInnes    Collective on SNES
1059c7afd0dbSLois Curfman McInnes 
10609b94acceSBarry Smith    Input Parameters:
1061c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1062c7afd0dbSLois Curfman McInnes -  x - input vector
10639b94acceSBarry Smith 
10649b94acceSBarry Smith    Output Parameter:
10653638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
10669b94acceSBarry Smith 
10671bffabb2SLois Curfman McInnes    Notes:
106836851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
106936851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
107036851e7fSLois Curfman McInnes    themselves.
107136851e7fSLois Curfman McInnes 
107236851e7fSLois Curfman McInnes    Level: developer
107336851e7fSLois Curfman McInnes 
10749b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
10759b94acceSBarry Smith 
1076a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
10779b94acceSBarry Smith @*/
107863dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESComputeFunction(SNES snes,Vec x,Vec y)
10799b94acceSBarry Smith {
1080dfbe8321SBarry Smith   PetscErrorCode ierr;
10819b94acceSBarry Smith 
10823a40ed3dSBarry Smith   PetscFunctionBegin;
10834482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
10844482741eSBarry Smith   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
10854482741eSBarry Smith   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1086c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
1087c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
1088184914b5SBarry Smith 
1089d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
1090e7788613SBarry Smith   if (snes->ops->computefunction) {
1091d64ed03dSBarry Smith     PetscStackPush("SNES user function");
1092e9a2bbcdSBarry Smith     CHKMEMQ;
1093e7788613SBarry Smith     ierr = (*snes->ops->computefunction)(snes,x,y,snes->funP);
1094e9a2bbcdSBarry Smith     CHKMEMQ;
1095d64ed03dSBarry Smith     PetscStackPop;
1096d5e45103SBarry Smith     if (PetscExceptionValue(ierr)) {
109719717074SBarry Smith       PetscErrorCode pierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(pierr);
109819717074SBarry Smith     }
1099d5e45103SBarry Smith     CHKERRQ(ierr);
110085385478SLisandro Dalcin   } else if (snes->vec_rhs) {
11011096aae1SMatthew Knepley     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
11021096aae1SMatthew Knepley   } else {
11031096aae1SMatthew Knepley     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() before SNESComputeFunction(), likely called from SNESSolve().");
11041096aae1SMatthew Knepley   }
110585385478SLisandro Dalcin   if (snes->vec_rhs) {
110685385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
11073ab0aad5SBarry Smith   }
1108ae3c334cSLois Curfman McInnes   snes->nfuncs++;
1109d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
11103a40ed3dSBarry Smith   PetscFunctionReturn(0);
11119b94acceSBarry Smith }
11129b94acceSBarry Smith 
11134a2ae208SSatish Balay #undef __FUNCT__
11144a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
111562fef451SLois Curfman McInnes /*@
111662fef451SLois Curfman McInnes    SNESComputeJacobian - Computes the Jacobian matrix that has been
111762fef451SLois Curfman McInnes    set with SNESSetJacobian().
111862fef451SLois Curfman McInnes 
1119c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
1120c7afd0dbSLois Curfman McInnes 
112162fef451SLois Curfman McInnes    Input Parameters:
1122c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1123c7afd0dbSLois Curfman McInnes -  x - input vector
112462fef451SLois Curfman McInnes 
112562fef451SLois Curfman McInnes    Output Parameters:
1126c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
112762fef451SLois Curfman McInnes .  B - optional preconditioning matrix
11282b668275SBarry Smith -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1129fee21e36SBarry Smith 
1130e35cf81dSBarry Smith   Options Database Keys:
1131e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
1132e35cf81dSBarry Smith -    -snes_lag_jacobian <lag>
1133e35cf81dSBarry Smith 
113462fef451SLois Curfman McInnes    Notes:
113562fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
113662fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
113762fef451SLois Curfman McInnes 
113894b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the
1139dc5a77f8SLois Curfman McInnes    flag parameter.
114062fef451SLois Curfman McInnes 
114136851e7fSLois Curfman McInnes    Level: developer
114236851e7fSLois Curfman McInnes 
114362fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
114462fef451SLois Curfman McInnes 
1145e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
114662fef451SLois Curfman McInnes @*/
114763dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
11489b94acceSBarry Smith {
1149dfbe8321SBarry Smith   PetscErrorCode ierr;
1150ebd3b9afSBarry Smith   PetscTruth     flag;
11513a40ed3dSBarry Smith 
11523a40ed3dSBarry Smith   PetscFunctionBegin;
11534482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
11544482741eSBarry Smith   PetscValidHeaderSpecific(X,VEC_COOKIE,2);
11554482741eSBarry Smith   PetscValidPointer(flg,5);
1156c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
1157e7788613SBarry Smith   if (!snes->ops->computejacobian) PetscFunctionReturn(0);
1158ebd3b9afSBarry Smith 
1159ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
1160ebd3b9afSBarry Smith 
1161fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
1162fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
1163fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
1164fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
1165e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1166e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
1167ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1168ebd3b9afSBarry Smith     if (flag) {
1169ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1170ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1171ebd3b9afSBarry Smith     }
1172e35cf81dSBarry Smith     PetscFunctionReturn(0);
1173e35cf81dSBarry Smith   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
1174e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1175e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
1176ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1177ebd3b9afSBarry Smith     if (flag) {
1178ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1179ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1180ebd3b9afSBarry Smith     }
1181e35cf81dSBarry Smith     PetscFunctionReturn(0);
1182e35cf81dSBarry Smith   }
1183e35cf81dSBarry Smith 
1184c4fc05e7SBarry Smith   *flg = DIFFERENT_NONZERO_PATTERN;
1185e35cf81dSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1186d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
1187dc67937bSBarry Smith   CHKMEMQ;
1188e7788613SBarry Smith   ierr = (*snes->ops->computejacobian)(snes,X,A,B,flg,snes->jacP);CHKERRQ(ierr);
1189dc67937bSBarry Smith   CHKMEMQ;
1190d64ed03dSBarry Smith   PetscStackPop;
1191d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1192a8054027SBarry Smith 
11933b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
11943b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
11953b4f5425SBarry Smith     snes->lagpreconditioner = -1;
11963b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
1197a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1198a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
1199a8054027SBarry Smith   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
1200a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1201a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
1202a8054027SBarry Smith   }
1203a8054027SBarry Smith 
12046d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
12056ce558aeSBarry Smith   /* PetscValidHeaderSpecific(*A,MAT_COOKIE,3);
12066ce558aeSBarry Smith     PetscValidHeaderSpecific(*B,MAT_COOKIE,4);   */
12073a40ed3dSBarry Smith   PetscFunctionReturn(0);
12089b94acceSBarry Smith }
12099b94acceSBarry Smith 
12104a2ae208SSatish Balay #undef __FUNCT__
12114a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
12129b94acceSBarry Smith /*@C
12139b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
1214044dda88SLois Curfman McInnes    location to store the matrix.
12159b94acceSBarry Smith 
1216c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
1217c7afd0dbSLois Curfman McInnes 
12189b94acceSBarry Smith    Input Parameters:
1219c7afd0dbSLois Curfman McInnes +  snes - the SNES context
12209b94acceSBarry Smith .  A - Jacobian matrix
12219b94acceSBarry Smith .  B - preconditioner matrix (usually same as the Jacobian)
12229b94acceSBarry Smith .  func - Jacobian evaluation routine
1223c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
12242cd2dfdcSLois Curfman McInnes          Jacobian evaluation routine (may be PETSC_NULL)
12259b94acceSBarry Smith 
12269b94acceSBarry Smith    Calling sequence of func:
12278d76a1e5SLois Curfman McInnes $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
12289b94acceSBarry Smith 
1229c7afd0dbSLois Curfman McInnes +  x - input vector
12309b94acceSBarry Smith .  A - Jacobian matrix
12319b94acceSBarry Smith .  B - preconditioner matrix, usually the same as A
1232ac21db08SLois Curfman McInnes .  flag - flag indicating information about the preconditioner matrix
12332b668275SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
1234c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined Jacobian context
12359b94acceSBarry Smith 
12369b94acceSBarry Smith    Notes:
123794b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the flag
12382cd2dfdcSLois Curfman McInnes    output parameter in the routine func().  Be sure to read this information!
1239ac21db08SLois Curfman McInnes 
1240ac21db08SLois Curfman McInnes    The routine func() takes Mat * as the matrix arguments rather than Mat.
12419b94acceSBarry Smith    This allows the Jacobian evaluation routine to replace A and/or B with a
12429b94acceSBarry Smith    completely new new matrix structure (not just different matrix elements)
12439b94acceSBarry Smith    when appropriate, for instance, if the nonzero structure is changing
12449b94acceSBarry Smith    throughout the global iterations.
12459b94acceSBarry Smith 
124616913363SBarry Smith    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
124716913363SBarry Smith    each matrix.
124816913363SBarry Smith 
124936851e7fSLois Curfman McInnes    Level: beginner
125036851e7fSLois Curfman McInnes 
12519b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
12529b94acceSBarry Smith 
12533ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
12549b94acceSBarry Smith @*/
125563dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
12569b94acceSBarry Smith {
1257dfbe8321SBarry Smith   PetscErrorCode ierr;
12583a7fca6bSBarry Smith 
12593a40ed3dSBarry Smith   PetscFunctionBegin;
12604482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
12614482741eSBarry Smith   if (A) PetscValidHeaderSpecific(A,MAT_COOKIE,2);
12624482741eSBarry Smith   if (B) PetscValidHeaderSpecific(B,MAT_COOKIE,3);
1263c9780b6fSBarry Smith   if (A) PetscCheckSameComm(snes,1,A,2);
126406975374SJed Brown   if (B) PetscCheckSameComm(snes,1,B,3);
1265e7788613SBarry Smith   if (func) snes->ops->computejacobian = func;
12663a7fca6bSBarry Smith   if (ctx)  snes->jacP                 = ctx;
12673a7fca6bSBarry Smith   if (A) {
12687dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
12693a7fca6bSBarry Smith     if (snes->jacobian) {ierr = MatDestroy(snes->jacobian);CHKERRQ(ierr);}
12709b94acceSBarry Smith     snes->jacobian = A;
12713a7fca6bSBarry Smith   }
12723a7fca6bSBarry Smith   if (B) {
12737dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
12743a7fca6bSBarry Smith     if (snes->jacobian_pre) {ierr = MatDestroy(snes->jacobian_pre);CHKERRQ(ierr);}
12759b94acceSBarry Smith     snes->jacobian_pre = B;
12763a7fca6bSBarry Smith   }
12773a40ed3dSBarry Smith   PetscFunctionReturn(0);
12789b94acceSBarry Smith }
127962fef451SLois Curfman McInnes 
12804a2ae208SSatish Balay #undef __FUNCT__
12814a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
1282c2aafc4cSSatish Balay /*@C
1283b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
1284b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
1285b4fd4287SBarry Smith 
1286c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
1287c7afd0dbSLois Curfman McInnes 
1288b4fd4287SBarry Smith    Input Parameter:
1289b4fd4287SBarry Smith .  snes - the nonlinear solver context
1290b4fd4287SBarry Smith 
1291b4fd4287SBarry Smith    Output Parameters:
1292c7afd0dbSLois Curfman McInnes +  A - location to stash Jacobian matrix (or PETSC_NULL)
1293b4fd4287SBarry Smith .  B - location to stash preconditioner matrix (or PETSC_NULL)
129470e92668SMatthew Knepley .  func - location to put Jacobian function (or PETSC_NULL)
129570e92668SMatthew Knepley -  ctx - location to stash Jacobian ctx (or PETSC_NULL)
1296fee21e36SBarry Smith 
129736851e7fSLois Curfman McInnes    Level: advanced
129836851e7fSLois Curfman McInnes 
1299b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian()
1300b4fd4287SBarry Smith @*/
130170e92668SMatthew Knepley PetscErrorCode PETSCSNES_DLLEXPORT SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
1302b4fd4287SBarry Smith {
13033a40ed3dSBarry Smith   PetscFunctionBegin;
13044482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
1305b4fd4287SBarry Smith   if (A)    *A    = snes->jacobian;
1306b4fd4287SBarry Smith   if (B)    *B    = snes->jacobian_pre;
1307e7788613SBarry Smith   if (func) *func = snes->ops->computejacobian;
130870e92668SMatthew Knepley   if (ctx)  *ctx  = snes->jacP;
13093a40ed3dSBarry Smith   PetscFunctionReturn(0);
1310b4fd4287SBarry Smith }
1311b4fd4287SBarry Smith 
13129b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
13139b94acceSBarry Smith 
13144a2ae208SSatish Balay #undef __FUNCT__
13154a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
13169b94acceSBarry Smith /*@
13179b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
1318272ac6f2SLois Curfman McInnes    of a nonlinear solver.
13199b94acceSBarry Smith 
1320fee21e36SBarry Smith    Collective on SNES
1321fee21e36SBarry Smith 
1322c7afd0dbSLois Curfman McInnes    Input Parameters:
132370e92668SMatthew Knepley .  snes - the SNES context
1324c7afd0dbSLois Curfman McInnes 
1325272ac6f2SLois Curfman McInnes    Notes:
1326272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
1327272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
1328272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
1329272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
1330272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
1331272ac6f2SLois Curfman McInnes 
133236851e7fSLois Curfman McInnes    Level: advanced
133336851e7fSLois Curfman McInnes 
13349b94acceSBarry Smith .keywords: SNES, nonlinear, setup
13359b94acceSBarry Smith 
13369b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
13379b94acceSBarry Smith @*/
133870e92668SMatthew Knepley PetscErrorCode PETSCSNES_DLLEXPORT SNESSetUp(SNES snes)
13399b94acceSBarry Smith {
1340dfbe8321SBarry Smith   PetscErrorCode ierr;
13413a40ed3dSBarry Smith 
13423a40ed3dSBarry Smith   PetscFunctionBegin;
13434482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
13444dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
13459b94acceSBarry Smith 
13467adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
134785385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
134885385478SLisandro Dalcin   }
134985385478SLisandro Dalcin 
135085385478SLisandro Dalcin   if (!snes->vec_func && !snes->vec_rhs) {
13511096aae1SMatthew Knepley     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
13521096aae1SMatthew Knepley   }
135385385478SLisandro Dalcin   if (!snes->ops->computefunction && !snes->vec_rhs) {
13541096aae1SMatthew Knepley     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
13551096aae1SMatthew Knepley   }
1356a8c6a408SBarry Smith   if (snes->vec_func == snes->vec_sol) {
135729bbc08cSBarry Smith     SETERRQ(PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
1358a8c6a408SBarry Smith   }
1359a703fe33SLois Curfman McInnes 
1360b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
1361b710008aSBarry Smith 
1362410397dcSLisandro Dalcin   if (snes->ops->setup) {
1363410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
1364410397dcSLisandro Dalcin   }
13657aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
13663a40ed3dSBarry Smith   PetscFunctionReturn(0);
13679b94acceSBarry Smith }
13689b94acceSBarry Smith 
13694a2ae208SSatish Balay #undef __FUNCT__
13704a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
137152baeb72SSatish Balay /*@
13729b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
13739b94acceSBarry Smith    with SNESCreate().
13749b94acceSBarry Smith 
1375c7afd0dbSLois Curfman McInnes    Collective on SNES
1376c7afd0dbSLois Curfman McInnes 
13779b94acceSBarry Smith    Input Parameter:
13789b94acceSBarry Smith .  snes - the SNES context
13799b94acceSBarry Smith 
138036851e7fSLois Curfman McInnes    Level: beginner
138136851e7fSLois Curfman McInnes 
13829b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
13839b94acceSBarry Smith 
138463a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
13859b94acceSBarry Smith @*/
138663dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESDestroy(SNES snes)
13879b94acceSBarry Smith {
13886849ba73SBarry Smith   PetscErrorCode ierr;
13893a40ed3dSBarry Smith 
13903a40ed3dSBarry Smith   PetscFunctionBegin;
13914482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
13927adad957SLisandro Dalcin   if (--((PetscObject)snes)->refct > 0) PetscFunctionReturn(0);
1393d4bb536fSBarry Smith 
1394be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
13950f5bd95cSBarry Smith   ierr = PetscObjectDepublish(snes);CHKERRQ(ierr);
1396e7788613SBarry Smith   if (snes->ops->destroy) {ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);}
139785385478SLisandro Dalcin 
139885385478SLisandro Dalcin   if (snes->vec_rhs) {ierr = VecDestroy(snes->vec_rhs);CHKERRQ(ierr);}
139985385478SLisandro Dalcin   if (snes->vec_sol) {ierr = VecDestroy(snes->vec_sol);CHKERRQ(ierr);}
140085385478SLisandro Dalcin   if (snes->vec_func) {ierr = VecDestroy(snes->vec_func);CHKERRQ(ierr);}
14013a7fca6bSBarry Smith   if (snes->jacobian) {ierr = MatDestroy(snes->jacobian);CHKERRQ(ierr);}
14023a7fca6bSBarry Smith   if (snes->jacobian_pre) {ierr = MatDestroy(snes->jacobian_pre);CHKERRQ(ierr);}
14031cee3971SBarry Smith   if (snes->ksp) {ierr = KSPDestroy(snes->ksp);CHKERRQ(ierr);}
140485385478SLisandro Dalcin   ierr = PetscFree(snes->kspconvctx);CHKERRQ(ierr);
1405522c5e43SBarry Smith   if (snes->vwork) {ierr = VecDestroyVecs(snes->vwork,snes->nvwork);CHKERRQ(ierr);}
1406a6570f20SBarry Smith   ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);
14077f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);}
1408a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
14093a40ed3dSBarry Smith   PetscFunctionReturn(0);
14109b94acceSBarry Smith }
14119b94acceSBarry Smith 
14129b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
14139b94acceSBarry Smith 
14144a2ae208SSatish Balay #undef __FUNCT__
1415a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
1416a8054027SBarry Smith /*@
1417a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
1418a8054027SBarry Smith 
1419a8054027SBarry Smith    Collective on SNES
1420a8054027SBarry Smith 
1421a8054027SBarry Smith    Input Parameters:
1422a8054027SBarry Smith +  snes - the SNES context
1423a8054027SBarry Smith -  lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
14243b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
1425a8054027SBarry Smith 
1426a8054027SBarry Smith    Options Database Keys:
1427a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
1428a8054027SBarry Smith 
1429a8054027SBarry Smith    Notes:
1430a8054027SBarry Smith    The default is 1
1431a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1432a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
1433a8054027SBarry Smith 
1434a8054027SBarry Smith    Level: intermediate
1435a8054027SBarry Smith 
1436a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1437a8054027SBarry Smith 
1438e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
1439a8054027SBarry Smith 
1440a8054027SBarry Smith @*/
1441a8054027SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESSetLagPreconditioner(SNES snes,PetscInt lag)
1442a8054027SBarry Smith {
1443a8054027SBarry Smith   PetscFunctionBegin;
1444a8054027SBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
14453b4f5425SBarry Smith   if (lag < -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
1446a8054027SBarry Smith   if (!lag) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
1447a8054027SBarry Smith   snes->lagpreconditioner = lag;
1448a8054027SBarry Smith   PetscFunctionReturn(0);
1449a8054027SBarry Smith }
1450a8054027SBarry Smith 
1451a8054027SBarry Smith #undef __FUNCT__
1452a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
1453a8054027SBarry Smith /*@
1454a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
1455a8054027SBarry Smith 
1456a8054027SBarry Smith    Collective on SNES
1457a8054027SBarry Smith 
1458a8054027SBarry Smith    Input Parameter:
1459a8054027SBarry Smith .  snes - the SNES context
1460a8054027SBarry Smith 
1461a8054027SBarry Smith    Output Parameter:
1462a8054027SBarry Smith .   lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
14633b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
1464a8054027SBarry Smith 
1465a8054027SBarry Smith    Options Database Keys:
1466a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
1467a8054027SBarry Smith 
1468a8054027SBarry Smith    Notes:
1469a8054027SBarry Smith    The default is 1
1470a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1471a8054027SBarry Smith 
1472a8054027SBarry Smith    Level: intermediate
1473a8054027SBarry Smith 
1474a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1475a8054027SBarry Smith 
1476a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
1477a8054027SBarry Smith 
1478a8054027SBarry Smith @*/
1479a8054027SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
1480a8054027SBarry Smith {
1481a8054027SBarry Smith   PetscFunctionBegin;
1482a8054027SBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
1483a8054027SBarry Smith   *lag = snes->lagpreconditioner;
1484a8054027SBarry Smith   PetscFunctionReturn(0);
1485a8054027SBarry Smith }
1486a8054027SBarry Smith 
1487a8054027SBarry Smith #undef __FUNCT__
1488e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
1489e35cf81dSBarry Smith /*@
1490e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
1491e35cf81dSBarry Smith      often the preconditioner is rebuilt.
1492e35cf81dSBarry Smith 
1493e35cf81dSBarry Smith    Collective on SNES
1494e35cf81dSBarry Smith 
1495e35cf81dSBarry Smith    Input Parameters:
1496e35cf81dSBarry Smith +  snes - the SNES context
1497e35cf81dSBarry Smith -  lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
1498fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
1499e35cf81dSBarry Smith 
1500e35cf81dSBarry Smith    Options Database Keys:
1501e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
1502e35cf81dSBarry Smith 
1503e35cf81dSBarry Smith    Notes:
1504e35cf81dSBarry Smith    The default is 1
1505e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1506fe3ffe1eSBarry Smith    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
1507fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
1508e35cf81dSBarry Smith 
1509e35cf81dSBarry Smith    Level: intermediate
1510e35cf81dSBarry Smith 
1511e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1512e35cf81dSBarry Smith 
1513e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
1514e35cf81dSBarry Smith 
1515e35cf81dSBarry Smith @*/
1516e35cf81dSBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESSetLagJacobian(SNES snes,PetscInt lag)
1517e35cf81dSBarry Smith {
1518e35cf81dSBarry Smith   PetscFunctionBegin;
1519e35cf81dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
1520fe3ffe1eSBarry Smith   if (lag < -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
1521e35cf81dSBarry Smith   if (!lag) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
1522e35cf81dSBarry Smith   snes->lagjacobian = lag;
1523e35cf81dSBarry Smith   PetscFunctionReturn(0);
1524e35cf81dSBarry Smith }
1525e35cf81dSBarry Smith 
1526e35cf81dSBarry Smith #undef __FUNCT__
1527e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
1528e35cf81dSBarry Smith /*@
1529e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
1530e35cf81dSBarry Smith 
1531e35cf81dSBarry Smith    Collective on SNES
1532e35cf81dSBarry Smith 
1533e35cf81dSBarry Smith    Input Parameter:
1534e35cf81dSBarry Smith .  snes - the SNES context
1535e35cf81dSBarry Smith 
1536e35cf81dSBarry Smith    Output Parameter:
1537e35cf81dSBarry Smith .   lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
1538e35cf81dSBarry Smith          the Jacobian is built etc.
1539e35cf81dSBarry Smith 
1540e35cf81dSBarry Smith    Options Database Keys:
1541e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
1542e35cf81dSBarry Smith 
1543e35cf81dSBarry Smith    Notes:
1544e35cf81dSBarry Smith    The default is 1
1545e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1546e35cf81dSBarry Smith 
1547e35cf81dSBarry Smith    Level: intermediate
1548e35cf81dSBarry Smith 
1549e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1550e35cf81dSBarry Smith 
1551e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
1552e35cf81dSBarry Smith 
1553e35cf81dSBarry Smith @*/
1554e35cf81dSBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESGetLagJacobian(SNES snes,PetscInt *lag)
1555e35cf81dSBarry Smith {
1556e35cf81dSBarry Smith   PetscFunctionBegin;
1557e35cf81dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
1558e35cf81dSBarry Smith   *lag = snes->lagjacobian;
1559e35cf81dSBarry Smith   PetscFunctionReturn(0);
1560e35cf81dSBarry Smith }
1561e35cf81dSBarry Smith 
1562e35cf81dSBarry Smith #undef __FUNCT__
15634a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
15649b94acceSBarry Smith /*@
1565d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
15669b94acceSBarry Smith 
1567c7afd0dbSLois Curfman McInnes    Collective on SNES
1568c7afd0dbSLois Curfman McInnes 
15699b94acceSBarry Smith    Input Parameters:
1570c7afd0dbSLois Curfman McInnes +  snes - the SNES context
157170441072SBarry Smith .  abstol - absolute convergence tolerance
157233174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
157333174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
157433174efeSLois Curfman McInnes            of the change in the solution between steps
157533174efeSLois Curfman McInnes .  maxit - maximum number of iterations
1576c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
1577fee21e36SBarry Smith 
157833174efeSLois Curfman McInnes    Options Database Keys:
157970441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
1580c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
1581c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
1582c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
1583c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
15849b94acceSBarry Smith 
1585d7a720efSLois Curfman McInnes    Notes:
15869b94acceSBarry Smith    The default maximum number of iterations is 50.
15879b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
15889b94acceSBarry Smith 
158936851e7fSLois Curfman McInnes    Level: intermediate
159036851e7fSLois Curfman McInnes 
159133174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
15929b94acceSBarry Smith 
15932492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
15949b94acceSBarry Smith @*/
159563dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
15969b94acceSBarry Smith {
15973a40ed3dSBarry Smith   PetscFunctionBegin;
15984482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
159970441072SBarry Smith   if (abstol != PETSC_DEFAULT)  snes->abstol      = abstol;
1600d7a720efSLois Curfman McInnes   if (rtol != PETSC_DEFAULT)  snes->rtol      = rtol;
1601d7a720efSLois Curfman McInnes   if (stol != PETSC_DEFAULT)  snes->xtol      = stol;
1602d7a720efSLois Curfman McInnes   if (maxit != PETSC_DEFAULT) snes->max_its   = maxit;
1603d7a720efSLois Curfman McInnes   if (maxf != PETSC_DEFAULT)  snes->max_funcs = maxf;
16043a40ed3dSBarry Smith   PetscFunctionReturn(0);
16059b94acceSBarry Smith }
16069b94acceSBarry Smith 
16074a2ae208SSatish Balay #undef __FUNCT__
16084a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
16099b94acceSBarry Smith /*@
161033174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
161133174efeSLois Curfman McInnes 
1612c7afd0dbSLois Curfman McInnes    Not Collective
1613c7afd0dbSLois Curfman McInnes 
161433174efeSLois Curfman McInnes    Input Parameters:
1615c7afd0dbSLois Curfman McInnes +  snes - the SNES context
161685385478SLisandro Dalcin .  atol - absolute convergence tolerance
161733174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
161833174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
161933174efeSLois Curfman McInnes            of the change in the solution between steps
162033174efeSLois Curfman McInnes .  maxit - maximum number of iterations
1621c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
1622fee21e36SBarry Smith 
162333174efeSLois Curfman McInnes    Notes:
162433174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
162533174efeSLois Curfman McInnes 
162636851e7fSLois Curfman McInnes    Level: intermediate
162736851e7fSLois Curfman McInnes 
162833174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
162933174efeSLois Curfman McInnes 
163033174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
163133174efeSLois Curfman McInnes @*/
163285385478SLisandro Dalcin PetscErrorCode PETSCSNES_DLLEXPORT SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
163333174efeSLois Curfman McInnes {
16343a40ed3dSBarry Smith   PetscFunctionBegin;
16354482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
163685385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
163733174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
163833174efeSLois Curfman McInnes   if (stol)  *stol  = snes->xtol;
163933174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
164033174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
16413a40ed3dSBarry Smith   PetscFunctionReturn(0);
164233174efeSLois Curfman McInnes }
164333174efeSLois Curfman McInnes 
16444a2ae208SSatish Balay #undef __FUNCT__
16454a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
164633174efeSLois Curfman McInnes /*@
16479b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
16489b94acceSBarry Smith 
1649fee21e36SBarry Smith    Collective on SNES
1650fee21e36SBarry Smith 
1651c7afd0dbSLois Curfman McInnes    Input Parameters:
1652c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1653c7afd0dbSLois Curfman McInnes -  tol - tolerance
1654c7afd0dbSLois Curfman McInnes 
16559b94acceSBarry Smith    Options Database Key:
1656c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
16579b94acceSBarry Smith 
165836851e7fSLois Curfman McInnes    Level: intermediate
165936851e7fSLois Curfman McInnes 
16609b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
16619b94acceSBarry Smith 
16622492ecdbSBarry Smith .seealso: SNESSetTolerances()
16639b94acceSBarry Smith @*/
166463dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
16659b94acceSBarry Smith {
16663a40ed3dSBarry Smith   PetscFunctionBegin;
16674482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
16689b94acceSBarry Smith   snes->deltatol = tol;
16693a40ed3dSBarry Smith   PetscFunctionReturn(0);
16709b94acceSBarry Smith }
16719b94acceSBarry Smith 
1672df9fa365SBarry Smith /*
1673df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
1674df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
1675df9fa365SBarry Smith    macros instead of functions
1676df9fa365SBarry Smith */
16774a2ae208SSatish Balay #undef __FUNCT__
1678a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
1679a6570f20SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
1680ce1608b8SBarry Smith {
1681dfbe8321SBarry Smith   PetscErrorCode ierr;
1682ce1608b8SBarry Smith 
1683ce1608b8SBarry Smith   PetscFunctionBegin;
16844482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
1685a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
1686ce1608b8SBarry Smith   PetscFunctionReturn(0);
1687ce1608b8SBarry Smith }
1688ce1608b8SBarry Smith 
16894a2ae208SSatish Balay #undef __FUNCT__
1690a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
1691a6570f20SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
1692df9fa365SBarry Smith {
1693dfbe8321SBarry Smith   PetscErrorCode ierr;
1694df9fa365SBarry Smith 
1695df9fa365SBarry Smith   PetscFunctionBegin;
1696a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
1697df9fa365SBarry Smith   PetscFunctionReturn(0);
1698df9fa365SBarry Smith }
1699df9fa365SBarry Smith 
17004a2ae208SSatish Balay #undef __FUNCT__
1701a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
1702a6570f20SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorLGDestroy(PetscDrawLG draw)
1703df9fa365SBarry Smith {
1704dfbe8321SBarry Smith   PetscErrorCode ierr;
1705df9fa365SBarry Smith 
1706df9fa365SBarry Smith   PetscFunctionBegin;
1707a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
1708df9fa365SBarry Smith   PetscFunctionReturn(0);
1709df9fa365SBarry Smith }
1710df9fa365SBarry Smith 
1711b271bb04SBarry Smith extern PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
1712b271bb04SBarry Smith #undef __FUNCT__
1713b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
1714b271bb04SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
1715b271bb04SBarry Smith {
1716b271bb04SBarry Smith   PetscDrawLG      lg;
1717b271bb04SBarry Smith   PetscErrorCode   ierr;
1718b271bb04SBarry Smith   PetscReal        x,y,per;
1719b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
1720b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
1721b271bb04SBarry Smith   PetscDraw        draw;
1722b271bb04SBarry Smith   PetscFunctionBegin;
1723b271bb04SBarry Smith   if (!monctx) {
1724b271bb04SBarry Smith     MPI_Comm    comm;
1725b271bb04SBarry Smith 
1726b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
1727b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
1728b271bb04SBarry Smith   }
1729b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
1730b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
1731b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
1732b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
1733b271bb04SBarry Smith   x = (PetscReal) n;
1734b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
1735b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
1736b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
1737b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
1738b271bb04SBarry Smith   }
1739b271bb04SBarry Smith 
1740b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
1741b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
1742b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
1743b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
1744b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
1745b271bb04SBarry Smith   x = (PetscReal) n;
1746b271bb04SBarry Smith   y = 100.0*per;
1747b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
1748b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
1749b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
1750b271bb04SBarry Smith   }
1751b271bb04SBarry Smith 
1752b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
1753b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
1754b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
1755b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
1756b271bb04SBarry Smith   x = (PetscReal) n;
1757b271bb04SBarry Smith   y = (prev - rnorm)/prev;
1758b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
1759b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
1760b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
1761b271bb04SBarry Smith   }
1762b271bb04SBarry Smith 
1763b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
1764b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
1765b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
1766b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
1767b271bb04SBarry Smith   x = (PetscReal) n;
1768b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
1769b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
1770b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
1771b271bb04SBarry Smith   }
1772b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
1773b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
1774b271bb04SBarry Smith   }
1775b271bb04SBarry Smith   prev = rnorm;
1776b271bb04SBarry Smith   PetscFunctionReturn(0);
1777b271bb04SBarry Smith }
1778b271bb04SBarry Smith 
1779b271bb04SBarry Smith #undef __FUNCT__
1780b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
1781b271bb04SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
1782b271bb04SBarry Smith {
1783b271bb04SBarry Smith   PetscErrorCode ierr;
1784b271bb04SBarry Smith 
1785b271bb04SBarry Smith   PetscFunctionBegin;
1786b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
1787b271bb04SBarry Smith   PetscFunctionReturn(0);
1788b271bb04SBarry Smith }
1789b271bb04SBarry Smith 
1790b271bb04SBarry Smith #undef __FUNCT__
1791b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
1792b271bb04SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorLGRangeDestroy(PetscDrawLG draw)
1793b271bb04SBarry Smith {
1794b271bb04SBarry Smith   PetscErrorCode ierr;
1795b271bb04SBarry Smith 
1796b271bb04SBarry Smith   PetscFunctionBegin;
1797b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
1798b271bb04SBarry Smith   PetscFunctionReturn(0);
1799b271bb04SBarry Smith }
1800b271bb04SBarry Smith 
18019b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
18029b94acceSBarry Smith 
18034a2ae208SSatish Balay #undef __FUNCT__
1804a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
18059b94acceSBarry Smith /*@C
1806a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
18079b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
18089b94acceSBarry Smith    progress.
18099b94acceSBarry Smith 
1810fee21e36SBarry Smith    Collective on SNES
1811fee21e36SBarry Smith 
1812c7afd0dbSLois Curfman McInnes    Input Parameters:
1813c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1814c7afd0dbSLois Curfman McInnes .  func - monitoring routine
1815b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
1816e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
1817b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
1818b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
18199b94acceSBarry Smith 
1820c7afd0dbSLois Curfman McInnes    Calling sequence of func:
1821a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
1822c7afd0dbSLois Curfman McInnes 
1823c7afd0dbSLois Curfman McInnes +    snes - the SNES context
1824c7afd0dbSLois Curfman McInnes .    its - iteration number
1825c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
182640a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
18279b94acceSBarry Smith 
18289665c990SLois Curfman McInnes    Options Database Keys:
1829a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
1830a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
1831a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
1832a6570f20SBarry Smith _    -snes_monitor_cancel - cancels all monitors that have
1833c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
1834a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
1835c7afd0dbSLois Curfman McInnes                             does not cancel those set via
1836c7afd0dbSLois Curfman McInnes                             the options database.
18379665c990SLois Curfman McInnes 
1838639f9d9dSBarry Smith    Notes:
18396bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
1840a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
18416bc08f3fSLois Curfman McInnes    order in which they were set.
1842639f9d9dSBarry Smith 
1843025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
1844025f1a04SBarry Smith 
184536851e7fSLois Curfman McInnes    Level: intermediate
184636851e7fSLois Curfman McInnes 
18479b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
18489b94acceSBarry Smith 
1849a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
18509b94acceSBarry Smith @*/
1851b90d0a6eSBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void*))
18529b94acceSBarry Smith {
1853b90d0a6eSBarry Smith   PetscInt i;
1854b90d0a6eSBarry Smith 
18553a40ed3dSBarry Smith   PetscFunctionBegin;
18564482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
1857639f9d9dSBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) {
185829bbc08cSBarry Smith     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
1859639f9d9dSBarry Smith   }
1860b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
1861b90d0a6eSBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) PetscFunctionReturn(0);
1862b90d0a6eSBarry Smith 
1863b90d0a6eSBarry Smith     /* check if both default monitors that share common ASCII viewer */
1864b90d0a6eSBarry Smith     if (monitor == snes->monitor[i] && monitor == SNESMonitorDefault) {
1865b90d0a6eSBarry Smith       if (mctx && snes->monitorcontext[i]) {
1866b90d0a6eSBarry Smith         PetscErrorCode          ierr;
1867b90d0a6eSBarry Smith         PetscViewerASCIIMonitor viewer1 = (PetscViewerASCIIMonitor) mctx;
1868b90d0a6eSBarry Smith         PetscViewerASCIIMonitor viewer2 = (PetscViewerASCIIMonitor) snes->monitorcontext[i];
1869b90d0a6eSBarry Smith         if (viewer1->viewer == viewer2->viewer) {
1870b90d0a6eSBarry Smith           ierr = (*monitordestroy)(mctx);CHKERRQ(ierr);
1871b90d0a6eSBarry Smith           PetscFunctionReturn(0);
1872b90d0a6eSBarry Smith         }
1873b90d0a6eSBarry Smith       }
1874b90d0a6eSBarry Smith     }
1875b90d0a6eSBarry Smith   }
1876b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
1877b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
1878639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
18793a40ed3dSBarry Smith   PetscFunctionReturn(0);
18809b94acceSBarry Smith }
18819b94acceSBarry Smith 
18824a2ae208SSatish Balay #undef __FUNCT__
1883a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
18845cd90555SBarry Smith /*@C
1885a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
18865cd90555SBarry Smith 
1887c7afd0dbSLois Curfman McInnes    Collective on SNES
1888c7afd0dbSLois Curfman McInnes 
18895cd90555SBarry Smith    Input Parameters:
18905cd90555SBarry Smith .  snes - the SNES context
18915cd90555SBarry Smith 
18921a480d89SAdministrator    Options Database Key:
1893a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
1894a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
1895c7afd0dbSLois Curfman McInnes     set via the options database
18965cd90555SBarry Smith 
18975cd90555SBarry Smith    Notes:
18985cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
18995cd90555SBarry Smith 
190036851e7fSLois Curfman McInnes    Level: intermediate
190136851e7fSLois Curfman McInnes 
19025cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
19035cd90555SBarry Smith 
1904a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
19055cd90555SBarry Smith @*/
1906a6570f20SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorCancel(SNES snes)
19075cd90555SBarry Smith {
1908d952e501SBarry Smith   PetscErrorCode ierr;
1909d952e501SBarry Smith   PetscInt       i;
1910d952e501SBarry Smith 
19115cd90555SBarry Smith   PetscFunctionBegin;
19124482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
1913d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
1914d952e501SBarry Smith     if (snes->monitordestroy[i]) {
1915d952e501SBarry Smith       ierr = (*snes->monitordestroy[i])(snes->monitorcontext[i]);CHKERRQ(ierr);
1916d952e501SBarry Smith     }
1917d952e501SBarry Smith   }
19185cd90555SBarry Smith   snes->numbermonitors = 0;
19195cd90555SBarry Smith   PetscFunctionReturn(0);
19205cd90555SBarry Smith }
19215cd90555SBarry Smith 
19224a2ae208SSatish Balay #undef __FUNCT__
19234a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
19249b94acceSBarry Smith /*@C
19259b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
19269b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
19279b94acceSBarry Smith 
1928fee21e36SBarry Smith    Collective on SNES
1929fee21e36SBarry Smith 
1930c7afd0dbSLois Curfman McInnes    Input Parameters:
1931c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1932c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
19337f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
19347f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
19359b94acceSBarry Smith 
1936c7afd0dbSLois Curfman McInnes    Calling sequence of func:
193706ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
1938c7afd0dbSLois Curfman McInnes 
1939c7afd0dbSLois Curfman McInnes +    snes - the SNES context
194006ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
1941c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
1942184914b5SBarry Smith .    reason - reason for convergence/divergence
1943c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
19444b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
19454b27c08aSLois Curfman McInnes -    f - 2-norm of function
19469b94acceSBarry Smith 
194736851e7fSLois Curfman McInnes    Level: advanced
194836851e7fSLois Curfman McInnes 
19499b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
19509b94acceSBarry Smith 
195185385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
19529b94acceSBarry Smith @*/
19537f7931b9SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
19549b94acceSBarry Smith {
19557f7931b9SBarry Smith   PetscErrorCode ierr;
19567f7931b9SBarry Smith 
19573a40ed3dSBarry Smith   PetscFunctionBegin;
19584482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
195985385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
19607f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
19617f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
19627f7931b9SBarry Smith   }
196385385478SLisandro Dalcin   snes->ops->converged        = func;
19647f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
196585385478SLisandro Dalcin   snes->cnvP                  = cctx;
19663a40ed3dSBarry Smith   PetscFunctionReturn(0);
19679b94acceSBarry Smith }
19689b94acceSBarry Smith 
19694a2ae208SSatish Balay #undef __FUNCT__
19704a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
197152baeb72SSatish Balay /*@
1972184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
1973184914b5SBarry Smith 
1974184914b5SBarry Smith    Not Collective
1975184914b5SBarry Smith 
1976184914b5SBarry Smith    Input Parameter:
1977184914b5SBarry Smith .  snes - the SNES context
1978184914b5SBarry Smith 
1979184914b5SBarry Smith    Output Parameter:
19804d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
1981184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
1982184914b5SBarry Smith 
1983184914b5SBarry Smith    Level: intermediate
1984184914b5SBarry Smith 
1985184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
1986184914b5SBarry Smith 
1987184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
1988184914b5SBarry Smith 
198985385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
1990184914b5SBarry Smith @*/
199163dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
1992184914b5SBarry Smith {
1993184914b5SBarry Smith   PetscFunctionBegin;
19944482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
19954482741eSBarry Smith   PetscValidPointer(reason,2);
1996184914b5SBarry Smith   *reason = snes->reason;
1997184914b5SBarry Smith   PetscFunctionReturn(0);
1998184914b5SBarry Smith }
1999184914b5SBarry Smith 
20004a2ae208SSatish Balay #undef __FUNCT__
20014a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
2002c9005455SLois Curfman McInnes /*@
2003c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
2004c9005455SLois Curfman McInnes 
2005fee21e36SBarry Smith    Collective on SNES
2006fee21e36SBarry Smith 
2007c7afd0dbSLois Curfman McInnes    Input Parameters:
2008c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
20098c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
2010cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
2011758f92a0SBarry Smith .  na  - size of a and its
201264731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
2013758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
2014c7afd0dbSLois Curfman McInnes 
2015c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
2016c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
2017c9005455SLois Curfman McInnes    during the section of code that is being timed.
2018c9005455SLois Curfman McInnes 
201936851e7fSLois Curfman McInnes    Level: intermediate
202036851e7fSLois Curfman McInnes 
2021c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
2022758f92a0SBarry Smith 
202308405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
2024758f92a0SBarry Smith 
2025c9005455SLois Curfman McInnes @*/
2026a562a398SLisandro Dalcin PetscErrorCode PETSCSNES_DLLEXPORT SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscTruth reset)
2027c9005455SLois Curfman McInnes {
20283a40ed3dSBarry Smith   PetscFunctionBegin;
20294482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
20304482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
2031a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
2032c9005455SLois Curfman McInnes   snes->conv_hist       = a;
2033758f92a0SBarry Smith   snes->conv_hist_its   = its;
2034758f92a0SBarry Smith   snes->conv_hist_max   = na;
2035a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
2036758f92a0SBarry Smith   snes->conv_hist_reset = reset;
2037758f92a0SBarry Smith   PetscFunctionReturn(0);
2038758f92a0SBarry Smith }
2039758f92a0SBarry Smith 
20404a2ae208SSatish Balay #undef __FUNCT__
20414a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
20420c4c9dddSBarry Smith /*@C
2043758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
2044758f92a0SBarry Smith 
2045758f92a0SBarry Smith    Collective on SNES
2046758f92a0SBarry Smith 
2047758f92a0SBarry Smith    Input Parameter:
2048758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
2049758f92a0SBarry Smith 
2050758f92a0SBarry Smith    Output Parameters:
2051758f92a0SBarry Smith .  a   - array to hold history
2052758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
2053758f92a0SBarry Smith          negative if not converged) for each solve.
2054758f92a0SBarry Smith -  na  - size of a and its
2055758f92a0SBarry Smith 
2056758f92a0SBarry Smith    Notes:
2057758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
2058758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
2059758f92a0SBarry Smith 
2060758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
2061758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
2062758f92a0SBarry Smith    during the section of code that is being timed.
2063758f92a0SBarry Smith 
2064758f92a0SBarry Smith    Level: intermediate
2065758f92a0SBarry Smith 
2066758f92a0SBarry Smith .keywords: SNES, get, convergence, history
2067758f92a0SBarry Smith 
2068758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
2069758f92a0SBarry Smith 
2070758f92a0SBarry Smith @*/
207163dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
2072758f92a0SBarry Smith {
2073758f92a0SBarry Smith   PetscFunctionBegin;
20744482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
2075758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
2076758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
2077758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
20783a40ed3dSBarry Smith   PetscFunctionReturn(0);
2079c9005455SLois Curfman McInnes }
2080c9005455SLois Curfman McInnes 
2081e74ef692SMatthew Knepley #undef __FUNCT__
2082e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
2083ac226902SBarry Smith /*@C
208476b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
20857e4bb74cSBarry Smith   at the beginning o every iteration of the nonlinear solve. Specifically
20867e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
208776b2cf59SMatthew Knepley 
208876b2cf59SMatthew Knepley   Collective on SNES
208976b2cf59SMatthew Knepley 
209076b2cf59SMatthew Knepley   Input Parameters:
209176b2cf59SMatthew Knepley . snes - The nonlinear solver context
209276b2cf59SMatthew Knepley . func - The function
209376b2cf59SMatthew Knepley 
209476b2cf59SMatthew Knepley   Calling sequence of func:
2095b5d30489SBarry Smith . func (SNES snes, PetscInt step);
209676b2cf59SMatthew Knepley 
209776b2cf59SMatthew Knepley . step - The current step of the iteration
209876b2cf59SMatthew Knepley 
2099*fe97e370SBarry Smith   Level: advanced
2100*fe97e370SBarry Smith 
2101*fe97e370SBarry Smith   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()
2102*fe97e370SBarry Smith         This is not used by most users.
210376b2cf59SMatthew Knepley 
210476b2cf59SMatthew Knepley .keywords: SNES, update
2105b5d30489SBarry Smith 
210685385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
210776b2cf59SMatthew Knepley @*/
210863dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
210976b2cf59SMatthew Knepley {
211076b2cf59SMatthew Knepley   PetscFunctionBegin;
21114482741eSBarry Smith   PetscValidHeaderSpecific(snes, SNES_COOKIE,1);
2112e7788613SBarry Smith   snes->ops->update = func;
211376b2cf59SMatthew Knepley   PetscFunctionReturn(0);
211476b2cf59SMatthew Knepley }
211576b2cf59SMatthew Knepley 
2116e74ef692SMatthew Knepley #undef __FUNCT__
2117e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
211876b2cf59SMatthew Knepley /*@
211976b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
212076b2cf59SMatthew Knepley 
212176b2cf59SMatthew Knepley   Not collective
212276b2cf59SMatthew Knepley 
212376b2cf59SMatthew Knepley   Input Parameters:
212476b2cf59SMatthew Knepley . snes - The nonlinear solver context
212576b2cf59SMatthew Knepley . step - The current step of the iteration
212676b2cf59SMatthew Knepley 
2127205452f4SMatthew Knepley   Level: intermediate
2128205452f4SMatthew Knepley 
212976b2cf59SMatthew Knepley .keywords: SNES, update
2130a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
213176b2cf59SMatthew Knepley @*/
213263dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESDefaultUpdate(SNES snes, PetscInt step)
213376b2cf59SMatthew Knepley {
213476b2cf59SMatthew Knepley   PetscFunctionBegin;
213576b2cf59SMatthew Knepley   PetscFunctionReturn(0);
213676b2cf59SMatthew Knepley }
213776b2cf59SMatthew Knepley 
21384a2ae208SSatish Balay #undef __FUNCT__
21394a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
21409b94acceSBarry Smith /*
21419b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
21429b94acceSBarry Smith    positive parameter delta.
21439b94acceSBarry Smith 
21449b94acceSBarry Smith     Input Parameters:
2145c7afd0dbSLois Curfman McInnes +   snes - the SNES context
21469b94acceSBarry Smith .   y - approximate solution of linear system
21479b94acceSBarry Smith .   fnorm - 2-norm of current function
2148c7afd0dbSLois Curfman McInnes -   delta - trust region size
21499b94acceSBarry Smith 
21509b94acceSBarry Smith     Output Parameters:
2151c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
21529b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
21539b94acceSBarry Smith     region, and exceeds zero otherwise.
2154c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
21559b94acceSBarry Smith 
21569b94acceSBarry Smith     Note:
21574b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
21589b94acceSBarry Smith     is set to be the maximum allowable step size.
21599b94acceSBarry Smith 
21609b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
21619b94acceSBarry Smith */
2162dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
21639b94acceSBarry Smith {
2164064f8208SBarry Smith   PetscReal      nrm;
2165ea709b57SSatish Balay   PetscScalar    cnorm;
2166dfbe8321SBarry Smith   PetscErrorCode ierr;
21673a40ed3dSBarry Smith 
21683a40ed3dSBarry Smith   PetscFunctionBegin;
21694482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
21704482741eSBarry Smith   PetscValidHeaderSpecific(y,VEC_COOKIE,2);
2171c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
2172184914b5SBarry Smith 
2173064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
2174064f8208SBarry Smith   if (nrm > *delta) {
2175064f8208SBarry Smith      nrm = *delta/nrm;
2176064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
2177064f8208SBarry Smith      cnorm = nrm;
21782dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
21799b94acceSBarry Smith      *ynorm = *delta;
21809b94acceSBarry Smith   } else {
21819b94acceSBarry Smith      *gpnorm = 0.0;
2182064f8208SBarry Smith      *ynorm = nrm;
21839b94acceSBarry Smith   }
21843a40ed3dSBarry Smith   PetscFunctionReturn(0);
21859b94acceSBarry Smith }
21869b94acceSBarry Smith 
21874a2ae208SSatish Balay #undef __FUNCT__
21884a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
21896ce558aeSBarry Smith /*@C
2190f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
2191f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
21929b94acceSBarry Smith 
2193c7afd0dbSLois Curfman McInnes    Collective on SNES
2194c7afd0dbSLois Curfman McInnes 
2195b2002411SLois Curfman McInnes    Input Parameters:
2196c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2197f69a0ea3SMatthew Knepley .  b - the constant part of the equation, or PETSC_NULL to use zero.
219885385478SLisandro Dalcin -  x - the solution vector.
21999b94acceSBarry Smith 
2200b2002411SLois Curfman McInnes    Notes:
22018ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
22028ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
22038ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
22048ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
22058ddd3da0SLois Curfman McInnes 
220636851e7fSLois Curfman McInnes    Level: beginner
220736851e7fSLois Curfman McInnes 
22089b94acceSBarry Smith .keywords: SNES, nonlinear, solve
22099b94acceSBarry Smith 
221085385478SLisandro Dalcin .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian()
22119b94acceSBarry Smith @*/
2212f69a0ea3SMatthew Knepley PetscErrorCode PETSCSNES_DLLEXPORT SNESSolve(SNES snes,Vec b,Vec x)
22139b94acceSBarry Smith {
2214dfbe8321SBarry Smith   PetscErrorCode ierr;
2215f1af5d2fSBarry Smith   PetscTruth     flg;
2216eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
2217eabae89aSBarry Smith   PetscViewer    viewer;
2218052efed2SBarry Smith 
22193a40ed3dSBarry Smith   PetscFunctionBegin;
22204482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
2221f69a0ea3SMatthew Knepley   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2222f69a0ea3SMatthew Knepley   PetscCheckSameComm(snes,1,x,3);
222385385478SLisandro Dalcin   if (b) PetscValidHeaderSpecific(b,VEC_COOKIE,2);
222485385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
222585385478SLisandro Dalcin 
222685385478SLisandro Dalcin   /* set solution vector */
222785385478SLisandro Dalcin   ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);
222885385478SLisandro Dalcin   if (snes->vec_sol) { ierr = VecDestroy(snes->vec_sol);CHKERRQ(ierr); }
222985385478SLisandro Dalcin   snes->vec_sol = x;
223085385478SLisandro Dalcin   /* set afine vector if provided */
223185385478SLisandro Dalcin   if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
223285385478SLisandro Dalcin   if (snes->vec_rhs) { ierr = VecDestroy(snes->vec_rhs);CHKERRQ(ierr); }
223385385478SLisandro Dalcin   snes->vec_rhs = b;
223485385478SLisandro Dalcin 
223585385478SLisandro Dalcin   if (!snes->vec_func && snes->vec_rhs) {
223685385478SLisandro Dalcin     ierr = VecDuplicate(b, &snes->vec_func);CHKERRQ(ierr);
223770e92668SMatthew Knepley   }
22383f149594SLisandro Dalcin 
223970e92668SMatthew Knepley   ierr = SNESSetUp(snes);CHKERRQ(ierr);
22403f149594SLisandro Dalcin 
2241abc0a331SBarry Smith   if (snes->conv_hist_reset) snes->conv_hist_len = 0;
224250ffb88aSMatthew Knepley   snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
2243d5e45103SBarry Smith 
22443f149594SLisandro Dalcin   ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
22454936397dSBarry Smith   ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
224685385478SLisandro Dalcin   ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
22474936397dSBarry Smith   if (snes->domainerror){
22484936397dSBarry Smith     snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
22494936397dSBarry Smith     snes->domainerror = PETSC_FALSE;
22504936397dSBarry Smith   }
225185385478SLisandro Dalcin 
22523f149594SLisandro Dalcin   if (!snes->reason) {
22533f149594SLisandro Dalcin     SETERRQ(PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
22543f149594SLisandro Dalcin   }
22553f149594SLisandro Dalcin 
22567adad957SLisandro Dalcin   ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
2257eabae89aSBarry Smith   if (flg && !PetscPreLoadingOn) {
22587adad957SLisandro Dalcin     ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
2259eabae89aSBarry Smith     ierr = SNESView(snes,viewer);CHKERRQ(ierr);
2260eabae89aSBarry Smith     ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr);
2261eabae89aSBarry Smith   }
2262eabae89aSBarry Smith 
226390d69ab7SBarry Smith   flg  = PETSC_FALSE;
226490d69ab7SBarry Smith   ierr = PetscOptionsGetTruth(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
2265da9b6338SBarry Smith   if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
22665968eb51SBarry Smith   if (snes->printreason) {
22675968eb51SBarry Smith     if (snes->reason > 0) {
22687adad957SLisandro Dalcin       ierr = PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr);
22695968eb51SBarry Smith     } else {
22707adad957SLisandro Dalcin       ierr = PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr);
22715968eb51SBarry Smith     }
22725968eb51SBarry Smith   }
22735968eb51SBarry Smith 
22743a40ed3dSBarry Smith   PetscFunctionReturn(0);
22759b94acceSBarry Smith }
22769b94acceSBarry Smith 
22779b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
22789b94acceSBarry Smith 
22794a2ae208SSatish Balay #undef __FUNCT__
22804a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
228182bf6240SBarry Smith /*@C
22824b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
22839b94acceSBarry Smith 
2284fee21e36SBarry Smith    Collective on SNES
2285fee21e36SBarry Smith 
2286c7afd0dbSLois Curfman McInnes    Input Parameters:
2287c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2288454a90a3SBarry Smith -  type - a known method
2289c7afd0dbSLois Curfman McInnes 
2290c7afd0dbSLois Curfman McInnes    Options Database Key:
2291454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
2292c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
2293ae12b187SLois Curfman McInnes 
22949b94acceSBarry Smith    Notes:
2295e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
22964b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
2297c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
22984b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
2299c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
23009b94acceSBarry Smith 
2301ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
2302ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
2303ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
2304ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
2305ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
2306ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
2307ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
2308ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
2309ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
2310b0a32e0cSBarry Smith   appropriate method.
231136851e7fSLois Curfman McInnes 
231236851e7fSLois Curfman McInnes   Level: intermediate
2313a703fe33SLois Curfman McInnes 
2314454a90a3SBarry Smith .keywords: SNES, set, type
2315435da068SBarry Smith 
2316435da068SBarry Smith .seealso: SNESType, SNESCreate()
2317435da068SBarry Smith 
23189b94acceSBarry Smith @*/
2319a313700dSBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESSetType(SNES snes,const SNESType type)
23209b94acceSBarry Smith {
2321dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
23226831982aSBarry Smith   PetscTruth     match;
23233a40ed3dSBarry Smith 
23243a40ed3dSBarry Smith   PetscFunctionBegin;
23254482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
23264482741eSBarry Smith   PetscValidCharPointer(type,2);
232782bf6240SBarry Smith 
23286831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
23290f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
233092ff6ae8SBarry Smith 
23317adad957SLisandro Dalcin   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,(void (**)(void)) &r);CHKERRQ(ierr);
2332958c9bccSBarry Smith   if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
233375396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
233475396ef9SLisandro Dalcin   if (snes->ops->destroy) { ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); }
233575396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
233675396ef9SLisandro Dalcin   snes->ops->setup          = 0;
233775396ef9SLisandro Dalcin   snes->ops->solve          = 0;
233875396ef9SLisandro Dalcin   snes->ops->view           = 0;
233975396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
234075396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
234175396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
234275396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
23433a40ed3dSBarry Smith   ierr = (*r)(snes);CHKERRQ(ierr);
2344454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
23453a40ed3dSBarry Smith   PetscFunctionReturn(0);
23469b94acceSBarry Smith }
23479b94acceSBarry Smith 
2348a847f771SSatish Balay 
23499b94acceSBarry Smith /* --------------------------------------------------------------------- */
23504a2ae208SSatish Balay #undef __FUNCT__
23514a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
235252baeb72SSatish Balay /*@
23539b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
2354f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
23559b94acceSBarry Smith 
2356fee21e36SBarry Smith    Not Collective
2357fee21e36SBarry Smith 
235836851e7fSLois Curfman McInnes    Level: advanced
235936851e7fSLois Curfman McInnes 
23609b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
23619b94acceSBarry Smith 
23629b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
23639b94acceSBarry Smith @*/
236463dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESRegisterDestroy(void)
23659b94acceSBarry Smith {
2366dfbe8321SBarry Smith   PetscErrorCode ierr;
236782bf6240SBarry Smith 
23683a40ed3dSBarry Smith   PetscFunctionBegin;
23691441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
23704c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
23713a40ed3dSBarry Smith   PetscFunctionReturn(0);
23729b94acceSBarry Smith }
23739b94acceSBarry Smith 
23744a2ae208SSatish Balay #undef __FUNCT__
23754a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
23769b94acceSBarry Smith /*@C
23779a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
23789b94acceSBarry Smith 
2379c7afd0dbSLois Curfman McInnes    Not Collective
2380c7afd0dbSLois Curfman McInnes 
23819b94acceSBarry Smith    Input Parameter:
23824b0e389bSBarry Smith .  snes - nonlinear solver context
23839b94acceSBarry Smith 
23849b94acceSBarry Smith    Output Parameter:
23853a7fca6bSBarry Smith .  type - SNES method (a character string)
23869b94acceSBarry Smith 
238736851e7fSLois Curfman McInnes    Level: intermediate
238836851e7fSLois Curfman McInnes 
2389454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
23909b94acceSBarry Smith @*/
2391a313700dSBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESGetType(SNES snes,const SNESType *type)
23929b94acceSBarry Smith {
23933a40ed3dSBarry Smith   PetscFunctionBegin;
23944482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
23954482741eSBarry Smith   PetscValidPointer(type,2);
23967adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
23973a40ed3dSBarry Smith   PetscFunctionReturn(0);
23989b94acceSBarry Smith }
23999b94acceSBarry Smith 
24004a2ae208SSatish Balay #undef __FUNCT__
24014a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
240252baeb72SSatish Balay /*@
24039b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
24049b94acceSBarry Smith    stored.
24059b94acceSBarry Smith 
2406c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
2407c7afd0dbSLois Curfman McInnes 
24089b94acceSBarry Smith    Input Parameter:
24099b94acceSBarry Smith .  snes - the SNES context
24109b94acceSBarry Smith 
24119b94acceSBarry Smith    Output Parameter:
24129b94acceSBarry Smith .  x - the solution
24139b94acceSBarry Smith 
241470e92668SMatthew Knepley    Level: intermediate
241536851e7fSLois Curfman McInnes 
24169b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
24179b94acceSBarry Smith 
241885385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
24199b94acceSBarry Smith @*/
242063dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESGetSolution(SNES snes,Vec *x)
24219b94acceSBarry Smith {
24223a40ed3dSBarry Smith   PetscFunctionBegin;
24234482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
24244482741eSBarry Smith   PetscValidPointer(x,2);
242585385478SLisandro Dalcin   *x = snes->vec_sol;
242670e92668SMatthew Knepley   PetscFunctionReturn(0);
242770e92668SMatthew Knepley }
242870e92668SMatthew Knepley 
242970e92668SMatthew Knepley #undef __FUNCT__
24304a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
243152baeb72SSatish Balay /*@
24329b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
24339b94acceSBarry Smith    stored.
24349b94acceSBarry Smith 
2435c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
2436c7afd0dbSLois Curfman McInnes 
24379b94acceSBarry Smith    Input Parameter:
24389b94acceSBarry Smith .  snes - the SNES context
24399b94acceSBarry Smith 
24409b94acceSBarry Smith    Output Parameter:
24419b94acceSBarry Smith .  x - the solution update
24429b94acceSBarry Smith 
244336851e7fSLois Curfman McInnes    Level: advanced
244436851e7fSLois Curfman McInnes 
24459b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
24469b94acceSBarry Smith 
244785385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
24489b94acceSBarry Smith @*/
244963dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESGetSolutionUpdate(SNES snes,Vec *x)
24509b94acceSBarry Smith {
24513a40ed3dSBarry Smith   PetscFunctionBegin;
24524482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
24534482741eSBarry Smith   PetscValidPointer(x,2);
245485385478SLisandro Dalcin   *x = snes->vec_sol_update;
24553a40ed3dSBarry Smith   PetscFunctionReturn(0);
24569b94acceSBarry Smith }
24579b94acceSBarry Smith 
24584a2ae208SSatish Balay #undef __FUNCT__
24594a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
24609b94acceSBarry Smith /*@C
24613638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
24629b94acceSBarry Smith 
2463c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
2464c7afd0dbSLois Curfman McInnes 
24659b94acceSBarry Smith    Input Parameter:
24669b94acceSBarry Smith .  snes - the SNES context
24679b94acceSBarry Smith 
24689b94acceSBarry Smith    Output Parameter:
24697bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
247070e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
247170e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
24729b94acceSBarry Smith 
247336851e7fSLois Curfman McInnes    Level: advanced
247436851e7fSLois Curfman McInnes 
2475a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
24769b94acceSBarry Smith 
24774b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
24789b94acceSBarry Smith @*/
247970e92668SMatthew Knepley PetscErrorCode PETSCSNES_DLLEXPORT SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
24809b94acceSBarry Smith {
24813a40ed3dSBarry Smith   PetscFunctionBegin;
24824482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
248385385478SLisandro Dalcin   if (r)    *r    = snes->vec_func;
2484e7788613SBarry Smith   if (func) *func = snes->ops->computefunction;
248570e92668SMatthew Knepley   if (ctx)  *ctx  = snes->funP;
24863a40ed3dSBarry Smith   PetscFunctionReturn(0);
24879b94acceSBarry Smith }
24889b94acceSBarry Smith 
24894a2ae208SSatish Balay #undef __FUNCT__
24904a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
24913c7409f5SSatish Balay /*@C
24923c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
2493d850072dSLois Curfman McInnes    SNES options in the database.
24943c7409f5SSatish Balay 
2495fee21e36SBarry Smith    Collective on SNES
2496fee21e36SBarry Smith 
2497c7afd0dbSLois Curfman McInnes    Input Parameter:
2498c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2499c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
2500c7afd0dbSLois Curfman McInnes 
2501d850072dSLois Curfman McInnes    Notes:
2502a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
2503c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
2504d850072dSLois Curfman McInnes 
250536851e7fSLois Curfman McInnes    Level: advanced
250636851e7fSLois Curfman McInnes 
25073c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
2508a86d99e1SLois Curfman McInnes 
2509a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
25103c7409f5SSatish Balay @*/
251163dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESSetOptionsPrefix(SNES snes,const char prefix[])
25123c7409f5SSatish Balay {
2513dfbe8321SBarry Smith   PetscErrorCode ierr;
25143c7409f5SSatish Balay 
25153a40ed3dSBarry Smith   PetscFunctionBegin;
25164482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
2517639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
25181cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
251994b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
25203a40ed3dSBarry Smith   PetscFunctionReturn(0);
25213c7409f5SSatish Balay }
25223c7409f5SSatish Balay 
25234a2ae208SSatish Balay #undef __FUNCT__
25244a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
25253c7409f5SSatish Balay /*@C
2526f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
2527d850072dSLois Curfman McInnes    SNES options in the database.
25283c7409f5SSatish Balay 
2529fee21e36SBarry Smith    Collective on SNES
2530fee21e36SBarry Smith 
2531c7afd0dbSLois Curfman McInnes    Input Parameters:
2532c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2533c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
2534c7afd0dbSLois Curfman McInnes 
2535d850072dSLois Curfman McInnes    Notes:
2536a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
2537c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
2538d850072dSLois Curfman McInnes 
253936851e7fSLois Curfman McInnes    Level: advanced
254036851e7fSLois Curfman McInnes 
25413c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
2542a86d99e1SLois Curfman McInnes 
2543a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
25443c7409f5SSatish Balay @*/
254563dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESAppendOptionsPrefix(SNES snes,const char prefix[])
25463c7409f5SSatish Balay {
2547dfbe8321SBarry Smith   PetscErrorCode ierr;
25483c7409f5SSatish Balay 
25493a40ed3dSBarry Smith   PetscFunctionBegin;
25504482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
2551639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
25521cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
255394b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
25543a40ed3dSBarry Smith   PetscFunctionReturn(0);
25553c7409f5SSatish Balay }
25563c7409f5SSatish Balay 
25574a2ae208SSatish Balay #undef __FUNCT__
25584a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
25599ab63eb5SSatish Balay /*@C
25603c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
25613c7409f5SSatish Balay    SNES options in the database.
25623c7409f5SSatish Balay 
2563c7afd0dbSLois Curfman McInnes    Not Collective
2564c7afd0dbSLois Curfman McInnes 
25653c7409f5SSatish Balay    Input Parameter:
25663c7409f5SSatish Balay .  snes - the SNES context
25673c7409f5SSatish Balay 
25683c7409f5SSatish Balay    Output Parameter:
25693c7409f5SSatish Balay .  prefix - pointer to the prefix string used
25703c7409f5SSatish Balay 
25714ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
25729ab63eb5SSatish Balay    sufficient length to hold the prefix.
25739ab63eb5SSatish Balay 
257436851e7fSLois Curfman McInnes    Level: advanced
257536851e7fSLois Curfman McInnes 
25763c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
2577a86d99e1SLois Curfman McInnes 
2578a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
25793c7409f5SSatish Balay @*/
2580e060cb09SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESGetOptionsPrefix(SNES snes,const char *prefix[])
25813c7409f5SSatish Balay {
2582dfbe8321SBarry Smith   PetscErrorCode ierr;
25833c7409f5SSatish Balay 
25843a40ed3dSBarry Smith   PetscFunctionBegin;
25854482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
2586639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
25873a40ed3dSBarry Smith   PetscFunctionReturn(0);
25883c7409f5SSatish Balay }
25893c7409f5SSatish Balay 
2590b2002411SLois Curfman McInnes 
25914a2ae208SSatish Balay #undef __FUNCT__
25924a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
25933cea93caSBarry Smith /*@C
25943cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
25953cea93caSBarry Smith 
25967f6c08e0SMatthew Knepley   Level: advanced
25973cea93caSBarry Smith @*/
259863dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
2599b2002411SLois Curfman McInnes {
2600e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
2601dfbe8321SBarry Smith   PetscErrorCode ierr;
2602b2002411SLois Curfman McInnes 
2603b2002411SLois Curfman McInnes   PetscFunctionBegin;
2604b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
2605c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
2606b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
2607b2002411SLois Curfman McInnes }
2608da9b6338SBarry Smith 
2609da9b6338SBarry Smith #undef __FUNCT__
2610da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
261163dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESTestLocalMin(SNES snes)
2612da9b6338SBarry Smith {
2613dfbe8321SBarry Smith   PetscErrorCode ierr;
261477431f27SBarry Smith   PetscInt       N,i,j;
2615da9b6338SBarry Smith   Vec            u,uh,fh;
2616da9b6338SBarry Smith   PetscScalar    value;
2617da9b6338SBarry Smith   PetscReal      norm;
2618da9b6338SBarry Smith 
2619da9b6338SBarry Smith   PetscFunctionBegin;
2620da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
2621da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
2622da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
2623da9b6338SBarry Smith 
2624da9b6338SBarry Smith   /* currently only works for sequential */
2625da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
2626da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
2627da9b6338SBarry Smith   for (i=0; i<N; i++) {
2628da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
262977431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
2630da9b6338SBarry Smith     for (j=-10; j<11; j++) {
2631ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
2632da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
26333ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
2634da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
263577431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
2636da9b6338SBarry Smith       value = -value;
2637da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
2638da9b6338SBarry Smith     }
2639da9b6338SBarry Smith   }
2640da9b6338SBarry Smith   ierr = VecDestroy(uh);CHKERRQ(ierr);
2641da9b6338SBarry Smith   ierr = VecDestroy(fh);CHKERRQ(ierr);
2642da9b6338SBarry Smith   PetscFunctionReturn(0);
2643da9b6338SBarry Smith }
264471f87433Sdalcinl 
264571f87433Sdalcinl #undef __FUNCT__
2646fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
264771f87433Sdalcinl /*@
2648fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
264971f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
265071f87433Sdalcinl    Newton method.
265171f87433Sdalcinl 
265271f87433Sdalcinl    Collective on SNES
265371f87433Sdalcinl 
265471f87433Sdalcinl    Input Parameters:
265571f87433Sdalcinl +  snes - SNES context
265671f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
265771f87433Sdalcinl 
265864ba62caSBarry Smith     Options Database:
265964ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
266064ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
266164ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
266264ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
266364ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
266464ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
266564ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
266664ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
266764ba62caSBarry Smith 
266871f87433Sdalcinl    Notes:
266971f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
267071f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
267171f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
267271f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
267371f87433Sdalcinl    solver.
267471f87433Sdalcinl 
267571f87433Sdalcinl    Level: advanced
267671f87433Sdalcinl 
267771f87433Sdalcinl    Reference:
267871f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
267971f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
268071f87433Sdalcinl 
268171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
268271f87433Sdalcinl 
2683fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
268471f87433Sdalcinl @*/
2685fa9f3622SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESKSPSetUseEW(SNES snes,PetscTruth flag)
268671f87433Sdalcinl {
268771f87433Sdalcinl   PetscFunctionBegin;
268871f87433Sdalcinl   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
268971f87433Sdalcinl   snes->ksp_ewconv = flag;
269071f87433Sdalcinl   PetscFunctionReturn(0);
269171f87433Sdalcinl }
269271f87433Sdalcinl 
269371f87433Sdalcinl #undef __FUNCT__
2694fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
269571f87433Sdalcinl /*@
2696fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
269771f87433Sdalcinl    for computing relative tolerance for linear solvers within an
269871f87433Sdalcinl    inexact Newton method.
269971f87433Sdalcinl 
270071f87433Sdalcinl    Not Collective
270171f87433Sdalcinl 
270271f87433Sdalcinl    Input Parameter:
270371f87433Sdalcinl .  snes - SNES context
270471f87433Sdalcinl 
270571f87433Sdalcinl    Output Parameter:
270671f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
270771f87433Sdalcinl 
270871f87433Sdalcinl    Notes:
270971f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
271071f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
271171f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
271271f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
271371f87433Sdalcinl    solver.
271471f87433Sdalcinl 
271571f87433Sdalcinl    Level: advanced
271671f87433Sdalcinl 
271771f87433Sdalcinl    Reference:
271871f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
271971f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
272071f87433Sdalcinl 
272171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
272271f87433Sdalcinl 
2723fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
272471f87433Sdalcinl @*/
2725fa9f3622SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESKSPGetUseEW(SNES snes, PetscTruth *flag)
272671f87433Sdalcinl {
272771f87433Sdalcinl   PetscFunctionBegin;
272871f87433Sdalcinl   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
272971f87433Sdalcinl   PetscValidPointer(flag,2);
273071f87433Sdalcinl   *flag = snes->ksp_ewconv;
273171f87433Sdalcinl   PetscFunctionReturn(0);
273271f87433Sdalcinl }
273371f87433Sdalcinl 
273471f87433Sdalcinl #undef __FUNCT__
2735fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
273671f87433Sdalcinl /*@
2737fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
273871f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
273971f87433Sdalcinl    Newton method.
274071f87433Sdalcinl 
274171f87433Sdalcinl    Collective on SNES
274271f87433Sdalcinl 
274371f87433Sdalcinl    Input Parameters:
274471f87433Sdalcinl +    snes - SNES context
274571f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
274671f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
274771f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
274871f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
274971f87433Sdalcinl              (0 <= gamma2 <= 1)
275071f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
275171f87433Sdalcinl .    alpha2 - power for safeguard
275271f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
275371f87433Sdalcinl 
275471f87433Sdalcinl    Note:
275571f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
275671f87433Sdalcinl 
275771f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
275871f87433Sdalcinl 
275971f87433Sdalcinl    Level: advanced
276071f87433Sdalcinl 
276171f87433Sdalcinl    Reference:
276271f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
276371f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
276471f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
276571f87433Sdalcinl 
276671f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
276771f87433Sdalcinl 
2768fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
276971f87433Sdalcinl @*/
2770fa9f3622SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
277171f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
277271f87433Sdalcinl {
2773fa9f3622SBarry Smith   SNESKSPEW *kctx;
277471f87433Sdalcinl   PetscFunctionBegin;
277571f87433Sdalcinl   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
2776fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
277771f87433Sdalcinl   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
277871f87433Sdalcinl 
277971f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
278071f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
278171f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
278271f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
278371f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
278471f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
278571f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
278671f87433Sdalcinl 
278771f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
278871f87433Sdalcinl     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
278971f87433Sdalcinl   }
279071f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
279171f87433Sdalcinl     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
279271f87433Sdalcinl   }
279371f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
279471f87433Sdalcinl     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
279571f87433Sdalcinl   }
279671f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
279771f87433Sdalcinl     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
279871f87433Sdalcinl   }
279971f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
280071f87433Sdalcinl     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
280171f87433Sdalcinl   }
280271f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
280371f87433Sdalcinl     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
280471f87433Sdalcinl   }
280571f87433Sdalcinl   PetscFunctionReturn(0);
280671f87433Sdalcinl }
280771f87433Sdalcinl 
280871f87433Sdalcinl #undef __FUNCT__
2809fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
281071f87433Sdalcinl /*@
2811fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
281271f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
281371f87433Sdalcinl    Newton method.
281471f87433Sdalcinl 
281571f87433Sdalcinl    Not Collective
281671f87433Sdalcinl 
281771f87433Sdalcinl    Input Parameters:
281871f87433Sdalcinl      snes - SNES context
281971f87433Sdalcinl 
282071f87433Sdalcinl    Output Parameters:
282171f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
282271f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
282371f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
282471f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
282571f87433Sdalcinl              (0 <= gamma2 <= 1)
282671f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
282771f87433Sdalcinl .    alpha2 - power for safeguard
282871f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
282971f87433Sdalcinl 
283071f87433Sdalcinl    Level: advanced
283171f87433Sdalcinl 
283271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
283371f87433Sdalcinl 
2834fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
283571f87433Sdalcinl @*/
2836fa9f3622SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
283771f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
283871f87433Sdalcinl {
2839fa9f3622SBarry Smith   SNESKSPEW *kctx;
284071f87433Sdalcinl   PetscFunctionBegin;
284171f87433Sdalcinl   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
2842fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
284371f87433Sdalcinl   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
284471f87433Sdalcinl   if(version)   *version   = kctx->version;
284571f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
284671f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
284771f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
284871f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
284971f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
285071f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
285171f87433Sdalcinl   PetscFunctionReturn(0);
285271f87433Sdalcinl }
285371f87433Sdalcinl 
285471f87433Sdalcinl #undef __FUNCT__
2855fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
2856fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
285771f87433Sdalcinl {
285871f87433Sdalcinl   PetscErrorCode ierr;
2859fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
286071f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
286171f87433Sdalcinl 
286271f87433Sdalcinl   PetscFunctionBegin;
286371f87433Sdalcinl   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
286471f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
286571f87433Sdalcinl     rtol = kctx->rtol_0;
286671f87433Sdalcinl   } else {
286771f87433Sdalcinl     if (kctx->version == 1) {
286871f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
286971f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
287071f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
287171f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
287271f87433Sdalcinl     } else if (kctx->version == 2) {
287371f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
287471f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
287571f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
287671f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
287771f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
287871f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
287971f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
288071f87433Sdalcinl       stol = PetscMax(rtol,stol);
288171f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
288271f87433Sdalcinl       /* safeguard: avoid oversolving */
288371f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
288471f87433Sdalcinl       stol = PetscMax(rtol,stol);
288571f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
288671f87433Sdalcinl     } else SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
288771f87433Sdalcinl   }
288871f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
288971f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
289071f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
289171f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
289271f87433Sdalcinl   PetscFunctionReturn(0);
289371f87433Sdalcinl }
289471f87433Sdalcinl 
289571f87433Sdalcinl #undef __FUNCT__
2896fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
2897fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
289871f87433Sdalcinl {
289971f87433Sdalcinl   PetscErrorCode ierr;
2900fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
290171f87433Sdalcinl   PCSide         pcside;
290271f87433Sdalcinl   Vec            lres;
290371f87433Sdalcinl 
290471f87433Sdalcinl   PetscFunctionBegin;
290571f87433Sdalcinl   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
290671f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
290771f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
290871f87433Sdalcinl   if (kctx->version == 1) {
290971f87433Sdalcinl     ierr = KSPGetPreconditionerSide(ksp,&pcside);CHKERRQ(ierr);
291071f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
291171f87433Sdalcinl       /* KSP residual is true linear residual */
291271f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
291371f87433Sdalcinl     } else {
291471f87433Sdalcinl       /* KSP residual is preconditioned residual */
291571f87433Sdalcinl       /* compute true linear residual norm */
291671f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
291771f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
291871f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
291971f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
292071f87433Sdalcinl       ierr = VecDestroy(lres);CHKERRQ(ierr);
292171f87433Sdalcinl     }
292271f87433Sdalcinl   }
292371f87433Sdalcinl   PetscFunctionReturn(0);
292471f87433Sdalcinl }
292571f87433Sdalcinl 
292671f87433Sdalcinl #undef __FUNCT__
292771f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
292871f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
292971f87433Sdalcinl {
293071f87433Sdalcinl   PetscErrorCode ierr;
293171f87433Sdalcinl 
293271f87433Sdalcinl   PetscFunctionBegin;
2933fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
293471f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
2935fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
293671f87433Sdalcinl   PetscFunctionReturn(0);
293771f87433Sdalcinl }
2938