xref: /petsc/src/snes/interface/snes.c (revision aa3661de44e2acc7351577e57fdffd6ad0090026)
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 
159*aa3661deSLisandro Dalcin EXTERN PetscErrorCode PETSCSNES_DLLEXPORT SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
160*aa3661deSLisandro Dalcin 
161*aa3661deSLisandro Dalcin #undef __FUNCT__
162*aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private"
163*aa3661deSLisandro Dalcin static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscTruth operator, PetscInt version)
164*aa3661deSLisandro Dalcin {
165*aa3661deSLisandro Dalcin   Mat            J;
166*aa3661deSLisandro Dalcin   KSP            ksp;
167*aa3661deSLisandro Dalcin   PC             pc;
168*aa3661deSLisandro Dalcin   PetscTruth     match;
169*aa3661deSLisandro Dalcin   PetscErrorCode ierr;
170*aa3661deSLisandro Dalcin 
171*aa3661deSLisandro Dalcin   PetscFunctionBegin;
172*aa3661deSLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
173*aa3661deSLisandro Dalcin 
174*aa3661deSLisandro Dalcin   if (version == 1) {
175*aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
176*aa3661deSLisandro Dalcin     /*ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);*/
177*aa3661deSLisandro Dalcin     ierr = MatMFFDSetFromOptions(J);CHKERRQ(ierr);
178*aa3661deSLisandro Dalcin   } else if (version == 2) {
179*aa3661deSLisandro Dalcin #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_MAT_SINGLE) && !defined(PETSC_USE_LONG_DOUBLE) && !defined(PETSC_USE_INT)
180*aa3661deSLisandro Dalcin     if (!snes->vec_func) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
181*aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
182*aa3661deSLisandro Dalcin #else
183*aa3661deSLisandro Dalcin     SETERRQ(PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
184*aa3661deSLisandro Dalcin #endif
185*aa3661deSLisandro Dalcin   } else {
186*aa3661deSLisandro Dalcin     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
187*aa3661deSLisandro Dalcin   }
188*aa3661deSLisandro Dalcin 
189*aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
190*aa3661deSLisandro Dalcin   if (operator) {
191*aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
192*aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
193*aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
194*aa3661deSLisandro Dalcin   } else {
195*aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
196*aa3661deSLisandro Dalcin        provided preconditioner matrix with the default matrix free version. */
197*aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);CHKERRQ(ierr);
198*aa3661deSLisandro Dalcin     /* Force no preconditioner */
199*aa3661deSLisandro Dalcin     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
200*aa3661deSLisandro Dalcin     ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
201*aa3661deSLisandro Dalcin     ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
202*aa3661deSLisandro Dalcin     if (!match) {
203*aa3661deSLisandro Dalcin       ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
204*aa3661deSLisandro Dalcin       ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
205*aa3661deSLisandro Dalcin     }
206*aa3661deSLisandro Dalcin   }
207*aa3661deSLisandro Dalcin   ierr = MatDestroy(J);CHKERRQ(ierr);
208*aa3661deSLisandro Dalcin 
209*aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
210*aa3661deSLisandro Dalcin }
211*aa3661deSLisandro Dalcin 
2124a2ae208SSatish Balay #undef __FUNCT__
2134a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions"
2149b94acceSBarry Smith /*@
21594b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
2169b94acceSBarry Smith 
217c7afd0dbSLois Curfman McInnes    Collective on SNES
218c7afd0dbSLois Curfman McInnes 
2199b94acceSBarry Smith    Input Parameter:
2209b94acceSBarry Smith .  snes - the SNES context
2219b94acceSBarry Smith 
22236851e7fSLois Curfman McInnes    Options Database Keys:
2236831982aSBarry Smith +  -snes_type <type> - ls, tr, umls, umtr, test
22482738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
22582738288SBarry Smith                 of the change in the solution between steps
22670441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
227b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
228b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
229b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
23050ffb88aSMatthew Knepley .  -snes_max_fail <max_fail> - maximum number of failures
231ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
232a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
233e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
234b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
2352492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
23682738288SBarry Smith                                solver; hence iterations will continue until max_it
2371fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
23882738288SBarry Smith                                of convergence test
239e8105e01SRichard Katz .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
240e8105e01SRichard Katz                                        filename given prints to stdout
241a6570f20SBarry Smith .  -snes_monitor_solution - plots solution at each iteration
242a6570f20SBarry Smith .  -snes_monitor_residual - plots residual (not its norm) at each iteration
243a6570f20SBarry Smith .  -snes_monitor_solution_update - plots update to solution at each iteration
244a6570f20SBarry Smith .  -snes_monitor_draw - plots residual norm at each iteration
245e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
2465968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
247fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
24882738288SBarry Smith 
24982738288SBarry Smith     Options Database for Eisenstat-Walker method:
250fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
2514b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
25236851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
25336851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
25436851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
25536851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
25636851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
25736851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
25882738288SBarry Smith 
25911ca99fdSLois Curfman McInnes    Notes:
26011ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
26111ca99fdSLois Curfman McInnes    the users manual.
26283e2fdc7SBarry Smith 
26336851e7fSLois Curfman McInnes    Level: beginner
26436851e7fSLois Curfman McInnes 
2659b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
2669b94acceSBarry Smith 
26769ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
2689b94acceSBarry Smith @*/
26963dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESSetFromOptions(SNES snes)
2709b94acceSBarry Smith {
271*aa3661deSLisandro Dalcin   PetscTruth              flg,mf,mf_operator;
272*aa3661deSLisandro Dalcin   PetscInt                i,indx,lag,mf_version;
273*aa3661deSLisandro Dalcin   MatStructure            matflag;
27485385478SLisandro Dalcin   const char              *deft = SNESLS;
27585385478SLisandro Dalcin   const char              *convtests[] = {"default","skip"};
27685385478SLisandro Dalcin   SNESKSPEW               *kctx = NULL;
277e8105e01SRichard Katz   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
27823d894e5SBarry Smith   PetscViewerASCIIMonitor monviewer;
27985385478SLisandro Dalcin   PetscErrorCode          ierr;
2809b94acceSBarry Smith 
2813a40ed3dSBarry Smith   PetscFunctionBegin;
2824482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
283ca161407SBarry Smith 
284186905e3SBarry Smith   if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
285cce0b1b2SLisandro Dalcin   ierr = PetscOptionsBegin(((PetscObject)snes)->comm,((PetscObject)snes)->prefix,"Nonlinear solver (SNES) options","SNES");CHKERRQ(ierr);
2867adad957SLisandro Dalcin     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
287b0a32e0cSBarry Smith     ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
288d64ed03dSBarry Smith     if (flg) {
289186905e3SBarry Smith       ierr = SNESSetType(snes,type);CHKERRQ(ierr);
2907adad957SLisandro Dalcin     } else if (!((PetscObject)snes)->type_name) {
291186905e3SBarry Smith       ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
292d64ed03dSBarry Smith     }
29390d69ab7SBarry Smith     /* not used here, but called so will go into help messaage */
294909c8a9fSBarry Smith     ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr);
29593c39befSBarry Smith 
29687828ca2SBarry Smith     ierr = PetscOptionsReal("-snes_stol","Stop if step length less then","SNESSetTolerances",snes->xtol,&snes->xtol,0);CHKERRQ(ierr);
29770441072SBarry Smith     ierr = PetscOptionsReal("-snes_atol","Stop if function norm less then","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr);
298186905e3SBarry Smith 
29987828ca2SBarry Smith     ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less then","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr);
300b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr);
301b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr);
30250ffb88aSMatthew Knepley     ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr);
303ddf469c8SBarry Smith     ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr);
30485385478SLisandro Dalcin 
305a8054027SBarry Smith     ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
306a8054027SBarry Smith     if (flg) {
307a8054027SBarry Smith       ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
308a8054027SBarry Smith     }
309e35cf81dSBarry Smith     ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
310e35cf81dSBarry Smith     if (flg) {
311e35cf81dSBarry Smith       ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
312e35cf81dSBarry Smith     }
313a8054027SBarry Smith 
31485385478SLisandro Dalcin     ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
31585385478SLisandro Dalcin     if (flg) {
31685385478SLisandro Dalcin       switch (indx) {
3177f7931b9SBarry Smith       case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break;
3187f7931b9SBarry Smith       case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);    break;
31985385478SLisandro Dalcin       }
32085385478SLisandro Dalcin     }
32185385478SLisandro Dalcin 
32290d69ab7SBarry Smith     ierr = PetscOptionsTruth("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr);
323186905e3SBarry Smith 
32485385478SLisandro Dalcin     kctx = (SNESKSPEW *)snes->kspconvctx;
32585385478SLisandro Dalcin 
326fa9f3622SBarry Smith     ierr = PetscOptionsTruth("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr);
327186905e3SBarry Smith 
328fa9f3622SBarry Smith     ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr);
329fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr);
330fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr);
331fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr);
332fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr);
333fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr);
334fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr);
335186905e3SBarry Smith 
33690d69ab7SBarry Smith     flg  = PETSC_FALSE;
33790d69ab7SBarry Smith     ierr = PetscOptionsTruth("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
338a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
339eabae89aSBarry Smith 
340a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
341e8105e01SRichard Katz     if (flg) {
342050a712dSBarry Smith       ierr = PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,((PetscObject)snes)->tablevel,&monviewer);CHKERRQ(ierr);
34323d894e5SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);CHKERRQ(ierr);
344e8105e01SRichard Katz     }
345eabae89aSBarry Smith 
346b271bb04SBarry Smith     ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
347b271bb04SBarry Smith     if (flg) {
348b271bb04SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr);
349b271bb04SBarry Smith     }
350b271bb04SBarry Smith 
351a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
352eabae89aSBarry Smith     if (flg) {
353050a712dSBarry Smith       ierr = PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,((PetscObject)snes)->tablevel,&monviewer);CHKERRQ(ierr);
354f1bef1bcSMatthew Knepley       ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr);
355e8105e01SRichard Katz     }
356eabae89aSBarry Smith 
357a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
358eabae89aSBarry Smith     if (flg) {
359050a712dSBarry Smith       ierr = PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,((PetscObject)snes)->tablevel,&monviewer);CHKERRQ(ierr);
36023d894e5SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);CHKERRQ(ierr);
361eabae89aSBarry Smith     }
362eabae89aSBarry Smith 
36390d69ab7SBarry Smith     flg  = PETSC_FALSE;
36490d69ab7SBarry Smith     ierr = PetscOptionsTruth("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
365a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
36690d69ab7SBarry Smith     flg  = PETSC_FALSE;
36790d69ab7SBarry Smith     ierr = PetscOptionsTruth("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
368a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
36990d69ab7SBarry Smith     flg  = PETSC_FALSE;
37090d69ab7SBarry Smith     ierr = PetscOptionsTruth("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
371a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
37290d69ab7SBarry Smith     flg  = PETSC_FALSE;
37390d69ab7SBarry Smith     ierr = PetscOptionsTruth("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
374a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
37590d69ab7SBarry Smith     flg  = PETSC_FALSE;
37690d69ab7SBarry Smith     ierr = PetscOptionsTruth("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
377b271bb04SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
378e24b481bSBarry Smith 
37990d69ab7SBarry Smith     flg  = PETSC_FALSE;
38090d69ab7SBarry Smith     ierr = PetscOptionsTruth("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
3814b27c08aSLois Curfman McInnes     if (flg) {
382186905e3SBarry Smith       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);CHKERRQ(ierr);
383ae15b995SBarry Smith       ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
3849b94acceSBarry Smith     }
385639f9d9dSBarry Smith 
386*aa3661deSLisandro Dalcin     mf = mf_operator = PETSC_FALSE;
387*aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
388*aa3661deSLisandro Dalcin     ierr = PetscOptionsTruth("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr);
389*aa3661deSLisandro Dalcin     if (flg && mf_operator) mf = PETSC_TRUE;
390*aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
391*aa3661deSLisandro Dalcin     ierr = PetscOptionsTruth("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr);
392*aa3661deSLisandro Dalcin     if (!flg && mf_operator) mf = PETSC_TRUE;
393*aa3661deSLisandro Dalcin     mf_version = 1;
394*aa3661deSLisandro Dalcin     ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr);
395*aa3661deSLisandro Dalcin 
39676b2cf59SMatthew Knepley     for(i = 0; i < numberofsetfromoptions; i++) {
39776b2cf59SMatthew Knepley       ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
39876b2cf59SMatthew Knepley     }
39976b2cf59SMatthew Knepley 
400e7788613SBarry Smith     if (snes->ops->setfromoptions) {
401e7788613SBarry Smith       ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr);
402639f9d9dSBarry Smith     }
403b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
4044bbc92c1SBarry Smith 
405*aa3661deSLisandro Dalcin   if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); }
4061cee3971SBarry Smith 
4071cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
408*aa3661deSLisandro Dalcin   ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
409*aa3661deSLisandro Dalcin   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr);
41085385478SLisandro Dalcin   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
41193993e2dSLois Curfman McInnes 
4123a40ed3dSBarry Smith   PetscFunctionReturn(0);
4139b94acceSBarry Smith }
4149b94acceSBarry Smith 
415a847f771SSatish Balay 
4164a2ae208SSatish Balay #undef __FUNCT__
4174a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
4189b94acceSBarry Smith /*@
4199b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
4209b94acceSBarry Smith    the nonlinear solvers.
4219b94acceSBarry Smith 
422fee21e36SBarry Smith    Collective on SNES
423fee21e36SBarry Smith 
424c7afd0dbSLois Curfman McInnes    Input Parameters:
425c7afd0dbSLois Curfman McInnes +  snes - the SNES context
426c7afd0dbSLois Curfman McInnes -  usrP - optional user context
427c7afd0dbSLois Curfman McInnes 
42836851e7fSLois Curfman McInnes    Level: intermediate
42936851e7fSLois Curfman McInnes 
4309b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
4319b94acceSBarry Smith 
4329b94acceSBarry Smith .seealso: SNESGetApplicationContext()
4339b94acceSBarry Smith @*/
43463dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESSetApplicationContext(SNES snes,void *usrP)
4359b94acceSBarry Smith {
4363a40ed3dSBarry Smith   PetscFunctionBegin;
4374482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
4389b94acceSBarry Smith   snes->user		= usrP;
4393a40ed3dSBarry Smith   PetscFunctionReturn(0);
4409b94acceSBarry Smith }
44174679c65SBarry Smith 
4424a2ae208SSatish Balay #undef __FUNCT__
4434a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
4449b94acceSBarry Smith /*@C
4459b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
4469b94acceSBarry Smith    nonlinear solvers.
4479b94acceSBarry Smith 
448c7afd0dbSLois Curfman McInnes    Not Collective
449c7afd0dbSLois Curfman McInnes 
4509b94acceSBarry Smith    Input Parameter:
4519b94acceSBarry Smith .  snes - SNES context
4529b94acceSBarry Smith 
4539b94acceSBarry Smith    Output Parameter:
4549b94acceSBarry Smith .  usrP - user context
4559b94acceSBarry Smith 
45636851e7fSLois Curfman McInnes    Level: intermediate
45736851e7fSLois Curfman McInnes 
4589b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
4599b94acceSBarry Smith 
4609b94acceSBarry Smith .seealso: SNESSetApplicationContext()
4619b94acceSBarry Smith @*/
46263dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESGetApplicationContext(SNES snes,void **usrP)
4639b94acceSBarry Smith {
4643a40ed3dSBarry Smith   PetscFunctionBegin;
4654482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
4669b94acceSBarry Smith   *usrP = snes->user;
4673a40ed3dSBarry Smith   PetscFunctionReturn(0);
4689b94acceSBarry Smith }
46974679c65SBarry Smith 
4704a2ae208SSatish Balay #undef __FUNCT__
4714a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
4729b94acceSBarry Smith /*@
473c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
474c8228a4eSBarry Smith    at this time.
4759b94acceSBarry Smith 
476c7afd0dbSLois Curfman McInnes    Not Collective
477c7afd0dbSLois Curfman McInnes 
4789b94acceSBarry Smith    Input Parameter:
4799b94acceSBarry Smith .  snes - SNES context
4809b94acceSBarry Smith 
4819b94acceSBarry Smith    Output Parameter:
4829b94acceSBarry Smith .  iter - iteration number
4839b94acceSBarry Smith 
484c8228a4eSBarry Smith    Notes:
485c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
486c8228a4eSBarry Smith 
487c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
48808405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
48908405cd6SLois Curfman McInnes .vb
49008405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
49108405cd6SLois Curfman McInnes       if (!(it % 2)) {
49208405cd6SLois Curfman McInnes         [compute Jacobian here]
49308405cd6SLois Curfman McInnes       }
49408405cd6SLois Curfman McInnes .ve
495c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
49608405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
497c8228a4eSBarry Smith 
49836851e7fSLois Curfman McInnes    Level: intermediate
49936851e7fSLois Curfman McInnes 
5002b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
5012b668275SBarry Smith 
502b850b91aSLisandro Dalcin .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
5039b94acceSBarry Smith @*/
50463dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESGetIterationNumber(SNES snes,PetscInt* iter)
5059b94acceSBarry Smith {
5063a40ed3dSBarry Smith   PetscFunctionBegin;
5074482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
5084482741eSBarry Smith   PetscValidIntPointer(iter,2);
5099b94acceSBarry Smith   *iter = snes->iter;
5103a40ed3dSBarry Smith   PetscFunctionReturn(0);
5119b94acceSBarry Smith }
51274679c65SBarry Smith 
5134a2ae208SSatish Balay #undef __FUNCT__
5144a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm"
5159b94acceSBarry Smith /*@
5169b94acceSBarry Smith    SNESGetFunctionNorm - Gets the norm of the current function that was set
5179b94acceSBarry Smith    with SNESSSetFunction().
5189b94acceSBarry Smith 
519c7afd0dbSLois Curfman McInnes    Collective on SNES
520c7afd0dbSLois Curfman McInnes 
5219b94acceSBarry Smith    Input Parameter:
5229b94acceSBarry Smith .  snes - SNES context
5239b94acceSBarry Smith 
5249b94acceSBarry Smith    Output Parameter:
5259b94acceSBarry Smith .  fnorm - 2-norm of function
5269b94acceSBarry Smith 
52736851e7fSLois Curfman McInnes    Level: intermediate
52836851e7fSLois Curfman McInnes 
5299b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm
530a86d99e1SLois Curfman McInnes 
531b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
5329b94acceSBarry Smith @*/
53371f87433Sdalcinl PetscErrorCode PETSCSNES_DLLEXPORT SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
5349b94acceSBarry Smith {
5353a40ed3dSBarry Smith   PetscFunctionBegin;
5364482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
5374482741eSBarry Smith   PetscValidScalarPointer(fnorm,2);
5389b94acceSBarry Smith   *fnorm = snes->norm;
5393a40ed3dSBarry Smith   PetscFunctionReturn(0);
5409b94acceSBarry Smith }
54174679c65SBarry Smith 
5424a2ae208SSatish Balay #undef __FUNCT__
543b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
5449b94acceSBarry Smith /*@
545b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
5469b94acceSBarry Smith    attempted by the nonlinear solver.
5479b94acceSBarry Smith 
548c7afd0dbSLois Curfman McInnes    Not Collective
549c7afd0dbSLois Curfman McInnes 
5509b94acceSBarry Smith    Input Parameter:
5519b94acceSBarry Smith .  snes - SNES context
5529b94acceSBarry Smith 
5539b94acceSBarry Smith    Output Parameter:
5549b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
5559b94acceSBarry Smith 
556c96a6f78SLois Curfman McInnes    Notes:
557c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
558c96a6f78SLois Curfman McInnes 
55936851e7fSLois Curfman McInnes    Level: intermediate
56036851e7fSLois Curfman McInnes 
5619b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
56258ebbce7SBarry Smith 
563e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
56458ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
5659b94acceSBarry Smith @*/
566b850b91aSLisandro Dalcin PetscErrorCode PETSCSNES_DLLEXPORT SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
5679b94acceSBarry Smith {
5683a40ed3dSBarry Smith   PetscFunctionBegin;
5694482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
5704482741eSBarry Smith   PetscValidIntPointer(nfails,2);
57150ffb88aSMatthew Knepley   *nfails = snes->numFailures;
57250ffb88aSMatthew Knepley   PetscFunctionReturn(0);
57350ffb88aSMatthew Knepley }
57450ffb88aSMatthew Knepley 
57550ffb88aSMatthew Knepley #undef __FUNCT__
576b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
57750ffb88aSMatthew Knepley /*@
578b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
57950ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
58050ffb88aSMatthew Knepley 
58150ffb88aSMatthew Knepley    Not Collective
58250ffb88aSMatthew Knepley 
58350ffb88aSMatthew Knepley    Input Parameters:
58450ffb88aSMatthew Knepley +  snes     - SNES context
58550ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
58650ffb88aSMatthew Knepley 
58750ffb88aSMatthew Knepley    Level: intermediate
58850ffb88aSMatthew Knepley 
58950ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
59058ebbce7SBarry Smith 
591e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
59258ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
59350ffb88aSMatthew Knepley @*/
594b850b91aSLisandro Dalcin PetscErrorCode PETSCSNES_DLLEXPORT SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
59550ffb88aSMatthew Knepley {
59650ffb88aSMatthew Knepley   PetscFunctionBegin;
5974482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
59850ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
59950ffb88aSMatthew Knepley   PetscFunctionReturn(0);
60050ffb88aSMatthew Knepley }
60150ffb88aSMatthew Knepley 
60250ffb88aSMatthew Knepley #undef __FUNCT__
603b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
60450ffb88aSMatthew Knepley /*@
605b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
60650ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
60750ffb88aSMatthew Knepley 
60850ffb88aSMatthew Knepley    Not Collective
60950ffb88aSMatthew Knepley 
61050ffb88aSMatthew Knepley    Input Parameter:
61150ffb88aSMatthew Knepley .  snes     - SNES context
61250ffb88aSMatthew Knepley 
61350ffb88aSMatthew Knepley    Output Parameter:
61450ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
61550ffb88aSMatthew Knepley 
61650ffb88aSMatthew Knepley    Level: intermediate
61750ffb88aSMatthew Knepley 
61850ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
61958ebbce7SBarry Smith 
620e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
62158ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
62258ebbce7SBarry Smith 
62350ffb88aSMatthew Knepley @*/
624b850b91aSLisandro Dalcin PetscErrorCode PETSCSNES_DLLEXPORT SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
62550ffb88aSMatthew Knepley {
62650ffb88aSMatthew Knepley   PetscFunctionBegin;
6274482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
6284482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
62950ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
6303a40ed3dSBarry Smith   PetscFunctionReturn(0);
6319b94acceSBarry Smith }
632a847f771SSatish Balay 
6334a2ae208SSatish Balay #undef __FUNCT__
6342541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
6352541af92SBarry Smith /*@
6362541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
6372541af92SBarry Smith      done by SNES.
6382541af92SBarry Smith 
6392541af92SBarry Smith    Not Collective
6402541af92SBarry Smith 
6412541af92SBarry Smith    Input Parameter:
6422541af92SBarry Smith .  snes     - SNES context
6432541af92SBarry Smith 
6442541af92SBarry Smith    Output Parameter:
6452541af92SBarry Smith .  nfuncs - number of evaluations
6462541af92SBarry Smith 
6472541af92SBarry Smith    Level: intermediate
6482541af92SBarry Smith 
6492541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
65058ebbce7SBarry Smith 
651e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
6522541af92SBarry Smith @*/
6532541af92SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
6542541af92SBarry Smith {
6552541af92SBarry Smith   PetscFunctionBegin;
6562541af92SBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
6572541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
6582541af92SBarry Smith   *nfuncs = snes->nfuncs;
6592541af92SBarry Smith   PetscFunctionReturn(0);
6602541af92SBarry Smith }
6612541af92SBarry Smith 
6622541af92SBarry Smith #undef __FUNCT__
6633d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
6643d4c4710SBarry Smith /*@
6653d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
6663d4c4710SBarry Smith    linear solvers.
6673d4c4710SBarry Smith 
6683d4c4710SBarry Smith    Not Collective
6693d4c4710SBarry Smith 
6703d4c4710SBarry Smith    Input Parameter:
6713d4c4710SBarry Smith .  snes - SNES context
6723d4c4710SBarry Smith 
6733d4c4710SBarry Smith    Output Parameter:
6743d4c4710SBarry Smith .  nfails - number of failed solves
6753d4c4710SBarry Smith 
6763d4c4710SBarry Smith    Notes:
6773d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
6783d4c4710SBarry Smith 
6793d4c4710SBarry Smith    Level: intermediate
6803d4c4710SBarry Smith 
6813d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
68258ebbce7SBarry Smith 
683e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
6843d4c4710SBarry Smith @*/
6853d4c4710SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
6863d4c4710SBarry Smith {
6873d4c4710SBarry Smith   PetscFunctionBegin;
6883d4c4710SBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
6893d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
6903d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
6913d4c4710SBarry Smith   PetscFunctionReturn(0);
6923d4c4710SBarry Smith }
6933d4c4710SBarry Smith 
6943d4c4710SBarry Smith #undef __FUNCT__
6953d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
6963d4c4710SBarry Smith /*@
6973d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
6983d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
6993d4c4710SBarry Smith 
7003d4c4710SBarry Smith    Collective on SNES
7013d4c4710SBarry Smith 
7023d4c4710SBarry Smith    Input Parameters:
7033d4c4710SBarry Smith +  snes     - SNES context
7043d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
7053d4c4710SBarry Smith 
7063d4c4710SBarry Smith    Level: intermediate
7073d4c4710SBarry Smith 
708a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
7093d4c4710SBarry Smith 
7103d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
7113d4c4710SBarry Smith 
71258ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
7133d4c4710SBarry Smith @*/
7143d4c4710SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
7153d4c4710SBarry Smith {
7163d4c4710SBarry Smith   PetscFunctionBegin;
7173d4c4710SBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
7183d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
7193d4c4710SBarry Smith   PetscFunctionReturn(0);
7203d4c4710SBarry Smith }
7213d4c4710SBarry Smith 
7223d4c4710SBarry Smith #undef __FUNCT__
7233d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
7243d4c4710SBarry Smith /*@
7253d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
7263d4c4710SBarry Smith      are allowed before SNES terminates
7273d4c4710SBarry Smith 
7283d4c4710SBarry Smith    Not Collective
7293d4c4710SBarry Smith 
7303d4c4710SBarry Smith    Input Parameter:
7313d4c4710SBarry Smith .  snes     - SNES context
7323d4c4710SBarry Smith 
7333d4c4710SBarry Smith    Output Parameter:
7343d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
7353d4c4710SBarry Smith 
7363d4c4710SBarry Smith    Level: intermediate
7373d4c4710SBarry Smith 
7383d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
7393d4c4710SBarry Smith 
7403d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
7413d4c4710SBarry Smith 
742e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
7433d4c4710SBarry Smith @*/
7443d4c4710SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
7453d4c4710SBarry Smith {
7463d4c4710SBarry Smith   PetscFunctionBegin;
7473d4c4710SBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
7483d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
7493d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
7503d4c4710SBarry Smith   PetscFunctionReturn(0);
7513d4c4710SBarry Smith }
7523d4c4710SBarry Smith 
7533d4c4710SBarry Smith #undef __FUNCT__
754b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
755c96a6f78SLois Curfman McInnes /*@
756b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
757c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
758c96a6f78SLois Curfman McInnes 
759c7afd0dbSLois Curfman McInnes    Not Collective
760c7afd0dbSLois Curfman McInnes 
761c96a6f78SLois Curfman McInnes    Input Parameter:
762c96a6f78SLois Curfman McInnes .  snes - SNES context
763c96a6f78SLois Curfman McInnes 
764c96a6f78SLois Curfman McInnes    Output Parameter:
765c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
766c96a6f78SLois Curfman McInnes 
767c96a6f78SLois Curfman McInnes    Notes:
768c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
769c96a6f78SLois Curfman McInnes 
77036851e7fSLois Curfman McInnes    Level: intermediate
77136851e7fSLois Curfman McInnes 
772c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
7732b668275SBarry Smith 
7748c7482ecSBarry Smith .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
775c96a6f78SLois Curfman McInnes @*/
776b850b91aSLisandro Dalcin PetscErrorCode PETSCSNES_DLLEXPORT SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
777c96a6f78SLois Curfman McInnes {
7783a40ed3dSBarry Smith   PetscFunctionBegin;
7794482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
7804482741eSBarry Smith   PetscValidIntPointer(lits,2);
781c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
7823a40ed3dSBarry Smith   PetscFunctionReturn(0);
783c96a6f78SLois Curfman McInnes }
784c96a6f78SLois Curfman McInnes 
7854a2ae208SSatish Balay #undef __FUNCT__
78694b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP"
78752baeb72SSatish Balay /*@
78894b7f48cSBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
7899b94acceSBarry Smith 
79094b7f48cSBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
791c7afd0dbSLois Curfman McInnes 
7929b94acceSBarry Smith    Input Parameter:
7939b94acceSBarry Smith .  snes - the SNES context
7949b94acceSBarry Smith 
7959b94acceSBarry Smith    Output Parameter:
79694b7f48cSBarry Smith .  ksp - the KSP context
7979b94acceSBarry Smith 
7989b94acceSBarry Smith    Notes:
79994b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
8009b94acceSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
8012999313aSBarry Smith    PC contexts as well.
8029b94acceSBarry Smith 
80336851e7fSLois Curfman McInnes    Level: beginner
80436851e7fSLois Curfman McInnes 
80594b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
8069b94acceSBarry Smith 
8072999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
8089b94acceSBarry Smith @*/
80963dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESGetKSP(SNES snes,KSP *ksp)
8109b94acceSBarry Smith {
8111cee3971SBarry Smith   PetscErrorCode ierr;
8121cee3971SBarry Smith 
8133a40ed3dSBarry Smith   PetscFunctionBegin;
8144482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
8154482741eSBarry Smith   PetscValidPointer(ksp,2);
8161cee3971SBarry Smith 
8171cee3971SBarry Smith   if (!snes->ksp) {
8181cee3971SBarry Smith     ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr);
8191cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
8201cee3971SBarry Smith     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
8211cee3971SBarry Smith   }
82294b7f48cSBarry Smith   *ksp = snes->ksp;
8233a40ed3dSBarry Smith   PetscFunctionReturn(0);
8249b94acceSBarry Smith }
82582bf6240SBarry Smith 
8264a2ae208SSatish Balay #undef __FUNCT__
8272999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
8282999313aSBarry Smith /*@
8292999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
8302999313aSBarry Smith 
8312999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
8322999313aSBarry Smith 
8332999313aSBarry Smith    Input Parameters:
8342999313aSBarry Smith +  snes - the SNES context
8352999313aSBarry Smith -  ksp - the KSP context
8362999313aSBarry Smith 
8372999313aSBarry Smith    Notes:
8382999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
8392999313aSBarry Smith    so this routine is rarely needed.
8402999313aSBarry Smith 
8412999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
8422999313aSBarry Smith    decreased by one.
8432999313aSBarry Smith 
8442999313aSBarry Smith    Level: developer
8452999313aSBarry Smith 
8462999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
8472999313aSBarry Smith 
8482999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
8492999313aSBarry Smith @*/
8502999313aSBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESSetKSP(SNES snes,KSP ksp)
8512999313aSBarry Smith {
8522999313aSBarry Smith   PetscErrorCode ierr;
8532999313aSBarry Smith 
8542999313aSBarry Smith   PetscFunctionBegin;
8552999313aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
8562999313aSBarry Smith   PetscValidHeaderSpecific(ksp,KSP_COOKIE,2);
8572999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
8587dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
859906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
8602999313aSBarry Smith   snes->ksp = ksp;
8612999313aSBarry Smith   PetscFunctionReturn(0);
8622999313aSBarry Smith }
8632999313aSBarry Smith 
8647adad957SLisandro Dalcin #if 0
8652999313aSBarry Smith #undef __FUNCT__
8664a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc"
8676849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
868e24b481bSBarry Smith {
869e24b481bSBarry Smith   PetscFunctionBegin;
870e24b481bSBarry Smith   PetscFunctionReturn(0);
871e24b481bSBarry Smith }
8727adad957SLisandro Dalcin #endif
873e24b481bSBarry Smith 
8749b94acceSBarry Smith /* -----------------------------------------------------------*/
8754a2ae208SSatish Balay #undef __FUNCT__
8764a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
87752baeb72SSatish Balay /*@
8789b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
8799b94acceSBarry Smith 
880c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
881c7afd0dbSLois Curfman McInnes 
882c7afd0dbSLois Curfman McInnes    Input Parameters:
883906ed7ccSBarry Smith .  comm - MPI communicator
8849b94acceSBarry Smith 
8859b94acceSBarry Smith    Output Parameter:
8869b94acceSBarry Smith .  outsnes - the new SNES context
8879b94acceSBarry Smith 
888c7afd0dbSLois Curfman McInnes    Options Database Keys:
889c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
890c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
891c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
892c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
893c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
894c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
895c1f60f51SBarry Smith 
89636851e7fSLois Curfman McInnes    Level: beginner
89736851e7fSLois Curfman McInnes 
8989b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
8999b94acceSBarry Smith 
900a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
901a8054027SBarry Smith 
9029b94acceSBarry Smith @*/
90363dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESCreate(MPI_Comm comm,SNES *outsnes)
9049b94acceSBarry Smith {
905dfbe8321SBarry Smith   PetscErrorCode      ierr;
9069b94acceSBarry Smith   SNES                snes;
907fa9f3622SBarry Smith   SNESKSPEW           *kctx;
90837fcc0dbSBarry Smith 
9093a40ed3dSBarry Smith   PetscFunctionBegin;
910ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
9118ba1e511SMatthew Knepley   *outsnes = PETSC_NULL;
9128ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
9138ba1e511SMatthew Knepley   ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr);
9148ba1e511SMatthew Knepley #endif
9158ba1e511SMatthew Knepley 
916e7788613SBarry Smith   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_COOKIE,0,"SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
9177adad957SLisandro Dalcin 
91885385478SLisandro Dalcin   snes->ops->converged    = SNESDefaultConverged;
9199b94acceSBarry Smith   snes->max_its           = 50;
9209750a799SBarry Smith   snes->max_funcs	  = 10000;
9219b94acceSBarry Smith   snes->norm		  = 0.0;
922b4874afaSBarry Smith   snes->rtol		  = 1.e-8;
923b4874afaSBarry Smith   snes->ttol              = 0.0;
92470441072SBarry Smith   snes->abstol		  = 1.e-50;
9259b94acceSBarry Smith   snes->xtol		  = 1.e-8;
9264b27c08aSLois Curfman McInnes   snes->deltatol	  = 1.e-12;
9279b94acceSBarry Smith   snes->nfuncs            = 0;
92850ffb88aSMatthew Knepley   snes->numFailures       = 0;
92950ffb88aSMatthew Knepley   snes->maxFailures       = 1;
9307a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
931e35cf81dSBarry Smith   snes->lagjacobian       = 1;
932a8054027SBarry Smith   snes->lagpreconditioner = 1;
933639f9d9dSBarry Smith   snes->numbermonitors    = 0;
9349b94acceSBarry Smith   snes->data              = 0;
9354dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
936186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
9376f24a144SLois Curfman McInnes   snes->vwork             = 0;
9386f24a144SLois Curfman McInnes   snes->nwork             = 0;
939758f92a0SBarry Smith   snes->conv_hist_len     = 0;
940758f92a0SBarry Smith   snes->conv_hist_max     = 0;
941758f92a0SBarry Smith   snes->conv_hist         = PETSC_NULL;
942758f92a0SBarry Smith   snes->conv_hist_its     = PETSC_NULL;
943758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
944184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
9459b94acceSBarry Smith 
9463d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
9473d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
9483d4c4710SBarry Smith 
9499b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
95038f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr);
9519b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
9529b94acceSBarry Smith   kctx->version     = 2;
9539b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
9549b94acceSBarry Smith                              this was too large for some test cases */
9559b94acceSBarry Smith   kctx->rtol_last   = 0;
9569b94acceSBarry Smith   kctx->rtol_max    = .9;
9579b94acceSBarry Smith   kctx->gamma       = 1.0;
95871f87433Sdalcinl   kctx->alpha       = .5*(1.0 + sqrt(5.0));
95971f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
9609b94acceSBarry Smith   kctx->threshold   = .1;
9619b94acceSBarry Smith   kctx->lresid_last = 0;
9629b94acceSBarry Smith   kctx->norm_last   = 0;
9639b94acceSBarry Smith 
9649b94acceSBarry Smith   *outsnes = snes;
96500036973SBarry Smith   ierr = PetscPublishAll(snes);CHKERRQ(ierr);
9663a40ed3dSBarry Smith   PetscFunctionReturn(0);
9679b94acceSBarry Smith }
9689b94acceSBarry Smith 
9694a2ae208SSatish Balay #undef __FUNCT__
9704a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
9719b94acceSBarry Smith /*@C
9729b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
9739b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
9749b94acceSBarry Smith    equations.
9759b94acceSBarry Smith 
976fee21e36SBarry Smith    Collective on SNES
977fee21e36SBarry Smith 
978c7afd0dbSLois Curfman McInnes    Input Parameters:
979c7afd0dbSLois Curfman McInnes +  snes - the SNES context
980c7afd0dbSLois Curfman McInnes .  r - vector to store function value
981de044059SHong Zhang .  func - function evaluation routine
982c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
983c7afd0dbSLois Curfman McInnes          function evaluation routine (may be PETSC_NULL)
9849b94acceSBarry Smith 
985c7afd0dbSLois Curfman McInnes    Calling sequence of func:
9868d76a1e5SLois Curfman McInnes $    func (SNES snes,Vec x,Vec f,void *ctx);
987c7afd0dbSLois Curfman McInnes 
988313e4042SLois Curfman McInnes .  f - function vector
989c7afd0dbSLois Curfman McInnes -  ctx - optional user-defined function context
9909b94acceSBarry Smith 
9919b94acceSBarry Smith    Notes:
9929b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
9939b94acceSBarry Smith $      f'(x) x = -f(x),
994c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
9959b94acceSBarry Smith 
99636851e7fSLois Curfman McInnes    Level: beginner
99736851e7fSLois Curfman McInnes 
9989b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
9999b94acceSBarry Smith 
1000a86d99e1SLois Curfman McInnes .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
10019b94acceSBarry Smith @*/
100263dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
10039b94acceSBarry Smith {
100485385478SLisandro Dalcin   PetscErrorCode ierr;
10053a40ed3dSBarry Smith   PetscFunctionBegin;
10064482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
10074482741eSBarry Smith   PetscValidHeaderSpecific(r,VEC_COOKIE,2);
1008c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,r,2);
100985385478SLisandro Dalcin   ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
101085385478SLisandro Dalcin   if (snes->vec_func) { ierr = VecDestroy(snes->vec_func);CHKERRQ(ierr); }
1011e7788613SBarry Smith   snes->ops->computefunction = func;
101285385478SLisandro Dalcin   snes->vec_func             = r;
10139b94acceSBarry Smith   snes->funP                 = ctx;
10143a40ed3dSBarry Smith   PetscFunctionReturn(0);
10159b94acceSBarry Smith }
10169b94acceSBarry Smith 
10173ab0aad5SBarry Smith /* --------------------------------------------------------------- */
10183ab0aad5SBarry Smith #undef __FUNCT__
10191096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
10201096aae1SMatthew Knepley /*@C
10211096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
10221096aae1SMatthew Knepley    it assumes a zero right hand side.
10231096aae1SMatthew Knepley 
10241096aae1SMatthew Knepley    Collective on SNES
10251096aae1SMatthew Knepley 
10261096aae1SMatthew Knepley    Input Parameter:
10271096aae1SMatthew Knepley .  snes - the SNES context
10281096aae1SMatthew Knepley 
10291096aae1SMatthew Knepley    Output Parameter:
1030bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
10311096aae1SMatthew Knepley 
10321096aae1SMatthew Knepley    Level: intermediate
10331096aae1SMatthew Knepley 
10341096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
10351096aae1SMatthew Knepley 
103685385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
10371096aae1SMatthew Knepley @*/
10381096aae1SMatthew Knepley PetscErrorCode PETSCSNES_DLLEXPORT SNESGetRhs(SNES snes,Vec *rhs)
10391096aae1SMatthew Knepley {
10401096aae1SMatthew Knepley   PetscFunctionBegin;
10411096aae1SMatthew Knepley   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
10421096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
104385385478SLisandro Dalcin   *rhs = snes->vec_rhs;
10441096aae1SMatthew Knepley   PetscFunctionReturn(0);
10451096aae1SMatthew Knepley }
10461096aae1SMatthew Knepley 
10471096aae1SMatthew Knepley #undef __FUNCT__
10484a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
10499b94acceSBarry Smith /*@
105036851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
10519b94acceSBarry Smith                          SNESSetFunction().
10529b94acceSBarry Smith 
1053c7afd0dbSLois Curfman McInnes    Collective on SNES
1054c7afd0dbSLois Curfman McInnes 
10559b94acceSBarry Smith    Input Parameters:
1056c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1057c7afd0dbSLois Curfman McInnes -  x - input vector
10589b94acceSBarry Smith 
10599b94acceSBarry Smith    Output Parameter:
10603638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
10619b94acceSBarry Smith 
10621bffabb2SLois Curfman McInnes    Notes:
106336851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
106436851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
106536851e7fSLois Curfman McInnes    themselves.
106636851e7fSLois Curfman McInnes 
106736851e7fSLois Curfman McInnes    Level: developer
106836851e7fSLois Curfman McInnes 
10699b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
10709b94acceSBarry Smith 
1071a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
10729b94acceSBarry Smith @*/
107363dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESComputeFunction(SNES snes,Vec x,Vec y)
10749b94acceSBarry Smith {
1075dfbe8321SBarry Smith   PetscErrorCode ierr;
10769b94acceSBarry Smith 
10773a40ed3dSBarry Smith   PetscFunctionBegin;
10784482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
10794482741eSBarry Smith   PetscValidHeaderSpecific(x,VEC_COOKIE,2);
10804482741eSBarry Smith   PetscValidHeaderSpecific(y,VEC_COOKIE,3);
1081c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
1082c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
1083184914b5SBarry Smith 
1084d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
1085e7788613SBarry Smith   if (snes->ops->computefunction) {
1086d64ed03dSBarry Smith     PetscStackPush("SNES user function");
1087e9a2bbcdSBarry Smith     CHKMEMQ;
1088e7788613SBarry Smith     ierr = (*snes->ops->computefunction)(snes,x,y,snes->funP);
1089e9a2bbcdSBarry Smith     CHKMEMQ;
1090d64ed03dSBarry Smith     PetscStackPop;
1091d5e45103SBarry Smith     if (PetscExceptionValue(ierr)) {
109219717074SBarry Smith       PetscErrorCode pierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(pierr);
109319717074SBarry Smith     }
1094d5e45103SBarry Smith     CHKERRQ(ierr);
109585385478SLisandro Dalcin   } else if (snes->vec_rhs) {
10961096aae1SMatthew Knepley     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
10971096aae1SMatthew Knepley   } else {
10981096aae1SMatthew Knepley     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() before SNESComputeFunction(), likely called from SNESSolve().");
10991096aae1SMatthew Knepley   }
110085385478SLisandro Dalcin   if (snes->vec_rhs) {
110185385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
11023ab0aad5SBarry Smith   }
1103ae3c334cSLois Curfman McInnes   snes->nfuncs++;
1104d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
11053a40ed3dSBarry Smith   PetscFunctionReturn(0);
11069b94acceSBarry Smith }
11079b94acceSBarry Smith 
11084a2ae208SSatish Balay #undef __FUNCT__
11094a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
111062fef451SLois Curfman McInnes /*@
111162fef451SLois Curfman McInnes    SNESComputeJacobian - Computes the Jacobian matrix that has been
111262fef451SLois Curfman McInnes    set with SNESSetJacobian().
111362fef451SLois Curfman McInnes 
1114c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
1115c7afd0dbSLois Curfman McInnes 
111662fef451SLois Curfman McInnes    Input Parameters:
1117c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1118c7afd0dbSLois Curfman McInnes -  x - input vector
111962fef451SLois Curfman McInnes 
112062fef451SLois Curfman McInnes    Output Parameters:
1121c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
112262fef451SLois Curfman McInnes .  B - optional preconditioning matrix
11232b668275SBarry Smith -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1124fee21e36SBarry Smith 
1125e35cf81dSBarry Smith   Options Database Keys:
1126e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
1127e35cf81dSBarry Smith -    -snes_lag_jacobian <lag>
1128e35cf81dSBarry Smith 
112962fef451SLois Curfman McInnes    Notes:
113062fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
113162fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
113262fef451SLois Curfman McInnes 
113394b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the
1134dc5a77f8SLois Curfman McInnes    flag parameter.
113562fef451SLois Curfman McInnes 
113636851e7fSLois Curfman McInnes    Level: developer
113736851e7fSLois Curfman McInnes 
113862fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
113962fef451SLois Curfman McInnes 
1140e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
114162fef451SLois Curfman McInnes @*/
114263dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
11439b94acceSBarry Smith {
1144dfbe8321SBarry Smith   PetscErrorCode ierr;
1145ebd3b9afSBarry Smith   PetscTruth     flag;
11463a40ed3dSBarry Smith 
11473a40ed3dSBarry Smith   PetscFunctionBegin;
11484482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
11494482741eSBarry Smith   PetscValidHeaderSpecific(X,VEC_COOKIE,2);
11504482741eSBarry Smith   PetscValidPointer(flg,5);
1151c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
1152e7788613SBarry Smith   if (!snes->ops->computejacobian) PetscFunctionReturn(0);
1153ebd3b9afSBarry Smith 
1154ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
1155ebd3b9afSBarry Smith 
1156fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
1157fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
1158fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
1159fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
1160e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1161e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
1162ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1163ebd3b9afSBarry Smith     if (flag) {
1164ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1165ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1166ebd3b9afSBarry Smith     }
1167e35cf81dSBarry Smith     PetscFunctionReturn(0);
1168e35cf81dSBarry Smith   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
1169e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1170e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
1171ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1172ebd3b9afSBarry Smith     if (flag) {
1173ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1174ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1175ebd3b9afSBarry Smith     }
1176e35cf81dSBarry Smith     PetscFunctionReturn(0);
1177e35cf81dSBarry Smith   }
1178e35cf81dSBarry Smith 
1179c4fc05e7SBarry Smith   *flg = DIFFERENT_NONZERO_PATTERN;
1180e35cf81dSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1181d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
1182dc67937bSBarry Smith   CHKMEMQ;
1183e7788613SBarry Smith   ierr = (*snes->ops->computejacobian)(snes,X,A,B,flg,snes->jacP);CHKERRQ(ierr);
1184dc67937bSBarry Smith   CHKMEMQ;
1185d64ed03dSBarry Smith   PetscStackPop;
1186d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1187a8054027SBarry Smith 
11883b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
11893b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
11903b4f5425SBarry Smith     snes->lagpreconditioner = -1;
11913b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
1192a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1193a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
1194a8054027SBarry Smith   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
1195a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1196a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
1197a8054027SBarry Smith   }
1198a8054027SBarry Smith 
11996d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
12006ce558aeSBarry Smith   /* PetscValidHeaderSpecific(*A,MAT_COOKIE,3);
12016ce558aeSBarry Smith     PetscValidHeaderSpecific(*B,MAT_COOKIE,4);   */
12023a40ed3dSBarry Smith   PetscFunctionReturn(0);
12039b94acceSBarry Smith }
12049b94acceSBarry Smith 
12054a2ae208SSatish Balay #undef __FUNCT__
12064a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
12079b94acceSBarry Smith /*@C
12089b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
1209044dda88SLois Curfman McInnes    location to store the matrix.
12109b94acceSBarry Smith 
1211c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
1212c7afd0dbSLois Curfman McInnes 
12139b94acceSBarry Smith    Input Parameters:
1214c7afd0dbSLois Curfman McInnes +  snes - the SNES context
12159b94acceSBarry Smith .  A - Jacobian matrix
12169b94acceSBarry Smith .  B - preconditioner matrix (usually same as the Jacobian)
12179b94acceSBarry Smith .  func - Jacobian evaluation routine
1218c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
12192cd2dfdcSLois Curfman McInnes          Jacobian evaluation routine (may be PETSC_NULL)
12209b94acceSBarry Smith 
12219b94acceSBarry Smith    Calling sequence of func:
12228d76a1e5SLois Curfman McInnes $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
12239b94acceSBarry Smith 
1224c7afd0dbSLois Curfman McInnes +  x - input vector
12259b94acceSBarry Smith .  A - Jacobian matrix
12269b94acceSBarry Smith .  B - preconditioner matrix, usually the same as A
1227ac21db08SLois Curfman McInnes .  flag - flag indicating information about the preconditioner matrix
12282b668275SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
1229c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined Jacobian context
12309b94acceSBarry Smith 
12319b94acceSBarry Smith    Notes:
123294b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the flag
12332cd2dfdcSLois Curfman McInnes    output parameter in the routine func().  Be sure to read this information!
1234ac21db08SLois Curfman McInnes 
1235ac21db08SLois Curfman McInnes    The routine func() takes Mat * as the matrix arguments rather than Mat.
12369b94acceSBarry Smith    This allows the Jacobian evaluation routine to replace A and/or B with a
12379b94acceSBarry Smith    completely new new matrix structure (not just different matrix elements)
12389b94acceSBarry Smith    when appropriate, for instance, if the nonzero structure is changing
12399b94acceSBarry Smith    throughout the global iterations.
12409b94acceSBarry Smith 
124116913363SBarry Smith    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
124216913363SBarry Smith    each matrix.
124316913363SBarry Smith 
124436851e7fSLois Curfman McInnes    Level: beginner
124536851e7fSLois Curfman McInnes 
12469b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
12479b94acceSBarry Smith 
12483ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
12499b94acceSBarry Smith @*/
125063dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
12519b94acceSBarry Smith {
1252dfbe8321SBarry Smith   PetscErrorCode ierr;
12533a7fca6bSBarry Smith 
12543a40ed3dSBarry Smith   PetscFunctionBegin;
12554482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
12564482741eSBarry Smith   if (A) PetscValidHeaderSpecific(A,MAT_COOKIE,2);
12574482741eSBarry Smith   if (B) PetscValidHeaderSpecific(B,MAT_COOKIE,3);
1258c9780b6fSBarry Smith   if (A) PetscCheckSameComm(snes,1,A,2);
1259c9780b6fSBarry Smith   if (B) PetscCheckSameComm(snes,1,B,2);
1260e7788613SBarry Smith   if (func) snes->ops->computejacobian = func;
12613a7fca6bSBarry Smith   if (ctx)  snes->jacP                 = ctx;
12623a7fca6bSBarry Smith   if (A) {
12637dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
12643a7fca6bSBarry Smith     if (snes->jacobian) {ierr = MatDestroy(snes->jacobian);CHKERRQ(ierr);}
12659b94acceSBarry Smith     snes->jacobian = A;
12663a7fca6bSBarry Smith   }
12673a7fca6bSBarry Smith   if (B) {
12687dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
12693a7fca6bSBarry Smith     if (snes->jacobian_pre) {ierr = MatDestroy(snes->jacobian_pre);CHKERRQ(ierr);}
12709b94acceSBarry Smith     snes->jacobian_pre = B;
12713a7fca6bSBarry Smith   }
12723a40ed3dSBarry Smith   PetscFunctionReturn(0);
12739b94acceSBarry Smith }
127462fef451SLois Curfman McInnes 
12754a2ae208SSatish Balay #undef __FUNCT__
12764a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
1277c2aafc4cSSatish Balay /*@C
1278b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
1279b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
1280b4fd4287SBarry Smith 
1281c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
1282c7afd0dbSLois Curfman McInnes 
1283b4fd4287SBarry Smith    Input Parameter:
1284b4fd4287SBarry Smith .  snes - the nonlinear solver context
1285b4fd4287SBarry Smith 
1286b4fd4287SBarry Smith    Output Parameters:
1287c7afd0dbSLois Curfman McInnes +  A - location to stash Jacobian matrix (or PETSC_NULL)
1288b4fd4287SBarry Smith .  B - location to stash preconditioner matrix (or PETSC_NULL)
128970e92668SMatthew Knepley .  func - location to put Jacobian function (or PETSC_NULL)
129070e92668SMatthew Knepley -  ctx - location to stash Jacobian ctx (or PETSC_NULL)
1291fee21e36SBarry Smith 
129236851e7fSLois Curfman McInnes    Level: advanced
129336851e7fSLois Curfman McInnes 
1294b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian()
1295b4fd4287SBarry Smith @*/
129670e92668SMatthew Knepley PetscErrorCode PETSCSNES_DLLEXPORT SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
1297b4fd4287SBarry Smith {
12983a40ed3dSBarry Smith   PetscFunctionBegin;
12994482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
1300b4fd4287SBarry Smith   if (A)    *A    = snes->jacobian;
1301b4fd4287SBarry Smith   if (B)    *B    = snes->jacobian_pre;
1302e7788613SBarry Smith   if (func) *func = snes->ops->computejacobian;
130370e92668SMatthew Knepley   if (ctx)  *ctx  = snes->jacP;
13043a40ed3dSBarry Smith   PetscFunctionReturn(0);
1305b4fd4287SBarry Smith }
1306b4fd4287SBarry Smith 
13079b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
13089b94acceSBarry Smith 
13094a2ae208SSatish Balay #undef __FUNCT__
13104a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
13119b94acceSBarry Smith /*@
13129b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
1313272ac6f2SLois Curfman McInnes    of a nonlinear solver.
13149b94acceSBarry Smith 
1315fee21e36SBarry Smith    Collective on SNES
1316fee21e36SBarry Smith 
1317c7afd0dbSLois Curfman McInnes    Input Parameters:
131870e92668SMatthew Knepley .  snes - the SNES context
1319c7afd0dbSLois Curfman McInnes 
1320272ac6f2SLois Curfman McInnes    Notes:
1321272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
1322272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
1323272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
1324272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
1325272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
1326272ac6f2SLois Curfman McInnes 
132736851e7fSLois Curfman McInnes    Level: advanced
132836851e7fSLois Curfman McInnes 
13299b94acceSBarry Smith .keywords: SNES, nonlinear, setup
13309b94acceSBarry Smith 
13319b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
13329b94acceSBarry Smith @*/
133370e92668SMatthew Knepley PetscErrorCode PETSCSNES_DLLEXPORT SNESSetUp(SNES snes)
13349b94acceSBarry Smith {
1335dfbe8321SBarry Smith   PetscErrorCode ierr;
13363a40ed3dSBarry Smith 
13373a40ed3dSBarry Smith   PetscFunctionBegin;
13384482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
13394dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
13409b94acceSBarry Smith 
13417adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
134285385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
134385385478SLisandro Dalcin   }
134485385478SLisandro Dalcin 
134585385478SLisandro Dalcin   if (!snes->vec_func && !snes->vec_rhs) {
13461096aae1SMatthew Knepley     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
13471096aae1SMatthew Knepley   }
134885385478SLisandro Dalcin   if (!snes->ops->computefunction && !snes->vec_rhs) {
13491096aae1SMatthew Knepley     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
13501096aae1SMatthew Knepley   }
1351a8c6a408SBarry Smith   if (snes->vec_func == snes->vec_sol) {
135229bbc08cSBarry Smith     SETERRQ(PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
1353a8c6a408SBarry Smith   }
1354a703fe33SLois Curfman McInnes 
1355b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
1356b710008aSBarry Smith 
1357410397dcSLisandro Dalcin   if (snes->ops->setup) {
1358410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
1359410397dcSLisandro Dalcin   }
13607aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
13613a40ed3dSBarry Smith   PetscFunctionReturn(0);
13629b94acceSBarry Smith }
13639b94acceSBarry Smith 
13644a2ae208SSatish Balay #undef __FUNCT__
13654a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
136652baeb72SSatish Balay /*@
13679b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
13689b94acceSBarry Smith    with SNESCreate().
13699b94acceSBarry Smith 
1370c7afd0dbSLois Curfman McInnes    Collective on SNES
1371c7afd0dbSLois Curfman McInnes 
13729b94acceSBarry Smith    Input Parameter:
13739b94acceSBarry Smith .  snes - the SNES context
13749b94acceSBarry Smith 
137536851e7fSLois Curfman McInnes    Level: beginner
137636851e7fSLois Curfman McInnes 
13779b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
13789b94acceSBarry Smith 
137963a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
13809b94acceSBarry Smith @*/
138163dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESDestroy(SNES snes)
13829b94acceSBarry Smith {
13836849ba73SBarry Smith   PetscErrorCode ierr;
13843a40ed3dSBarry Smith 
13853a40ed3dSBarry Smith   PetscFunctionBegin;
13864482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
13877adad957SLisandro Dalcin   if (--((PetscObject)snes)->refct > 0) PetscFunctionReturn(0);
1388d4bb536fSBarry Smith 
1389be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
13900f5bd95cSBarry Smith   ierr = PetscObjectDepublish(snes);CHKERRQ(ierr);
1391e7788613SBarry Smith   if (snes->ops->destroy) {ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);}
139285385478SLisandro Dalcin 
139385385478SLisandro Dalcin   if (snes->vec_rhs) {ierr = VecDestroy(snes->vec_rhs);CHKERRQ(ierr);}
139485385478SLisandro Dalcin   if (snes->vec_sol) {ierr = VecDestroy(snes->vec_sol);CHKERRQ(ierr);}
139585385478SLisandro Dalcin   if (snes->vec_func) {ierr = VecDestroy(snes->vec_func);CHKERRQ(ierr);}
13963a7fca6bSBarry Smith   if (snes->jacobian) {ierr = MatDestroy(snes->jacobian);CHKERRQ(ierr);}
13973a7fca6bSBarry Smith   if (snes->jacobian_pre) {ierr = MatDestroy(snes->jacobian_pre);CHKERRQ(ierr);}
13981cee3971SBarry Smith   if (snes->ksp) {ierr = KSPDestroy(snes->ksp);CHKERRQ(ierr);}
139985385478SLisandro Dalcin   ierr = PetscFree(snes->kspconvctx);CHKERRQ(ierr);
1400522c5e43SBarry Smith   if (snes->vwork) {ierr = VecDestroyVecs(snes->vwork,snes->nvwork);CHKERRQ(ierr);}
1401a6570f20SBarry Smith   ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);
14027f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);}
1403a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
14043a40ed3dSBarry Smith   PetscFunctionReturn(0);
14059b94acceSBarry Smith }
14069b94acceSBarry Smith 
14079b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
14089b94acceSBarry Smith 
14094a2ae208SSatish Balay #undef __FUNCT__
1410a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
1411a8054027SBarry Smith /*@
1412a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
1413a8054027SBarry Smith 
1414a8054027SBarry Smith    Collective on SNES
1415a8054027SBarry Smith 
1416a8054027SBarry Smith    Input Parameters:
1417a8054027SBarry Smith +  snes - the SNES context
1418a8054027SBarry 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
14193b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
1420a8054027SBarry Smith 
1421a8054027SBarry Smith    Options Database Keys:
1422a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
1423a8054027SBarry Smith 
1424a8054027SBarry Smith    Notes:
1425a8054027SBarry Smith    The default is 1
1426a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1427a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
1428a8054027SBarry Smith 
1429a8054027SBarry Smith    Level: intermediate
1430a8054027SBarry Smith 
1431a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1432a8054027SBarry Smith 
1433e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
1434a8054027SBarry Smith 
1435a8054027SBarry Smith @*/
1436a8054027SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESSetLagPreconditioner(SNES snes,PetscInt lag)
1437a8054027SBarry Smith {
1438a8054027SBarry Smith   PetscFunctionBegin;
1439a8054027SBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
14403b4f5425SBarry Smith   if (lag < -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
1441a8054027SBarry Smith   if (!lag) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
1442a8054027SBarry Smith   snes->lagpreconditioner = lag;
1443a8054027SBarry Smith   PetscFunctionReturn(0);
1444a8054027SBarry Smith }
1445a8054027SBarry Smith 
1446a8054027SBarry Smith #undef __FUNCT__
1447a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
1448a8054027SBarry Smith /*@
1449a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
1450a8054027SBarry Smith 
1451a8054027SBarry Smith    Collective on SNES
1452a8054027SBarry Smith 
1453a8054027SBarry Smith    Input Parameter:
1454a8054027SBarry Smith .  snes - the SNES context
1455a8054027SBarry Smith 
1456a8054027SBarry Smith    Output Parameter:
1457a8054027SBarry 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
14583b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
1459a8054027SBarry Smith 
1460a8054027SBarry Smith    Options Database Keys:
1461a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
1462a8054027SBarry Smith 
1463a8054027SBarry Smith    Notes:
1464a8054027SBarry Smith    The default is 1
1465a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1466a8054027SBarry Smith 
1467a8054027SBarry Smith    Level: intermediate
1468a8054027SBarry Smith 
1469a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1470a8054027SBarry Smith 
1471a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
1472a8054027SBarry Smith 
1473a8054027SBarry Smith @*/
1474a8054027SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
1475a8054027SBarry Smith {
1476a8054027SBarry Smith   PetscFunctionBegin;
1477a8054027SBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
1478a8054027SBarry Smith   *lag = snes->lagpreconditioner;
1479a8054027SBarry Smith   PetscFunctionReturn(0);
1480a8054027SBarry Smith }
1481a8054027SBarry Smith 
1482a8054027SBarry Smith #undef __FUNCT__
1483e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
1484e35cf81dSBarry Smith /*@
1485e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
1486e35cf81dSBarry Smith      often the preconditioner is rebuilt.
1487e35cf81dSBarry Smith 
1488e35cf81dSBarry Smith    Collective on SNES
1489e35cf81dSBarry Smith 
1490e35cf81dSBarry Smith    Input Parameters:
1491e35cf81dSBarry Smith +  snes - the SNES context
1492e35cf81dSBarry 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
1493fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
1494e35cf81dSBarry Smith 
1495e35cf81dSBarry Smith    Options Database Keys:
1496e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
1497e35cf81dSBarry Smith 
1498e35cf81dSBarry Smith    Notes:
1499e35cf81dSBarry Smith    The default is 1
1500e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1501fe3ffe1eSBarry 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
1502fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
1503e35cf81dSBarry Smith 
1504e35cf81dSBarry Smith    Level: intermediate
1505e35cf81dSBarry Smith 
1506e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1507e35cf81dSBarry Smith 
1508e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
1509e35cf81dSBarry Smith 
1510e35cf81dSBarry Smith @*/
1511e35cf81dSBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESSetLagJacobian(SNES snes,PetscInt lag)
1512e35cf81dSBarry Smith {
1513e35cf81dSBarry Smith   PetscFunctionBegin;
1514e35cf81dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
1515fe3ffe1eSBarry Smith   if (lag < -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
1516e35cf81dSBarry Smith   if (!lag) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
1517e35cf81dSBarry Smith   snes->lagjacobian = lag;
1518e35cf81dSBarry Smith   PetscFunctionReturn(0);
1519e35cf81dSBarry Smith }
1520e35cf81dSBarry Smith 
1521e35cf81dSBarry Smith #undef __FUNCT__
1522e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
1523e35cf81dSBarry Smith /*@
1524e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
1525e35cf81dSBarry Smith 
1526e35cf81dSBarry Smith    Collective on SNES
1527e35cf81dSBarry Smith 
1528e35cf81dSBarry Smith    Input Parameter:
1529e35cf81dSBarry Smith .  snes - the SNES context
1530e35cf81dSBarry Smith 
1531e35cf81dSBarry Smith    Output Parameter:
1532e35cf81dSBarry 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
1533e35cf81dSBarry Smith          the Jacobian is built etc.
1534e35cf81dSBarry Smith 
1535e35cf81dSBarry Smith    Options Database Keys:
1536e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
1537e35cf81dSBarry Smith 
1538e35cf81dSBarry Smith    Notes:
1539e35cf81dSBarry Smith    The default is 1
1540e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1541e35cf81dSBarry Smith 
1542e35cf81dSBarry Smith    Level: intermediate
1543e35cf81dSBarry Smith 
1544e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1545e35cf81dSBarry Smith 
1546e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
1547e35cf81dSBarry Smith 
1548e35cf81dSBarry Smith @*/
1549e35cf81dSBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESGetLagJacobian(SNES snes,PetscInt *lag)
1550e35cf81dSBarry Smith {
1551e35cf81dSBarry Smith   PetscFunctionBegin;
1552e35cf81dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
1553e35cf81dSBarry Smith   *lag = snes->lagjacobian;
1554e35cf81dSBarry Smith   PetscFunctionReturn(0);
1555e35cf81dSBarry Smith }
1556e35cf81dSBarry Smith 
1557e35cf81dSBarry Smith #undef __FUNCT__
15584a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
15599b94acceSBarry Smith /*@
1560d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
15619b94acceSBarry Smith 
1562c7afd0dbSLois Curfman McInnes    Collective on SNES
1563c7afd0dbSLois Curfman McInnes 
15649b94acceSBarry Smith    Input Parameters:
1565c7afd0dbSLois Curfman McInnes +  snes - the SNES context
156670441072SBarry Smith .  abstol - absolute convergence tolerance
156733174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
156833174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
156933174efeSLois Curfman McInnes            of the change in the solution between steps
157033174efeSLois Curfman McInnes .  maxit - maximum number of iterations
1571c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
1572fee21e36SBarry Smith 
157333174efeSLois Curfman McInnes    Options Database Keys:
157470441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
1575c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
1576c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
1577c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
1578c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
15799b94acceSBarry Smith 
1580d7a720efSLois Curfman McInnes    Notes:
15819b94acceSBarry Smith    The default maximum number of iterations is 50.
15829b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
15839b94acceSBarry Smith 
158436851e7fSLois Curfman McInnes    Level: intermediate
158536851e7fSLois Curfman McInnes 
158633174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
15879b94acceSBarry Smith 
15882492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
15899b94acceSBarry Smith @*/
159063dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
15919b94acceSBarry Smith {
15923a40ed3dSBarry Smith   PetscFunctionBegin;
15934482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
159470441072SBarry Smith   if (abstol != PETSC_DEFAULT)  snes->abstol      = abstol;
1595d7a720efSLois Curfman McInnes   if (rtol != PETSC_DEFAULT)  snes->rtol      = rtol;
1596d7a720efSLois Curfman McInnes   if (stol != PETSC_DEFAULT)  snes->xtol      = stol;
1597d7a720efSLois Curfman McInnes   if (maxit != PETSC_DEFAULT) snes->max_its   = maxit;
1598d7a720efSLois Curfman McInnes   if (maxf != PETSC_DEFAULT)  snes->max_funcs = maxf;
15993a40ed3dSBarry Smith   PetscFunctionReturn(0);
16009b94acceSBarry Smith }
16019b94acceSBarry Smith 
16024a2ae208SSatish Balay #undef __FUNCT__
16034a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
16049b94acceSBarry Smith /*@
160533174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
160633174efeSLois Curfman McInnes 
1607c7afd0dbSLois Curfman McInnes    Not Collective
1608c7afd0dbSLois Curfman McInnes 
160933174efeSLois Curfman McInnes    Input Parameters:
1610c7afd0dbSLois Curfman McInnes +  snes - the SNES context
161185385478SLisandro Dalcin .  atol - absolute convergence tolerance
161233174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
161333174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
161433174efeSLois Curfman McInnes            of the change in the solution between steps
161533174efeSLois Curfman McInnes .  maxit - maximum number of iterations
1616c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
1617fee21e36SBarry Smith 
161833174efeSLois Curfman McInnes    Notes:
161933174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
162033174efeSLois Curfman McInnes 
162136851e7fSLois Curfman McInnes    Level: intermediate
162236851e7fSLois Curfman McInnes 
162333174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
162433174efeSLois Curfman McInnes 
162533174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
162633174efeSLois Curfman McInnes @*/
162785385478SLisandro Dalcin PetscErrorCode PETSCSNES_DLLEXPORT SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
162833174efeSLois Curfman McInnes {
16293a40ed3dSBarry Smith   PetscFunctionBegin;
16304482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
163185385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
163233174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
163333174efeSLois Curfman McInnes   if (stol)  *stol  = snes->xtol;
163433174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
163533174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
16363a40ed3dSBarry Smith   PetscFunctionReturn(0);
163733174efeSLois Curfman McInnes }
163833174efeSLois Curfman McInnes 
16394a2ae208SSatish Balay #undef __FUNCT__
16404a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
164133174efeSLois Curfman McInnes /*@
16429b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
16439b94acceSBarry Smith 
1644fee21e36SBarry Smith    Collective on SNES
1645fee21e36SBarry Smith 
1646c7afd0dbSLois Curfman McInnes    Input Parameters:
1647c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1648c7afd0dbSLois Curfman McInnes -  tol - tolerance
1649c7afd0dbSLois Curfman McInnes 
16509b94acceSBarry Smith    Options Database Key:
1651c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
16529b94acceSBarry Smith 
165336851e7fSLois Curfman McInnes    Level: intermediate
165436851e7fSLois Curfman McInnes 
16559b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
16569b94acceSBarry Smith 
16572492ecdbSBarry Smith .seealso: SNESSetTolerances()
16589b94acceSBarry Smith @*/
165963dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
16609b94acceSBarry Smith {
16613a40ed3dSBarry Smith   PetscFunctionBegin;
16624482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
16639b94acceSBarry Smith   snes->deltatol = tol;
16643a40ed3dSBarry Smith   PetscFunctionReturn(0);
16659b94acceSBarry Smith }
16669b94acceSBarry Smith 
1667df9fa365SBarry Smith /*
1668df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
1669df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
1670df9fa365SBarry Smith    macros instead of functions
1671df9fa365SBarry Smith */
16724a2ae208SSatish Balay #undef __FUNCT__
1673a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
1674a6570f20SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
1675ce1608b8SBarry Smith {
1676dfbe8321SBarry Smith   PetscErrorCode ierr;
1677ce1608b8SBarry Smith 
1678ce1608b8SBarry Smith   PetscFunctionBegin;
16794482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
1680a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
1681ce1608b8SBarry Smith   PetscFunctionReturn(0);
1682ce1608b8SBarry Smith }
1683ce1608b8SBarry Smith 
16844a2ae208SSatish Balay #undef __FUNCT__
1685a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
1686a6570f20SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
1687df9fa365SBarry Smith {
1688dfbe8321SBarry Smith   PetscErrorCode ierr;
1689df9fa365SBarry Smith 
1690df9fa365SBarry Smith   PetscFunctionBegin;
1691a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
1692df9fa365SBarry Smith   PetscFunctionReturn(0);
1693df9fa365SBarry Smith }
1694df9fa365SBarry Smith 
16954a2ae208SSatish Balay #undef __FUNCT__
1696a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
1697a6570f20SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorLGDestroy(PetscDrawLG draw)
1698df9fa365SBarry Smith {
1699dfbe8321SBarry Smith   PetscErrorCode ierr;
1700df9fa365SBarry Smith 
1701df9fa365SBarry Smith   PetscFunctionBegin;
1702a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
1703df9fa365SBarry Smith   PetscFunctionReturn(0);
1704df9fa365SBarry Smith }
1705df9fa365SBarry Smith 
1706b271bb04SBarry Smith extern PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
1707b271bb04SBarry Smith #undef __FUNCT__
1708b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
1709b271bb04SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
1710b271bb04SBarry Smith {
1711b271bb04SBarry Smith   PetscDrawLG      lg;
1712b271bb04SBarry Smith   PetscErrorCode   ierr;
1713b271bb04SBarry Smith   PetscReal        x,y,per;
1714b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
1715b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
1716b271bb04SBarry Smith   PetscDraw        draw;
1717b271bb04SBarry Smith   PetscFunctionBegin;
1718b271bb04SBarry Smith   if (!monctx) {
1719b271bb04SBarry Smith     MPI_Comm    comm;
1720b271bb04SBarry Smith 
1721b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
1722b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
1723b271bb04SBarry Smith   }
1724b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
1725b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
1726b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
1727b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
1728b271bb04SBarry Smith   x = (PetscReal) n;
1729b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
1730b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
1731b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
1732b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
1733b271bb04SBarry Smith   }
1734b271bb04SBarry Smith 
1735b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
1736b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
1737b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
1738b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
1739b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
1740b271bb04SBarry Smith   x = (PetscReal) n;
1741b271bb04SBarry Smith   y = 100.0*per;
1742b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
1743b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
1744b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
1745b271bb04SBarry Smith   }
1746b271bb04SBarry Smith 
1747b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
1748b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
1749b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
1750b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
1751b271bb04SBarry Smith   x = (PetscReal) n;
1752b271bb04SBarry Smith   y = (prev - rnorm)/prev;
1753b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
1754b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
1755b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
1756b271bb04SBarry Smith   }
1757b271bb04SBarry Smith 
1758b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
1759b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
1760b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
1761b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
1762b271bb04SBarry Smith   x = (PetscReal) n;
1763b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
1764b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
1765b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
1766b271bb04SBarry Smith   }
1767b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
1768b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
1769b271bb04SBarry Smith   }
1770b271bb04SBarry Smith   prev = rnorm;
1771b271bb04SBarry Smith   PetscFunctionReturn(0);
1772b271bb04SBarry Smith }
1773b271bb04SBarry Smith 
1774b271bb04SBarry Smith #undef __FUNCT__
1775b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
1776b271bb04SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
1777b271bb04SBarry Smith {
1778b271bb04SBarry Smith   PetscErrorCode ierr;
1779b271bb04SBarry Smith 
1780b271bb04SBarry Smith   PetscFunctionBegin;
1781b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
1782b271bb04SBarry Smith   PetscFunctionReturn(0);
1783b271bb04SBarry Smith }
1784b271bb04SBarry Smith 
1785b271bb04SBarry Smith #undef __FUNCT__
1786b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
1787b271bb04SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorLGRangeDestroy(PetscDrawLG draw)
1788b271bb04SBarry Smith {
1789b271bb04SBarry Smith   PetscErrorCode ierr;
1790b271bb04SBarry Smith 
1791b271bb04SBarry Smith   PetscFunctionBegin;
1792b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
1793b271bb04SBarry Smith   PetscFunctionReturn(0);
1794b271bb04SBarry Smith }
1795b271bb04SBarry Smith 
17969b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
17979b94acceSBarry Smith 
17984a2ae208SSatish Balay #undef __FUNCT__
1799a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
18009b94acceSBarry Smith /*@C
1801a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
18029b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
18039b94acceSBarry Smith    progress.
18049b94acceSBarry Smith 
1805fee21e36SBarry Smith    Collective on SNES
1806fee21e36SBarry Smith 
1807c7afd0dbSLois Curfman McInnes    Input Parameters:
1808c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1809c7afd0dbSLois Curfman McInnes .  func - monitoring routine
1810b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
1811e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
1812b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
1813b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
18149b94acceSBarry Smith 
1815c7afd0dbSLois Curfman McInnes    Calling sequence of func:
1816a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
1817c7afd0dbSLois Curfman McInnes 
1818c7afd0dbSLois Curfman McInnes +    snes - the SNES context
1819c7afd0dbSLois Curfman McInnes .    its - iteration number
1820c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
182140a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
18229b94acceSBarry Smith 
18239665c990SLois Curfman McInnes    Options Database Keys:
1824a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
1825a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
1826a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
1827a6570f20SBarry Smith _    -snes_monitor_cancel - cancels all monitors that have
1828c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
1829a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
1830c7afd0dbSLois Curfman McInnes                             does not cancel those set via
1831c7afd0dbSLois Curfman McInnes                             the options database.
18329665c990SLois Curfman McInnes 
1833639f9d9dSBarry Smith    Notes:
18346bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
1835a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
18366bc08f3fSLois Curfman McInnes    order in which they were set.
1837639f9d9dSBarry Smith 
1838025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
1839025f1a04SBarry Smith 
184036851e7fSLois Curfman McInnes    Level: intermediate
184136851e7fSLois Curfman McInnes 
18429b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
18439b94acceSBarry Smith 
1844a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
18459b94acceSBarry Smith @*/
1846b90d0a6eSBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void*))
18479b94acceSBarry Smith {
1848b90d0a6eSBarry Smith   PetscInt i;
1849b90d0a6eSBarry Smith 
18503a40ed3dSBarry Smith   PetscFunctionBegin;
18514482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
1852639f9d9dSBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) {
185329bbc08cSBarry Smith     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
1854639f9d9dSBarry Smith   }
1855b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
1856b90d0a6eSBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) PetscFunctionReturn(0);
1857b90d0a6eSBarry Smith 
1858b90d0a6eSBarry Smith     /* check if both default monitors that share common ASCII viewer */
1859b90d0a6eSBarry Smith     if (monitor == snes->monitor[i] && monitor == SNESMonitorDefault) {
1860b90d0a6eSBarry Smith       if (mctx && snes->monitorcontext[i]) {
1861b90d0a6eSBarry Smith         PetscErrorCode          ierr;
1862b90d0a6eSBarry Smith         PetscViewerASCIIMonitor viewer1 = (PetscViewerASCIIMonitor) mctx;
1863b90d0a6eSBarry Smith         PetscViewerASCIIMonitor viewer2 = (PetscViewerASCIIMonitor) snes->monitorcontext[i];
1864b90d0a6eSBarry Smith         if (viewer1->viewer == viewer2->viewer) {
1865b90d0a6eSBarry Smith           ierr = (*monitordestroy)(mctx);CHKERRQ(ierr);
1866b90d0a6eSBarry Smith           PetscFunctionReturn(0);
1867b90d0a6eSBarry Smith         }
1868b90d0a6eSBarry Smith       }
1869b90d0a6eSBarry Smith     }
1870b90d0a6eSBarry Smith   }
1871b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
1872b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
1873639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
18743a40ed3dSBarry Smith   PetscFunctionReturn(0);
18759b94acceSBarry Smith }
18769b94acceSBarry Smith 
18774a2ae208SSatish Balay #undef __FUNCT__
1878a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
18795cd90555SBarry Smith /*@C
1880a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
18815cd90555SBarry Smith 
1882c7afd0dbSLois Curfman McInnes    Collective on SNES
1883c7afd0dbSLois Curfman McInnes 
18845cd90555SBarry Smith    Input Parameters:
18855cd90555SBarry Smith .  snes - the SNES context
18865cd90555SBarry Smith 
18871a480d89SAdministrator    Options Database Key:
1888a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
1889a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
1890c7afd0dbSLois Curfman McInnes     set via the options database
18915cd90555SBarry Smith 
18925cd90555SBarry Smith    Notes:
18935cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
18945cd90555SBarry Smith 
189536851e7fSLois Curfman McInnes    Level: intermediate
189636851e7fSLois Curfman McInnes 
18975cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
18985cd90555SBarry Smith 
1899a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
19005cd90555SBarry Smith @*/
1901a6570f20SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESMonitorCancel(SNES snes)
19025cd90555SBarry Smith {
1903d952e501SBarry Smith   PetscErrorCode ierr;
1904d952e501SBarry Smith   PetscInt       i;
1905d952e501SBarry Smith 
19065cd90555SBarry Smith   PetscFunctionBegin;
19074482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
1908d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
1909d952e501SBarry Smith     if (snes->monitordestroy[i]) {
1910d952e501SBarry Smith       ierr = (*snes->monitordestroy[i])(snes->monitorcontext[i]);CHKERRQ(ierr);
1911d952e501SBarry Smith     }
1912d952e501SBarry Smith   }
19135cd90555SBarry Smith   snes->numbermonitors = 0;
19145cd90555SBarry Smith   PetscFunctionReturn(0);
19155cd90555SBarry Smith }
19165cd90555SBarry Smith 
19174a2ae208SSatish Balay #undef __FUNCT__
19184a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
19199b94acceSBarry Smith /*@C
19209b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
19219b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
19229b94acceSBarry Smith 
1923fee21e36SBarry Smith    Collective on SNES
1924fee21e36SBarry Smith 
1925c7afd0dbSLois Curfman McInnes    Input Parameters:
1926c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1927c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
19287f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
19297f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
19309b94acceSBarry Smith 
1931c7afd0dbSLois Curfman McInnes    Calling sequence of func:
193206ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
1933c7afd0dbSLois Curfman McInnes 
1934c7afd0dbSLois Curfman McInnes +    snes - the SNES context
193506ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
1936c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
1937184914b5SBarry Smith .    reason - reason for convergence/divergence
1938c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
19394b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
19404b27c08aSLois Curfman McInnes -    f - 2-norm of function
19419b94acceSBarry Smith 
194236851e7fSLois Curfman McInnes    Level: advanced
194336851e7fSLois Curfman McInnes 
19449b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
19459b94acceSBarry Smith 
194685385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
19479b94acceSBarry Smith @*/
19487f7931b9SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
19499b94acceSBarry Smith {
19507f7931b9SBarry Smith   PetscErrorCode ierr;
19517f7931b9SBarry Smith 
19523a40ed3dSBarry Smith   PetscFunctionBegin;
19534482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
195485385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
19557f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
19567f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
19577f7931b9SBarry Smith   }
195885385478SLisandro Dalcin   snes->ops->converged        = func;
19597f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
196085385478SLisandro Dalcin   snes->cnvP                  = cctx;
19613a40ed3dSBarry Smith   PetscFunctionReturn(0);
19629b94acceSBarry Smith }
19639b94acceSBarry Smith 
19644a2ae208SSatish Balay #undef __FUNCT__
19654a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
196652baeb72SSatish Balay /*@
1967184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
1968184914b5SBarry Smith 
1969184914b5SBarry Smith    Not Collective
1970184914b5SBarry Smith 
1971184914b5SBarry Smith    Input Parameter:
1972184914b5SBarry Smith .  snes - the SNES context
1973184914b5SBarry Smith 
1974184914b5SBarry Smith    Output Parameter:
19754d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
1976184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
1977184914b5SBarry Smith 
1978184914b5SBarry Smith    Level: intermediate
1979184914b5SBarry Smith 
1980184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
1981184914b5SBarry Smith 
1982184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
1983184914b5SBarry Smith 
198485385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
1985184914b5SBarry Smith @*/
198663dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
1987184914b5SBarry Smith {
1988184914b5SBarry Smith   PetscFunctionBegin;
19894482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
19904482741eSBarry Smith   PetscValidPointer(reason,2);
1991184914b5SBarry Smith   *reason = snes->reason;
1992184914b5SBarry Smith   PetscFunctionReturn(0);
1993184914b5SBarry Smith }
1994184914b5SBarry Smith 
19954a2ae208SSatish Balay #undef __FUNCT__
19964a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
1997c9005455SLois Curfman McInnes /*@
1998c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
1999c9005455SLois Curfman McInnes 
2000fee21e36SBarry Smith    Collective on SNES
2001fee21e36SBarry Smith 
2002c7afd0dbSLois Curfman McInnes    Input Parameters:
2003c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
20048c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
2005cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
2006758f92a0SBarry Smith .  na  - size of a and its
200764731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
2008758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
2009c7afd0dbSLois Curfman McInnes 
2010c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
2011c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
2012c9005455SLois Curfman McInnes    during the section of code that is being timed.
2013c9005455SLois Curfman McInnes 
201436851e7fSLois Curfman McInnes    Level: intermediate
201536851e7fSLois Curfman McInnes 
2016c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
2017758f92a0SBarry Smith 
201808405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
2019758f92a0SBarry Smith 
2020c9005455SLois Curfman McInnes @*/
2021a562a398SLisandro Dalcin PetscErrorCode PETSCSNES_DLLEXPORT SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscTruth reset)
2022c9005455SLois Curfman McInnes {
20233a40ed3dSBarry Smith   PetscFunctionBegin;
20244482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
20254482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
2026a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
2027c9005455SLois Curfman McInnes   snes->conv_hist       = a;
2028758f92a0SBarry Smith   snes->conv_hist_its   = its;
2029758f92a0SBarry Smith   snes->conv_hist_max   = na;
2030a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
2031758f92a0SBarry Smith   snes->conv_hist_reset = reset;
2032758f92a0SBarry Smith   PetscFunctionReturn(0);
2033758f92a0SBarry Smith }
2034758f92a0SBarry Smith 
20354a2ae208SSatish Balay #undef __FUNCT__
20364a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
20370c4c9dddSBarry Smith /*@C
2038758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
2039758f92a0SBarry Smith 
2040758f92a0SBarry Smith    Collective on SNES
2041758f92a0SBarry Smith 
2042758f92a0SBarry Smith    Input Parameter:
2043758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
2044758f92a0SBarry Smith 
2045758f92a0SBarry Smith    Output Parameters:
2046758f92a0SBarry Smith .  a   - array to hold history
2047758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
2048758f92a0SBarry Smith          negative if not converged) for each solve.
2049758f92a0SBarry Smith -  na  - size of a and its
2050758f92a0SBarry Smith 
2051758f92a0SBarry Smith    Notes:
2052758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
2053758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
2054758f92a0SBarry Smith 
2055758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
2056758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
2057758f92a0SBarry Smith    during the section of code that is being timed.
2058758f92a0SBarry Smith 
2059758f92a0SBarry Smith    Level: intermediate
2060758f92a0SBarry Smith 
2061758f92a0SBarry Smith .keywords: SNES, get, convergence, history
2062758f92a0SBarry Smith 
2063758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
2064758f92a0SBarry Smith 
2065758f92a0SBarry Smith @*/
206663dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
2067758f92a0SBarry Smith {
2068758f92a0SBarry Smith   PetscFunctionBegin;
20694482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
2070758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
2071758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
2072758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
20733a40ed3dSBarry Smith   PetscFunctionReturn(0);
2074c9005455SLois Curfman McInnes }
2075c9005455SLois Curfman McInnes 
2076e74ef692SMatthew Knepley #undef __FUNCT__
2077e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
2078ac226902SBarry Smith /*@C
207976b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
20807e4bb74cSBarry Smith   at the beginning o every iteration of the nonlinear solve. Specifically
20817e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
208276b2cf59SMatthew Knepley 
208376b2cf59SMatthew Knepley   Collective on SNES
208476b2cf59SMatthew Knepley 
208576b2cf59SMatthew Knepley   Input Parameters:
208676b2cf59SMatthew Knepley . snes - The nonlinear solver context
208776b2cf59SMatthew Knepley . func - The function
208876b2cf59SMatthew Knepley 
208976b2cf59SMatthew Knepley   Calling sequence of func:
2090b5d30489SBarry Smith . func (SNES snes, PetscInt step);
209176b2cf59SMatthew Knepley 
209276b2cf59SMatthew Knepley . step - The current step of the iteration
209376b2cf59SMatthew Knepley 
209476b2cf59SMatthew Knepley   Level: intermediate
209576b2cf59SMatthew Knepley 
209676b2cf59SMatthew Knepley .keywords: SNES, update
2097b5d30489SBarry Smith 
209885385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
209976b2cf59SMatthew Knepley @*/
210063dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
210176b2cf59SMatthew Knepley {
210276b2cf59SMatthew Knepley   PetscFunctionBegin;
21034482741eSBarry Smith   PetscValidHeaderSpecific(snes, SNES_COOKIE,1);
2104e7788613SBarry Smith   snes->ops->update = func;
210576b2cf59SMatthew Knepley   PetscFunctionReturn(0);
210676b2cf59SMatthew Knepley }
210776b2cf59SMatthew Knepley 
2108e74ef692SMatthew Knepley #undef __FUNCT__
2109e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
211076b2cf59SMatthew Knepley /*@
211176b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
211276b2cf59SMatthew Knepley 
211376b2cf59SMatthew Knepley   Not collective
211476b2cf59SMatthew Knepley 
211576b2cf59SMatthew Knepley   Input Parameters:
211676b2cf59SMatthew Knepley . snes - The nonlinear solver context
211776b2cf59SMatthew Knepley . step - The current step of the iteration
211876b2cf59SMatthew Knepley 
2119205452f4SMatthew Knepley   Level: intermediate
2120205452f4SMatthew Knepley 
212176b2cf59SMatthew Knepley .keywords: SNES, update
2122a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
212376b2cf59SMatthew Knepley @*/
212463dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESDefaultUpdate(SNES snes, PetscInt step)
212576b2cf59SMatthew Knepley {
212676b2cf59SMatthew Knepley   PetscFunctionBegin;
212776b2cf59SMatthew Knepley   PetscFunctionReturn(0);
212876b2cf59SMatthew Knepley }
212976b2cf59SMatthew Knepley 
21304a2ae208SSatish Balay #undef __FUNCT__
21314a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
21329b94acceSBarry Smith /*
21339b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
21349b94acceSBarry Smith    positive parameter delta.
21359b94acceSBarry Smith 
21369b94acceSBarry Smith     Input Parameters:
2137c7afd0dbSLois Curfman McInnes +   snes - the SNES context
21389b94acceSBarry Smith .   y - approximate solution of linear system
21399b94acceSBarry Smith .   fnorm - 2-norm of current function
2140c7afd0dbSLois Curfman McInnes -   delta - trust region size
21419b94acceSBarry Smith 
21429b94acceSBarry Smith     Output Parameters:
2143c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
21449b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
21459b94acceSBarry Smith     region, and exceeds zero otherwise.
2146c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
21479b94acceSBarry Smith 
21489b94acceSBarry Smith     Note:
21494b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
21509b94acceSBarry Smith     is set to be the maximum allowable step size.
21519b94acceSBarry Smith 
21529b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
21539b94acceSBarry Smith */
2154dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
21559b94acceSBarry Smith {
2156064f8208SBarry Smith   PetscReal      nrm;
2157ea709b57SSatish Balay   PetscScalar    cnorm;
2158dfbe8321SBarry Smith   PetscErrorCode ierr;
21593a40ed3dSBarry Smith 
21603a40ed3dSBarry Smith   PetscFunctionBegin;
21614482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
21624482741eSBarry Smith   PetscValidHeaderSpecific(y,VEC_COOKIE,2);
2163c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
2164184914b5SBarry Smith 
2165064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
2166064f8208SBarry Smith   if (nrm > *delta) {
2167064f8208SBarry Smith      nrm = *delta/nrm;
2168064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
2169064f8208SBarry Smith      cnorm = nrm;
21702dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
21719b94acceSBarry Smith      *ynorm = *delta;
21729b94acceSBarry Smith   } else {
21739b94acceSBarry Smith      *gpnorm = 0.0;
2174064f8208SBarry Smith      *ynorm = nrm;
21759b94acceSBarry Smith   }
21763a40ed3dSBarry Smith   PetscFunctionReturn(0);
21779b94acceSBarry Smith }
21789b94acceSBarry Smith 
21794a2ae208SSatish Balay #undef __FUNCT__
21804a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
21816ce558aeSBarry Smith /*@C
2182f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
2183f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
21849b94acceSBarry Smith 
2185c7afd0dbSLois Curfman McInnes    Collective on SNES
2186c7afd0dbSLois Curfman McInnes 
2187b2002411SLois Curfman McInnes    Input Parameters:
2188c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2189f69a0ea3SMatthew Knepley .  b - the constant part of the equation, or PETSC_NULL to use zero.
219085385478SLisandro Dalcin -  x - the solution vector.
21919b94acceSBarry Smith 
2192b2002411SLois Curfman McInnes    Notes:
21938ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
21948ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
21958ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
21968ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
21978ddd3da0SLois Curfman McInnes 
219836851e7fSLois Curfman McInnes    Level: beginner
219936851e7fSLois Curfman McInnes 
22009b94acceSBarry Smith .keywords: SNES, nonlinear, solve
22019b94acceSBarry Smith 
220285385478SLisandro Dalcin .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian()
22039b94acceSBarry Smith @*/
2204f69a0ea3SMatthew Knepley PetscErrorCode PETSCSNES_DLLEXPORT SNESSolve(SNES snes,Vec b,Vec x)
22059b94acceSBarry Smith {
2206dfbe8321SBarry Smith   PetscErrorCode ierr;
2207f1af5d2fSBarry Smith   PetscTruth     flg;
2208eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
2209eabae89aSBarry Smith   PetscViewer    viewer;
2210052efed2SBarry Smith 
22113a40ed3dSBarry Smith   PetscFunctionBegin;
22124482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
2213f69a0ea3SMatthew Knepley   PetscValidHeaderSpecific(x,VEC_COOKIE,3);
2214f69a0ea3SMatthew Knepley   PetscCheckSameComm(snes,1,x,3);
221585385478SLisandro Dalcin   if (b) PetscValidHeaderSpecific(b,VEC_COOKIE,2);
221685385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
221785385478SLisandro Dalcin 
221885385478SLisandro Dalcin   /* set solution vector */
221985385478SLisandro Dalcin   ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);
222085385478SLisandro Dalcin   if (snes->vec_sol) { ierr = VecDestroy(snes->vec_sol);CHKERRQ(ierr); }
222185385478SLisandro Dalcin   snes->vec_sol = x;
222285385478SLisandro Dalcin   /* set afine vector if provided */
222385385478SLisandro Dalcin   if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
222485385478SLisandro Dalcin   if (snes->vec_rhs) { ierr = VecDestroy(snes->vec_rhs);CHKERRQ(ierr); }
222585385478SLisandro Dalcin   snes->vec_rhs = b;
222685385478SLisandro Dalcin 
222785385478SLisandro Dalcin   if (!snes->vec_func && snes->vec_rhs) {
222885385478SLisandro Dalcin     ierr = VecDuplicate(b, &snes->vec_func);CHKERRQ(ierr);
222970e92668SMatthew Knepley   }
22303f149594SLisandro Dalcin 
223170e92668SMatthew Knepley   ierr = SNESSetUp(snes);CHKERRQ(ierr);
22323f149594SLisandro Dalcin 
2233abc0a331SBarry Smith   if (snes->conv_hist_reset) snes->conv_hist_len = 0;
223450ffb88aSMatthew Knepley   snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
2235d5e45103SBarry Smith 
22363f149594SLisandro Dalcin   ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
22374936397dSBarry Smith   ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
223885385478SLisandro Dalcin   ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
22394936397dSBarry Smith   if (snes->domainerror){
22404936397dSBarry Smith     snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
22414936397dSBarry Smith     snes->domainerror = PETSC_FALSE;
22424936397dSBarry Smith   }
224385385478SLisandro Dalcin 
22443f149594SLisandro Dalcin   if (!snes->reason) {
22453f149594SLisandro Dalcin     SETERRQ(PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
22463f149594SLisandro Dalcin   }
22473f149594SLisandro Dalcin 
22487adad957SLisandro Dalcin   ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
2249eabae89aSBarry Smith   if (flg && !PetscPreLoadingOn) {
22507adad957SLisandro Dalcin     ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
2251eabae89aSBarry Smith     ierr = SNESView(snes,viewer);CHKERRQ(ierr);
2252eabae89aSBarry Smith     ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr);
2253eabae89aSBarry Smith   }
2254eabae89aSBarry Smith 
225590d69ab7SBarry Smith   flg  = PETSC_FALSE;
225690d69ab7SBarry Smith   ierr = PetscOptionsGetTruth(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
2257da9b6338SBarry Smith   if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
22585968eb51SBarry Smith   if (snes->printreason) {
22595968eb51SBarry Smith     if (snes->reason > 0) {
22607adad957SLisandro Dalcin       ierr = PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr);
22615968eb51SBarry Smith     } else {
22627adad957SLisandro Dalcin       ierr = PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr);
22635968eb51SBarry Smith     }
22645968eb51SBarry Smith   }
22655968eb51SBarry Smith 
22663a40ed3dSBarry Smith   PetscFunctionReturn(0);
22679b94acceSBarry Smith }
22689b94acceSBarry Smith 
22699b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
22709b94acceSBarry Smith 
22714a2ae208SSatish Balay #undef __FUNCT__
22724a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
227382bf6240SBarry Smith /*@C
22744b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
22759b94acceSBarry Smith 
2276fee21e36SBarry Smith    Collective on SNES
2277fee21e36SBarry Smith 
2278c7afd0dbSLois Curfman McInnes    Input Parameters:
2279c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2280454a90a3SBarry Smith -  type - a known method
2281c7afd0dbSLois Curfman McInnes 
2282c7afd0dbSLois Curfman McInnes    Options Database Key:
2283454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
2284c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
2285ae12b187SLois Curfman McInnes 
22869b94acceSBarry Smith    Notes:
2287e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
22884b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
2289c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
22904b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
2291c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
22929b94acceSBarry Smith 
2293ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
2294ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
2295ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
2296ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
2297ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
2298ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
2299ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
2300ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
2301ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
2302b0a32e0cSBarry Smith   appropriate method.
230336851e7fSLois Curfman McInnes 
230436851e7fSLois Curfman McInnes   Level: intermediate
2305a703fe33SLois Curfman McInnes 
2306454a90a3SBarry Smith .keywords: SNES, set, type
2307435da068SBarry Smith 
2308435da068SBarry Smith .seealso: SNESType, SNESCreate()
2309435da068SBarry Smith 
23109b94acceSBarry Smith @*/
2311a313700dSBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESSetType(SNES snes,const SNESType type)
23129b94acceSBarry Smith {
2313dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
23146831982aSBarry Smith   PetscTruth     match;
23153a40ed3dSBarry Smith 
23163a40ed3dSBarry Smith   PetscFunctionBegin;
23174482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
23184482741eSBarry Smith   PetscValidCharPointer(type,2);
231982bf6240SBarry Smith 
23206831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
23210f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
232292ff6ae8SBarry Smith 
23237adad957SLisandro Dalcin   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,(void (**)(void)) &r);CHKERRQ(ierr);
2324958c9bccSBarry Smith   if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
232575396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
232675396ef9SLisandro Dalcin   if (snes->ops->destroy) { ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); }
232775396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
232875396ef9SLisandro Dalcin   snes->ops->setup          = 0;
232975396ef9SLisandro Dalcin   snes->ops->solve          = 0;
233075396ef9SLisandro Dalcin   snes->ops->view           = 0;
233175396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
233275396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
233375396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
233475396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
23353a40ed3dSBarry Smith   ierr = (*r)(snes);CHKERRQ(ierr);
2336454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
23373a40ed3dSBarry Smith   PetscFunctionReturn(0);
23389b94acceSBarry Smith }
23399b94acceSBarry Smith 
2340a847f771SSatish Balay 
23419b94acceSBarry Smith /* --------------------------------------------------------------------- */
23424a2ae208SSatish Balay #undef __FUNCT__
23434a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
234452baeb72SSatish Balay /*@
23459b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
2346f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
23479b94acceSBarry Smith 
2348fee21e36SBarry Smith    Not Collective
2349fee21e36SBarry Smith 
235036851e7fSLois Curfman McInnes    Level: advanced
235136851e7fSLois Curfman McInnes 
23529b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
23539b94acceSBarry Smith 
23549b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
23559b94acceSBarry Smith @*/
235663dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESRegisterDestroy(void)
23579b94acceSBarry Smith {
2358dfbe8321SBarry Smith   PetscErrorCode ierr;
235982bf6240SBarry Smith 
23603a40ed3dSBarry Smith   PetscFunctionBegin;
23611441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
23624c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
23633a40ed3dSBarry Smith   PetscFunctionReturn(0);
23649b94acceSBarry Smith }
23659b94acceSBarry Smith 
23664a2ae208SSatish Balay #undef __FUNCT__
23674a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
23689b94acceSBarry Smith /*@C
23699a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
23709b94acceSBarry Smith 
2371c7afd0dbSLois Curfman McInnes    Not Collective
2372c7afd0dbSLois Curfman McInnes 
23739b94acceSBarry Smith    Input Parameter:
23744b0e389bSBarry Smith .  snes - nonlinear solver context
23759b94acceSBarry Smith 
23769b94acceSBarry Smith    Output Parameter:
23773a7fca6bSBarry Smith .  type - SNES method (a character string)
23789b94acceSBarry Smith 
237936851e7fSLois Curfman McInnes    Level: intermediate
238036851e7fSLois Curfman McInnes 
2381454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
23829b94acceSBarry Smith @*/
2383a313700dSBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESGetType(SNES snes,const SNESType *type)
23849b94acceSBarry Smith {
23853a40ed3dSBarry Smith   PetscFunctionBegin;
23864482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
23874482741eSBarry Smith   PetscValidPointer(type,2);
23887adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
23893a40ed3dSBarry Smith   PetscFunctionReturn(0);
23909b94acceSBarry Smith }
23919b94acceSBarry Smith 
23924a2ae208SSatish Balay #undef __FUNCT__
23934a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
239452baeb72SSatish Balay /*@
23959b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
23969b94acceSBarry Smith    stored.
23979b94acceSBarry Smith 
2398c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
2399c7afd0dbSLois Curfman McInnes 
24009b94acceSBarry Smith    Input Parameter:
24019b94acceSBarry Smith .  snes - the SNES context
24029b94acceSBarry Smith 
24039b94acceSBarry Smith    Output Parameter:
24049b94acceSBarry Smith .  x - the solution
24059b94acceSBarry Smith 
240670e92668SMatthew Knepley    Level: intermediate
240736851e7fSLois Curfman McInnes 
24089b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
24099b94acceSBarry Smith 
241085385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
24119b94acceSBarry Smith @*/
241263dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESGetSolution(SNES snes,Vec *x)
24139b94acceSBarry Smith {
24143a40ed3dSBarry Smith   PetscFunctionBegin;
24154482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
24164482741eSBarry Smith   PetscValidPointer(x,2);
241785385478SLisandro Dalcin   *x = snes->vec_sol;
241870e92668SMatthew Knepley   PetscFunctionReturn(0);
241970e92668SMatthew Knepley }
242070e92668SMatthew Knepley 
242170e92668SMatthew Knepley #undef __FUNCT__
24224a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
242352baeb72SSatish Balay /*@
24249b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
24259b94acceSBarry Smith    stored.
24269b94acceSBarry Smith 
2427c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
2428c7afd0dbSLois Curfman McInnes 
24299b94acceSBarry Smith    Input Parameter:
24309b94acceSBarry Smith .  snes - the SNES context
24319b94acceSBarry Smith 
24329b94acceSBarry Smith    Output Parameter:
24339b94acceSBarry Smith .  x - the solution update
24349b94acceSBarry Smith 
243536851e7fSLois Curfman McInnes    Level: advanced
243636851e7fSLois Curfman McInnes 
24379b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
24389b94acceSBarry Smith 
243985385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
24409b94acceSBarry Smith @*/
244163dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESGetSolutionUpdate(SNES snes,Vec *x)
24429b94acceSBarry Smith {
24433a40ed3dSBarry Smith   PetscFunctionBegin;
24444482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
24454482741eSBarry Smith   PetscValidPointer(x,2);
244685385478SLisandro Dalcin   *x = snes->vec_sol_update;
24473a40ed3dSBarry Smith   PetscFunctionReturn(0);
24489b94acceSBarry Smith }
24499b94acceSBarry Smith 
24504a2ae208SSatish Balay #undef __FUNCT__
24514a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
24529b94acceSBarry Smith /*@C
24533638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
24549b94acceSBarry Smith 
2455c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
2456c7afd0dbSLois Curfman McInnes 
24579b94acceSBarry Smith    Input Parameter:
24589b94acceSBarry Smith .  snes - the SNES context
24599b94acceSBarry Smith 
24609b94acceSBarry Smith    Output Parameter:
24617bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
246270e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
246370e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
24649b94acceSBarry Smith 
246536851e7fSLois Curfman McInnes    Level: advanced
246636851e7fSLois Curfman McInnes 
2467a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
24689b94acceSBarry Smith 
24694b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
24709b94acceSBarry Smith @*/
247170e92668SMatthew Knepley PetscErrorCode PETSCSNES_DLLEXPORT SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
24729b94acceSBarry Smith {
24733a40ed3dSBarry Smith   PetscFunctionBegin;
24744482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
247585385478SLisandro Dalcin   if (r)    *r    = snes->vec_func;
2476e7788613SBarry Smith   if (func) *func = snes->ops->computefunction;
247770e92668SMatthew Knepley   if (ctx)  *ctx  = snes->funP;
24783a40ed3dSBarry Smith   PetscFunctionReturn(0);
24799b94acceSBarry Smith }
24809b94acceSBarry Smith 
24814a2ae208SSatish Balay #undef __FUNCT__
24824a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
24833c7409f5SSatish Balay /*@C
24843c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
2485d850072dSLois Curfman McInnes    SNES options in the database.
24863c7409f5SSatish Balay 
2487fee21e36SBarry Smith    Collective on SNES
2488fee21e36SBarry Smith 
2489c7afd0dbSLois Curfman McInnes    Input Parameter:
2490c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2491c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
2492c7afd0dbSLois Curfman McInnes 
2493d850072dSLois Curfman McInnes    Notes:
2494a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
2495c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
2496d850072dSLois Curfman McInnes 
249736851e7fSLois Curfman McInnes    Level: advanced
249836851e7fSLois Curfman McInnes 
24993c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
2500a86d99e1SLois Curfman McInnes 
2501a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
25023c7409f5SSatish Balay @*/
250363dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESSetOptionsPrefix(SNES snes,const char prefix[])
25043c7409f5SSatish Balay {
2505dfbe8321SBarry Smith   PetscErrorCode ierr;
25063c7409f5SSatish Balay 
25073a40ed3dSBarry Smith   PetscFunctionBegin;
25084482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
2509639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
25101cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
251194b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
25123a40ed3dSBarry Smith   PetscFunctionReturn(0);
25133c7409f5SSatish Balay }
25143c7409f5SSatish Balay 
25154a2ae208SSatish Balay #undef __FUNCT__
25164a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
25173c7409f5SSatish Balay /*@C
2518f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
2519d850072dSLois Curfman McInnes    SNES options in the database.
25203c7409f5SSatish Balay 
2521fee21e36SBarry Smith    Collective on SNES
2522fee21e36SBarry Smith 
2523c7afd0dbSLois Curfman McInnes    Input Parameters:
2524c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2525c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
2526c7afd0dbSLois Curfman McInnes 
2527d850072dSLois Curfman McInnes    Notes:
2528a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
2529c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
2530d850072dSLois Curfman McInnes 
253136851e7fSLois Curfman McInnes    Level: advanced
253236851e7fSLois Curfman McInnes 
25333c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
2534a86d99e1SLois Curfman McInnes 
2535a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
25363c7409f5SSatish Balay @*/
253763dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESAppendOptionsPrefix(SNES snes,const char prefix[])
25383c7409f5SSatish Balay {
2539dfbe8321SBarry Smith   PetscErrorCode ierr;
25403c7409f5SSatish Balay 
25413a40ed3dSBarry Smith   PetscFunctionBegin;
25424482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
2543639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
25441cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
254594b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
25463a40ed3dSBarry Smith   PetscFunctionReturn(0);
25473c7409f5SSatish Balay }
25483c7409f5SSatish Balay 
25494a2ae208SSatish Balay #undef __FUNCT__
25504a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
25519ab63eb5SSatish Balay /*@C
25523c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
25533c7409f5SSatish Balay    SNES options in the database.
25543c7409f5SSatish Balay 
2555c7afd0dbSLois Curfman McInnes    Not Collective
2556c7afd0dbSLois Curfman McInnes 
25573c7409f5SSatish Balay    Input Parameter:
25583c7409f5SSatish Balay .  snes - the SNES context
25593c7409f5SSatish Balay 
25603c7409f5SSatish Balay    Output Parameter:
25613c7409f5SSatish Balay .  prefix - pointer to the prefix string used
25623c7409f5SSatish Balay 
25634ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
25649ab63eb5SSatish Balay    sufficient length to hold the prefix.
25659ab63eb5SSatish Balay 
256636851e7fSLois Curfman McInnes    Level: advanced
256736851e7fSLois Curfman McInnes 
25683c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
2569a86d99e1SLois Curfman McInnes 
2570a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
25713c7409f5SSatish Balay @*/
2572e060cb09SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESGetOptionsPrefix(SNES snes,const char *prefix[])
25733c7409f5SSatish Balay {
2574dfbe8321SBarry Smith   PetscErrorCode ierr;
25753c7409f5SSatish Balay 
25763a40ed3dSBarry Smith   PetscFunctionBegin;
25774482741eSBarry Smith   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
2578639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
25793a40ed3dSBarry Smith   PetscFunctionReturn(0);
25803c7409f5SSatish Balay }
25813c7409f5SSatish Balay 
2582b2002411SLois Curfman McInnes 
25834a2ae208SSatish Balay #undef __FUNCT__
25844a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
25853cea93caSBarry Smith /*@C
25863cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
25873cea93caSBarry Smith 
25887f6c08e0SMatthew Knepley   Level: advanced
25893cea93caSBarry Smith @*/
259063dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
2591b2002411SLois Curfman McInnes {
2592e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
2593dfbe8321SBarry Smith   PetscErrorCode ierr;
2594b2002411SLois Curfman McInnes 
2595b2002411SLois Curfman McInnes   PetscFunctionBegin;
2596b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
2597c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
2598b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
2599b2002411SLois Curfman McInnes }
2600da9b6338SBarry Smith 
2601da9b6338SBarry Smith #undef __FUNCT__
2602da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
260363dd3a1aSKris Buschelman PetscErrorCode PETSCSNES_DLLEXPORT SNESTestLocalMin(SNES snes)
2604da9b6338SBarry Smith {
2605dfbe8321SBarry Smith   PetscErrorCode ierr;
260677431f27SBarry Smith   PetscInt       N,i,j;
2607da9b6338SBarry Smith   Vec            u,uh,fh;
2608da9b6338SBarry Smith   PetscScalar    value;
2609da9b6338SBarry Smith   PetscReal      norm;
2610da9b6338SBarry Smith 
2611da9b6338SBarry Smith   PetscFunctionBegin;
2612da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
2613da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
2614da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
2615da9b6338SBarry Smith 
2616da9b6338SBarry Smith   /* currently only works for sequential */
2617da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
2618da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
2619da9b6338SBarry Smith   for (i=0; i<N; i++) {
2620da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
262177431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
2622da9b6338SBarry Smith     for (j=-10; j<11; j++) {
2623ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
2624da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
26253ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
2626da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
262777431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
2628da9b6338SBarry Smith       value = -value;
2629da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
2630da9b6338SBarry Smith     }
2631da9b6338SBarry Smith   }
2632da9b6338SBarry Smith   ierr = VecDestroy(uh);CHKERRQ(ierr);
2633da9b6338SBarry Smith   ierr = VecDestroy(fh);CHKERRQ(ierr);
2634da9b6338SBarry Smith   PetscFunctionReturn(0);
2635da9b6338SBarry Smith }
263671f87433Sdalcinl 
263771f87433Sdalcinl #undef __FUNCT__
2638fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
263971f87433Sdalcinl /*@
2640fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
264171f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
264271f87433Sdalcinl    Newton method.
264371f87433Sdalcinl 
264471f87433Sdalcinl    Collective on SNES
264571f87433Sdalcinl 
264671f87433Sdalcinl    Input Parameters:
264771f87433Sdalcinl +  snes - SNES context
264871f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
264971f87433Sdalcinl 
265064ba62caSBarry Smith     Options Database:
265164ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
265264ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
265364ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
265464ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
265564ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
265664ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
265764ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
265864ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
265964ba62caSBarry Smith 
266071f87433Sdalcinl    Notes:
266171f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
266271f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
266371f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
266471f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
266571f87433Sdalcinl    solver.
266671f87433Sdalcinl 
266771f87433Sdalcinl    Level: advanced
266871f87433Sdalcinl 
266971f87433Sdalcinl    Reference:
267071f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
267171f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
267271f87433Sdalcinl 
267371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
267471f87433Sdalcinl 
2675fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
267671f87433Sdalcinl @*/
2677fa9f3622SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESKSPSetUseEW(SNES snes,PetscTruth flag)
267871f87433Sdalcinl {
267971f87433Sdalcinl   PetscFunctionBegin;
268071f87433Sdalcinl   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
268171f87433Sdalcinl   snes->ksp_ewconv = flag;
268271f87433Sdalcinl   PetscFunctionReturn(0);
268371f87433Sdalcinl }
268471f87433Sdalcinl 
268571f87433Sdalcinl #undef __FUNCT__
2686fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
268771f87433Sdalcinl /*@
2688fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
268971f87433Sdalcinl    for computing relative tolerance for linear solvers within an
269071f87433Sdalcinl    inexact Newton method.
269171f87433Sdalcinl 
269271f87433Sdalcinl    Not Collective
269371f87433Sdalcinl 
269471f87433Sdalcinl    Input Parameter:
269571f87433Sdalcinl .  snes - SNES context
269671f87433Sdalcinl 
269771f87433Sdalcinl    Output Parameter:
269871f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
269971f87433Sdalcinl 
270071f87433Sdalcinl    Notes:
270171f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
270271f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
270371f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
270471f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
270571f87433Sdalcinl    solver.
270671f87433Sdalcinl 
270771f87433Sdalcinl    Level: advanced
270871f87433Sdalcinl 
270971f87433Sdalcinl    Reference:
271071f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
271171f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
271271f87433Sdalcinl 
271371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
271471f87433Sdalcinl 
2715fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
271671f87433Sdalcinl @*/
2717fa9f3622SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESKSPGetUseEW(SNES snes, PetscTruth *flag)
271871f87433Sdalcinl {
271971f87433Sdalcinl   PetscFunctionBegin;
272071f87433Sdalcinl   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
272171f87433Sdalcinl   PetscValidPointer(flag,2);
272271f87433Sdalcinl   *flag = snes->ksp_ewconv;
272371f87433Sdalcinl   PetscFunctionReturn(0);
272471f87433Sdalcinl }
272571f87433Sdalcinl 
272671f87433Sdalcinl #undef __FUNCT__
2727fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
272871f87433Sdalcinl /*@
2729fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
273071f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
273171f87433Sdalcinl    Newton method.
273271f87433Sdalcinl 
273371f87433Sdalcinl    Collective on SNES
273471f87433Sdalcinl 
273571f87433Sdalcinl    Input Parameters:
273671f87433Sdalcinl +    snes - SNES context
273771f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
273871f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
273971f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
274071f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
274171f87433Sdalcinl              (0 <= gamma2 <= 1)
274271f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
274371f87433Sdalcinl .    alpha2 - power for safeguard
274471f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
274571f87433Sdalcinl 
274671f87433Sdalcinl    Note:
274771f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
274871f87433Sdalcinl 
274971f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
275071f87433Sdalcinl 
275171f87433Sdalcinl    Level: advanced
275271f87433Sdalcinl 
275371f87433Sdalcinl    Reference:
275471f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
275571f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
275671f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
275771f87433Sdalcinl 
275871f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
275971f87433Sdalcinl 
2760fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
276171f87433Sdalcinl @*/
2762fa9f3622SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
276371f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
276471f87433Sdalcinl {
2765fa9f3622SBarry Smith   SNESKSPEW *kctx;
276671f87433Sdalcinl   PetscFunctionBegin;
276771f87433Sdalcinl   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
2768fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
276971f87433Sdalcinl   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
277071f87433Sdalcinl 
277171f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
277271f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
277371f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
277471f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
277571f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
277671f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
277771f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
277871f87433Sdalcinl 
277971f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
278071f87433Sdalcinl     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
278171f87433Sdalcinl   }
278271f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
278371f87433Sdalcinl     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
278471f87433Sdalcinl   }
278571f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
278671f87433Sdalcinl     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
278771f87433Sdalcinl   }
278871f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
278971f87433Sdalcinl     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
279071f87433Sdalcinl   }
279171f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
279271f87433Sdalcinl     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
279371f87433Sdalcinl   }
279471f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
279571f87433Sdalcinl     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
279671f87433Sdalcinl   }
279771f87433Sdalcinl   PetscFunctionReturn(0);
279871f87433Sdalcinl }
279971f87433Sdalcinl 
280071f87433Sdalcinl #undef __FUNCT__
2801fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
280271f87433Sdalcinl /*@
2803fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
280471f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
280571f87433Sdalcinl    Newton method.
280671f87433Sdalcinl 
280771f87433Sdalcinl    Not Collective
280871f87433Sdalcinl 
280971f87433Sdalcinl    Input Parameters:
281071f87433Sdalcinl      snes - SNES context
281171f87433Sdalcinl 
281271f87433Sdalcinl    Output Parameters:
281371f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
281471f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
281571f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
281671f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
281771f87433Sdalcinl              (0 <= gamma2 <= 1)
281871f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
281971f87433Sdalcinl .    alpha2 - power for safeguard
282071f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
282171f87433Sdalcinl 
282271f87433Sdalcinl    Level: advanced
282371f87433Sdalcinl 
282471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
282571f87433Sdalcinl 
2826fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
282771f87433Sdalcinl @*/
2828fa9f3622SBarry Smith PetscErrorCode PETSCSNES_DLLEXPORT SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
282971f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
283071f87433Sdalcinl {
2831fa9f3622SBarry Smith   SNESKSPEW *kctx;
283271f87433Sdalcinl   PetscFunctionBegin;
283371f87433Sdalcinl   PetscValidHeaderSpecific(snes,SNES_COOKIE,1);
2834fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
283571f87433Sdalcinl   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
283671f87433Sdalcinl   if(version)   *version   = kctx->version;
283771f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
283871f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
283971f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
284071f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
284171f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
284271f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
284371f87433Sdalcinl   PetscFunctionReturn(0);
284471f87433Sdalcinl }
284571f87433Sdalcinl 
284671f87433Sdalcinl #undef __FUNCT__
2847fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
2848fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
284971f87433Sdalcinl {
285071f87433Sdalcinl   PetscErrorCode ierr;
2851fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
285271f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
285371f87433Sdalcinl 
285471f87433Sdalcinl   PetscFunctionBegin;
285571f87433Sdalcinl   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
285671f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
285771f87433Sdalcinl     rtol = kctx->rtol_0;
285871f87433Sdalcinl   } else {
285971f87433Sdalcinl     if (kctx->version == 1) {
286071f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
286171f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
286271f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
286371f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
286471f87433Sdalcinl     } else if (kctx->version == 2) {
286571f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
286671f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
286771f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
286871f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
286971f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
287071f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
287171f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
287271f87433Sdalcinl       stol = PetscMax(rtol,stol);
287371f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
287471f87433Sdalcinl       /* safeguard: avoid oversolving */
287571f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
287671f87433Sdalcinl       stol = PetscMax(rtol,stol);
287771f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
287871f87433Sdalcinl     } else SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
287971f87433Sdalcinl   }
288071f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
288171f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
288271f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
288371f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
288471f87433Sdalcinl   PetscFunctionReturn(0);
288571f87433Sdalcinl }
288671f87433Sdalcinl 
288771f87433Sdalcinl #undef __FUNCT__
2888fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
2889fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
289071f87433Sdalcinl {
289171f87433Sdalcinl   PetscErrorCode ierr;
2892fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
289371f87433Sdalcinl   PCSide         pcside;
289471f87433Sdalcinl   Vec            lres;
289571f87433Sdalcinl 
289671f87433Sdalcinl   PetscFunctionBegin;
289771f87433Sdalcinl   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
289871f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
289971f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
290071f87433Sdalcinl   if (kctx->version == 1) {
290171f87433Sdalcinl     ierr = KSPGetPreconditionerSide(ksp,&pcside);CHKERRQ(ierr);
290271f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
290371f87433Sdalcinl       /* KSP residual is true linear residual */
290471f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
290571f87433Sdalcinl     } else {
290671f87433Sdalcinl       /* KSP residual is preconditioned residual */
290771f87433Sdalcinl       /* compute true linear residual norm */
290871f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
290971f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
291071f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
291171f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
291271f87433Sdalcinl       ierr = VecDestroy(lres);CHKERRQ(ierr);
291371f87433Sdalcinl     }
291471f87433Sdalcinl   }
291571f87433Sdalcinl   PetscFunctionReturn(0);
291671f87433Sdalcinl }
291771f87433Sdalcinl 
291871f87433Sdalcinl #undef __FUNCT__
291971f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
292071f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
292171f87433Sdalcinl {
292271f87433Sdalcinl   PetscErrorCode ierr;
292371f87433Sdalcinl 
292471f87433Sdalcinl   PetscFunctionBegin;
2925fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
292671f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
2927fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
292871f87433Sdalcinl   PetscFunctionReturn(0);
292971f87433Sdalcinl }
2930