xref: /petsc/src/snes/interface/snes.c (revision 31823bd8f80a570acdc90e1e35eb7fd249fc8d01)
19b94acceSBarry Smith 
2c6db04a5SJed Brown #include <private/snesimpl.h>      /*I "petscsnes.h"  I*/
39b94acceSBarry Smith 
4ace3abfcSBarry Smith PetscBool  SNESRegisterAllCalled = PETSC_FALSE;
58ba1e511SMatthew Knepley PetscFList SNESList              = PETSC_NULL;
68ba1e511SMatthew Knepley 
78ba1e511SMatthew Knepley /* Logging support */
87087cfbeSBarry Smith PetscClassId  SNES_CLASSID;
9166c7f25SBarry Smith PetscLogEvent  SNES_Solve, SNES_LineSearch, SNES_FunctionEval, SNES_JacobianEval;
10a09944afSBarry Smith 
11a09944afSBarry Smith #undef __FUNCT__
12cab2e9ccSBarry Smith #define __FUNCT__ "SNESDMComputeJacobian"
13cab2e9ccSBarry Smith /*
14cab2e9ccSBarry Smith     Translates from a SNES call to a DM call in computing a Jacobian
15cab2e9ccSBarry Smith */
16cab2e9ccSBarry Smith PetscErrorCode SNESDMComputeJacobian(SNES snes,Vec X,Mat *J,Mat *B,MatStructure *flag,void *ptr)
17cab2e9ccSBarry Smith {
18cab2e9ccSBarry Smith   PetscErrorCode ierr;
19cab2e9ccSBarry Smith   DM             dm;
20cab2e9ccSBarry Smith 
21cab2e9ccSBarry Smith   PetscFunctionBegin;
22cab2e9ccSBarry Smith   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
23cab2e9ccSBarry Smith   ierr = DMComputeJacobian(dm,X,*J,*B,flag);CHKERRQ(ierr);
24cab2e9ccSBarry Smith   PetscFunctionReturn(0);
25cab2e9ccSBarry Smith }
26cab2e9ccSBarry Smith 
27cab2e9ccSBarry Smith #undef __FUNCT__
28e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged"
29e113a28aSBarry Smith /*@
30e113a28aSBarry Smith    SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged.
31e113a28aSBarry Smith 
323f9fe445SBarry Smith    Logically Collective on SNES
33e113a28aSBarry Smith 
34e113a28aSBarry Smith    Input Parameters:
35e113a28aSBarry Smith +  snes - iterative context obtained from SNESCreate()
36e113a28aSBarry Smith -  flg - PETSC_TRUE indicates you want the error generated
37e113a28aSBarry Smith 
38e113a28aSBarry Smith    Options database keys:
39e113a28aSBarry Smith .  -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false)
40e113a28aSBarry Smith 
41e113a28aSBarry Smith    Level: intermediate
42e113a28aSBarry Smith 
43e113a28aSBarry Smith    Notes:
44e113a28aSBarry Smith     Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve()
45e113a28aSBarry Smith     to determine if it has converged.
46e113a28aSBarry Smith 
47e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
48e113a28aSBarry Smith 
49e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
50e113a28aSBarry Smith @*/
517087cfbeSBarry Smith PetscErrorCode  SNESSetErrorIfNotConverged(SNES snes,PetscBool  flg)
52e113a28aSBarry Smith {
53e113a28aSBarry Smith   PetscFunctionBegin;
54e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
55acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flg,2);
56e113a28aSBarry Smith   snes->errorifnotconverged = flg;
57e113a28aSBarry Smith   PetscFunctionReturn(0);
58e113a28aSBarry Smith }
59e113a28aSBarry Smith 
60e113a28aSBarry Smith #undef __FUNCT__
61e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged"
62e113a28aSBarry Smith /*@
63e113a28aSBarry Smith    SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge?
64e113a28aSBarry Smith 
65e113a28aSBarry Smith    Not Collective
66e113a28aSBarry Smith 
67e113a28aSBarry Smith    Input Parameter:
68e113a28aSBarry Smith .  snes - iterative context obtained from SNESCreate()
69e113a28aSBarry Smith 
70e113a28aSBarry Smith    Output Parameter:
71e113a28aSBarry Smith .  flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE
72e113a28aSBarry Smith 
73e113a28aSBarry Smith    Level: intermediate
74e113a28aSBarry Smith 
75e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
76e113a28aSBarry Smith 
77e113a28aSBarry Smith .seealso:  SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
78e113a28aSBarry Smith @*/
797087cfbeSBarry Smith PetscErrorCode  SNESGetErrorIfNotConverged(SNES snes,PetscBool  *flag)
80e113a28aSBarry Smith {
81e113a28aSBarry Smith   PetscFunctionBegin;
82e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
83e113a28aSBarry Smith   PetscValidPointer(flag,2);
84e113a28aSBarry Smith   *flag = snes->errorifnotconverged;
85e113a28aSBarry Smith   PetscFunctionReturn(0);
86e113a28aSBarry Smith }
87e113a28aSBarry Smith 
88e113a28aSBarry Smith #undef __FUNCT__
894936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError"
90e725d27bSBarry Smith /*@
914936397dSBarry Smith    SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not
924936397dSBarry Smith      in the functions domain. For example, negative pressure.
934936397dSBarry Smith 
943f9fe445SBarry Smith    Logically Collective on SNES
954936397dSBarry Smith 
964936397dSBarry Smith    Input Parameters:
974936397dSBarry Smith .  SNES - the SNES context
984936397dSBarry Smith 
9928529972SSatish Balay    Level: advanced
1004936397dSBarry Smith 
1014936397dSBarry Smith .keywords: SNES, view
1024936397dSBarry Smith 
1034936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction()
1044936397dSBarry Smith @*/
1057087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionDomainError(SNES snes)
1064936397dSBarry Smith {
1074936397dSBarry Smith   PetscFunctionBegin;
1080700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1094936397dSBarry Smith   snes->domainerror = PETSC_TRUE;
1104936397dSBarry Smith   PetscFunctionReturn(0);
1114936397dSBarry Smith }
1124936397dSBarry Smith 
1134936397dSBarry Smith #undef __FUNCT__
1144a2ae208SSatish Balay #define __FUNCT__ "SNESView"
1157e2c5f70SBarry Smith /*@C
1169b94acceSBarry Smith    SNESView - Prints the SNES data structure.
1179b94acceSBarry Smith 
1184c49b128SBarry Smith    Collective on SNES
119fee21e36SBarry Smith 
120c7afd0dbSLois Curfman McInnes    Input Parameters:
121c7afd0dbSLois Curfman McInnes +  SNES - the SNES context
122c7afd0dbSLois Curfman McInnes -  viewer - visualization context
123c7afd0dbSLois Curfman McInnes 
1249b94acceSBarry Smith    Options Database Key:
125c8a8ba5cSLois Curfman McInnes .  -snes_view - Calls SNESView() at end of SNESSolve()
1269b94acceSBarry Smith 
1279b94acceSBarry Smith    Notes:
1289b94acceSBarry Smith    The available visualization contexts include
129b0a32e0cSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
130b0a32e0cSBarry Smith -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
131c8a8ba5cSLois Curfman McInnes          output where only the first processor opens
132c8a8ba5cSLois Curfman McInnes          the file.  All other processors send their
133c8a8ba5cSLois Curfman McInnes          data to the first processor to print.
1349b94acceSBarry Smith 
1353e081fefSLois Curfman McInnes    The user can open an alternative visualization context with
136b0a32e0cSBarry Smith    PetscViewerASCIIOpen() - output to a specified file.
1379b94acceSBarry Smith 
13836851e7fSLois Curfman McInnes    Level: beginner
13936851e7fSLois Curfman McInnes 
1409b94acceSBarry Smith .keywords: SNES, view
1419b94acceSBarry Smith 
142b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen()
1439b94acceSBarry Smith @*/
1447087cfbeSBarry Smith PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
1459b94acceSBarry Smith {
146fa9f3622SBarry Smith   SNESKSPEW           *kctx;
147dfbe8321SBarry Smith   PetscErrorCode      ierr;
14894b7f48cSBarry Smith   KSP                 ksp;
149ace3abfcSBarry Smith   PetscBool           iascii,isstring;
1509b94acceSBarry Smith 
1513a40ed3dSBarry Smith   PetscFunctionBegin;
1520700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1533050cee2SBarry Smith   if (!viewer) {
1547adad957SLisandro Dalcin     ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
1553050cee2SBarry Smith   }
1560700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
157c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,viewer,2);
15874679c65SBarry Smith 
1592692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1602692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
16132077d6dSBarry Smith   if (iascii) {
162317d6ea6SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr);
163e7788613SBarry Smith     if (snes->ops->view) {
164b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
165e7788613SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
166b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1670ef38995SBarry Smith     }
16877431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr);
169a83599f4SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%G, absolute=%G, solution=%G\n",
17070441072SBarry Smith                  snes->rtol,snes->abstol,snes->xtol);CHKERRQ(ierr);
17177431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr);
17277431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr);
1739b94acceSBarry Smith     if (snes->ksp_ewconv) {
174fa9f3622SBarry Smith       kctx = (SNESKSPEW *)snes->kspconvctx;
1759b94acceSBarry Smith       if (kctx) {
17677431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr);
177a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr);
178a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr);
1799b94acceSBarry Smith       }
1809b94acceSBarry Smith     }
181eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
182eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");CHKERRQ(ierr);
183eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
184eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr);
185eb1f6c34SBarry Smith     }
186eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
187eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");CHKERRQ(ierr);
188eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
189eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D Newton iterations\n",snes->lagjacobian);CHKERRQ(ierr);
190eb1f6c34SBarry Smith     }
1910f5bd95cSBarry Smith   } else if (isstring) {
192317d6ea6SBarry Smith     const char *type;
193454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
194b0a32e0cSBarry Smith     ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr);
19519bcc07fSBarry Smith   }
19694b7f48cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
197b0a32e0cSBarry Smith   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
19894b7f48cSBarry Smith   ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
199b0a32e0cSBarry Smith   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2003a40ed3dSBarry Smith   PetscFunctionReturn(0);
2019b94acceSBarry Smith }
2029b94acceSBarry Smith 
20376b2cf59SMatthew Knepley /*
20476b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
20576b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
20676b2cf59SMatthew Knepley */
20776b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
208a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
2096849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
21076b2cf59SMatthew Knepley 
211e74ef692SMatthew Knepley #undef __FUNCT__
212e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker"
213ac226902SBarry Smith /*@C
21476b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
21576b2cf59SMatthew Knepley 
21676b2cf59SMatthew Knepley   Not Collective
21776b2cf59SMatthew Knepley 
21876b2cf59SMatthew Knepley   Input Parameter:
21976b2cf59SMatthew Knepley . snescheck - function that checks for options
22076b2cf59SMatthew Knepley 
22176b2cf59SMatthew Knepley   Level: developer
22276b2cf59SMatthew Knepley 
22376b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
22476b2cf59SMatthew Knepley @*/
2257087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
22676b2cf59SMatthew Knepley {
22776b2cf59SMatthew Knepley   PetscFunctionBegin;
22876b2cf59SMatthew Knepley   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
229e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
23076b2cf59SMatthew Knepley   }
23176b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
23276b2cf59SMatthew Knepley   PetscFunctionReturn(0);
23376b2cf59SMatthew Knepley }
23476b2cf59SMatthew Knepley 
2357087cfbeSBarry Smith extern PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
236aa3661deSLisandro Dalcin 
237aa3661deSLisandro Dalcin #undef __FUNCT__
238aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private"
239ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool  hasOperator, PetscInt version)
240aa3661deSLisandro Dalcin {
241aa3661deSLisandro Dalcin   Mat            J;
242aa3661deSLisandro Dalcin   KSP            ksp;
243aa3661deSLisandro Dalcin   PC             pc;
244ace3abfcSBarry Smith   PetscBool      match;
245aa3661deSLisandro Dalcin   PetscErrorCode ierr;
246aa3661deSLisandro Dalcin 
247aa3661deSLisandro Dalcin   PetscFunctionBegin;
2480700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
249aa3661deSLisandro Dalcin 
25098613b67SLisandro Dalcin   if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
25198613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
25298613b67SLisandro Dalcin     ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr);
25398613b67SLisandro Dalcin   }
25498613b67SLisandro Dalcin 
255aa3661deSLisandro Dalcin   if (version == 1) {
256aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
25798613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
2589c6ac3b3SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
259aa3661deSLisandro Dalcin   } else if (version == 2) {
260e32f2f54SBarry Smith     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
261ce63c4c1SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL_LONG_DOUBLE)
262aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
263aa3661deSLisandro Dalcin #else
264e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
265aa3661deSLisandro Dalcin #endif
266aa3661deSLisandro Dalcin   } else {
267e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
268aa3661deSLisandro Dalcin   }
269aa3661deSLisandro Dalcin 
270aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
271d3462f78SMatthew Knepley   if (hasOperator) {
272aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
273aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
274aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
275aa3661deSLisandro Dalcin   } else {
276aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
277aa3661deSLisandro Dalcin        provided preconditioner matrix with the default matrix free version. */
278aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);CHKERRQ(ierr);
279aa3661deSLisandro Dalcin     /* Force no preconditioner */
280aa3661deSLisandro Dalcin     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
281aa3661deSLisandro Dalcin     ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
282aa3661deSLisandro Dalcin     ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
283aa3661deSLisandro Dalcin     if (!match) {
284aa3661deSLisandro Dalcin       ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
285aa3661deSLisandro Dalcin       ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
286aa3661deSLisandro Dalcin     }
287aa3661deSLisandro Dalcin   }
2886bf464f9SBarry Smith   ierr = MatDestroy(&J);CHKERRQ(ierr);
289aa3661deSLisandro Dalcin 
290aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
291aa3661deSLisandro Dalcin }
292aa3661deSLisandro Dalcin 
2934a2ae208SSatish Balay #undef __FUNCT__
2944a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions"
2959b94acceSBarry Smith /*@
29694b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
2979b94acceSBarry Smith 
298c7afd0dbSLois Curfman McInnes    Collective on SNES
299c7afd0dbSLois Curfman McInnes 
3009b94acceSBarry Smith    Input Parameter:
3019b94acceSBarry Smith .  snes - the SNES context
3029b94acceSBarry Smith 
30336851e7fSLois Curfman McInnes    Options Database Keys:
3046831982aSBarry Smith +  -snes_type <type> - ls, tr, umls, umtr, test
30582738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
30682738288SBarry Smith                 of the change in the solution between steps
30770441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
308b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
309b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
310b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
31150ffb88aSMatthew Knepley .  -snes_max_fail <max_fail> - maximum number of failures
312ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
313a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
314e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
315b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
3162492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
31782738288SBarry Smith                                solver; hence iterations will continue until max_it
3181fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
31982738288SBarry Smith                                of convergence test
320e8105e01SRichard Katz .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
321e8105e01SRichard Katz                                        filename given prints to stdout
322a6570f20SBarry Smith .  -snes_monitor_solution - plots solution at each iteration
323a6570f20SBarry Smith .  -snes_monitor_residual - plots residual (not its norm) at each iteration
324a6570f20SBarry Smith .  -snes_monitor_solution_update - plots update to solution at each iteration
325a6570f20SBarry Smith .  -snes_monitor_draw - plots residual norm at each iteration
326e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
3275968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
328fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
32982738288SBarry Smith 
33082738288SBarry Smith     Options Database for Eisenstat-Walker method:
331fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
3324b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
33336851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
33436851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
33536851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
33636851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
33736851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
33836851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
33982738288SBarry Smith 
34011ca99fdSLois Curfman McInnes    Notes:
34111ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
3420598bfebSBarry Smith    the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>.
34383e2fdc7SBarry Smith 
34436851e7fSLois Curfman McInnes    Level: beginner
34536851e7fSLois Curfman McInnes 
3469b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
3479b94acceSBarry Smith 
34869ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
3499b94acceSBarry Smith @*/
3507087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
3519b94acceSBarry Smith {
352ace3abfcSBarry Smith   PetscBool               flg,mf,mf_operator;
353efd51863SBarry Smith   PetscInt                i,indx,lag,mf_version,grids;
354aa3661deSLisandro Dalcin   MatStructure            matflag;
35585385478SLisandro Dalcin   const char              *deft = SNESLS;
35685385478SLisandro Dalcin   const char              *convtests[] = {"default","skip"};
35785385478SLisandro Dalcin   SNESKSPEW               *kctx = NULL;
358e8105e01SRichard Katz   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
359649052a6SBarry Smith   PetscViewer             monviewer;
36085385478SLisandro Dalcin   PetscErrorCode          ierr;
3619b94acceSBarry Smith 
3623a40ed3dSBarry Smith   PetscFunctionBegin;
3630700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
364ca161407SBarry Smith 
365186905e3SBarry Smith   if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
366cce0b1b2SLisandro Dalcin   ierr = PetscOptionsBegin(((PetscObject)snes)->comm,((PetscObject)snes)->prefix,"Nonlinear solver (SNES) options","SNES");CHKERRQ(ierr);
3677adad957SLisandro Dalcin     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
368b0a32e0cSBarry Smith     ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
369d64ed03dSBarry Smith     if (flg) {
370186905e3SBarry Smith       ierr = SNESSetType(snes,type);CHKERRQ(ierr);
3717adad957SLisandro Dalcin     } else if (!((PetscObject)snes)->type_name) {
372186905e3SBarry Smith       ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
373d64ed03dSBarry Smith     }
37490d69ab7SBarry Smith     /* not used here, but called so will go into help messaage */
375909c8a9fSBarry Smith     ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr);
37693c39befSBarry Smith 
37757034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->xtol,&snes->xtol,0);CHKERRQ(ierr);
37857034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr);
379186905e3SBarry Smith 
38057034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr);
381b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr);
382b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr);
38350ffb88aSMatthew Knepley     ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr);
384ddf469c8SBarry Smith     ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr);
385acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr);
38685385478SLisandro Dalcin 
387a8054027SBarry Smith     ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
388a8054027SBarry Smith     if (flg) {
389a8054027SBarry Smith       ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
390a8054027SBarry Smith     }
391e35cf81dSBarry Smith     ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
392e35cf81dSBarry Smith     if (flg) {
393e35cf81dSBarry Smith       ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
394e35cf81dSBarry Smith     }
395efd51863SBarry Smith     ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
396efd51863SBarry Smith     if (flg) {
397efd51863SBarry Smith       ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
398efd51863SBarry Smith     }
399a8054027SBarry Smith 
40085385478SLisandro Dalcin     ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
40185385478SLisandro Dalcin     if (flg) {
40285385478SLisandro Dalcin       switch (indx) {
4037f7931b9SBarry Smith       case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break;
4047f7931b9SBarry Smith       case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);    break;
40585385478SLisandro Dalcin       }
40685385478SLisandro Dalcin     }
40785385478SLisandro Dalcin 
408acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr);
409186905e3SBarry Smith 
41085385478SLisandro Dalcin     kctx = (SNESKSPEW *)snes->kspconvctx;
41185385478SLisandro Dalcin 
412acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr);
413186905e3SBarry Smith 
414fa9f3622SBarry Smith     ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr);
415fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr);
416fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr);
417fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr);
418fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr);
419fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr);
420fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr);
421186905e3SBarry Smith 
42290d69ab7SBarry Smith     flg  = PETSC_FALSE;
423acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
424a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
425eabae89aSBarry Smith 
426a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
427e8105e01SRichard Katz     if (flg) {
428649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
429649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
430e8105e01SRichard Katz     }
431eabae89aSBarry Smith 
432b271bb04SBarry Smith     ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
433b271bb04SBarry Smith     if (flg) {
434b271bb04SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr);
435b271bb04SBarry Smith     }
436b271bb04SBarry Smith 
437a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
438eabae89aSBarry Smith     if (flg) {
439649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
440f1bef1bcSMatthew Knepley       ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr);
441e8105e01SRichard Katz     }
442eabae89aSBarry Smith 
443a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
444eabae89aSBarry Smith     if (flg) {
445649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
446649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
447eabae89aSBarry Smith     }
448eabae89aSBarry Smith 
44990d69ab7SBarry Smith     flg  = PETSC_FALSE;
450acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
451a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
45290d69ab7SBarry Smith     flg  = PETSC_FALSE;
453acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
454a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
45590d69ab7SBarry Smith     flg  = PETSC_FALSE;
456acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
457a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
45890d69ab7SBarry Smith     flg  = PETSC_FALSE;
459acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
460a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
46190d69ab7SBarry Smith     flg  = PETSC_FALSE;
462acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
463b271bb04SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
464e24b481bSBarry Smith 
46590d69ab7SBarry Smith     flg  = PETSC_FALSE;
466acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
4674b27c08aSLois Curfman McInnes     if (flg) {
468186905e3SBarry Smith       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);CHKERRQ(ierr);
469ae15b995SBarry Smith       ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
4709b94acceSBarry Smith     }
471639f9d9dSBarry Smith 
472aa3661deSLisandro Dalcin     mf = mf_operator = PETSC_FALSE;
473aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
474acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr);
475aa3661deSLisandro Dalcin     if (flg && mf_operator) mf = PETSC_TRUE;
476aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
477acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr);
478aa3661deSLisandro Dalcin     if (!flg && mf_operator) mf = PETSC_TRUE;
479aa3661deSLisandro Dalcin     mf_version = 1;
480aa3661deSLisandro Dalcin     ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr);
481aa3661deSLisandro Dalcin 
48276b2cf59SMatthew Knepley     for(i = 0; i < numberofsetfromoptions; i++) {
48376b2cf59SMatthew Knepley       ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
48476b2cf59SMatthew Knepley     }
48576b2cf59SMatthew Knepley 
486e7788613SBarry Smith     if (snes->ops->setfromoptions) {
487e7788613SBarry Smith       ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr);
488639f9d9dSBarry Smith     }
4895d973c19SBarry Smith 
4905d973c19SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
4915d973c19SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr);
492b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
4934bbc92c1SBarry Smith 
494aa3661deSLisandro Dalcin   if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); }
4951cee3971SBarry Smith 
4961cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
497aa3661deSLisandro Dalcin   ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
498aa3661deSLisandro Dalcin   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr);
49985385478SLisandro Dalcin   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
50093993e2dSLois Curfman McInnes 
5013a40ed3dSBarry Smith   PetscFunctionReturn(0);
5029b94acceSBarry Smith }
5039b94acceSBarry Smith 
504d25893d9SBarry Smith #undef __FUNCT__
505d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext"
506d25893d9SBarry Smith /*@
507d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
508d25893d9SBarry Smith    the nonlinear solvers.
509d25893d9SBarry Smith 
510d25893d9SBarry Smith    Logically Collective on SNES
511d25893d9SBarry Smith 
512d25893d9SBarry Smith    Input Parameters:
513d25893d9SBarry Smith +  snes - the SNES context
514d25893d9SBarry Smith .  compute - function to compute the context
515d25893d9SBarry Smith -  destroy - function to destroy the context
516d25893d9SBarry Smith 
517d25893d9SBarry Smith    Level: intermediate
518d25893d9SBarry Smith 
519d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
520d25893d9SBarry Smith 
521d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
522d25893d9SBarry Smith @*/
523d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
524d25893d9SBarry Smith {
525d25893d9SBarry Smith   PetscFunctionBegin;
526d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
527d25893d9SBarry Smith   snes->ops->usercompute = compute;
528d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
529d25893d9SBarry Smith   PetscFunctionReturn(0);
530d25893d9SBarry Smith }
531a847f771SSatish Balay 
5324a2ae208SSatish Balay #undef __FUNCT__
5334a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
534b07ff414SBarry Smith /*@
5359b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
5369b94acceSBarry Smith    the nonlinear solvers.
5379b94acceSBarry Smith 
5383f9fe445SBarry Smith    Logically Collective on SNES
539fee21e36SBarry Smith 
540c7afd0dbSLois Curfman McInnes    Input Parameters:
541c7afd0dbSLois Curfman McInnes +  snes - the SNES context
542c7afd0dbSLois Curfman McInnes -  usrP - optional user context
543c7afd0dbSLois Curfman McInnes 
54436851e7fSLois Curfman McInnes    Level: intermediate
54536851e7fSLois Curfman McInnes 
5469b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
5479b94acceSBarry Smith 
548d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext()
5499b94acceSBarry Smith @*/
5507087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
5519b94acceSBarry Smith {
5521b2093e4SBarry Smith   PetscErrorCode ierr;
553b07ff414SBarry Smith   KSP            ksp;
5541b2093e4SBarry Smith 
5553a40ed3dSBarry Smith   PetscFunctionBegin;
5560700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
557b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
558b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
5599b94acceSBarry Smith   snes->user = usrP;
5603a40ed3dSBarry Smith   PetscFunctionReturn(0);
5619b94acceSBarry Smith }
56274679c65SBarry Smith 
5634a2ae208SSatish Balay #undef __FUNCT__
5644a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
565b07ff414SBarry Smith /*@
5669b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
5679b94acceSBarry Smith    nonlinear solvers.
5689b94acceSBarry Smith 
569c7afd0dbSLois Curfman McInnes    Not Collective
570c7afd0dbSLois Curfman McInnes 
5719b94acceSBarry Smith    Input Parameter:
5729b94acceSBarry Smith .  snes - SNES context
5739b94acceSBarry Smith 
5749b94acceSBarry Smith    Output Parameter:
5759b94acceSBarry Smith .  usrP - user context
5769b94acceSBarry Smith 
57736851e7fSLois Curfman McInnes    Level: intermediate
57836851e7fSLois Curfman McInnes 
5799b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
5809b94acceSBarry Smith 
5819b94acceSBarry Smith .seealso: SNESSetApplicationContext()
5829b94acceSBarry Smith @*/
5837087cfbeSBarry Smith PetscErrorCode  SNESGetApplicationContext(SNES snes,void **usrP)
5849b94acceSBarry Smith {
5853a40ed3dSBarry Smith   PetscFunctionBegin;
5860700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5879b94acceSBarry Smith   *usrP = snes->user;
5883a40ed3dSBarry Smith   PetscFunctionReturn(0);
5899b94acceSBarry Smith }
59074679c65SBarry Smith 
5914a2ae208SSatish Balay #undef __FUNCT__
5924a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
5939b94acceSBarry Smith /*@
594c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
595c8228a4eSBarry Smith    at this time.
5969b94acceSBarry Smith 
597c7afd0dbSLois Curfman McInnes    Not Collective
598c7afd0dbSLois Curfman McInnes 
5999b94acceSBarry Smith    Input Parameter:
6009b94acceSBarry Smith .  snes - SNES context
6019b94acceSBarry Smith 
6029b94acceSBarry Smith    Output Parameter:
6039b94acceSBarry Smith .  iter - iteration number
6049b94acceSBarry Smith 
605c8228a4eSBarry Smith    Notes:
606c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
607c8228a4eSBarry Smith 
608c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
60908405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
61008405cd6SLois Curfman McInnes .vb
61108405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
61208405cd6SLois Curfman McInnes       if (!(it % 2)) {
61308405cd6SLois Curfman McInnes         [compute Jacobian here]
61408405cd6SLois Curfman McInnes       }
61508405cd6SLois Curfman McInnes .ve
616c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
61708405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
618c8228a4eSBarry Smith 
61936851e7fSLois Curfman McInnes    Level: intermediate
62036851e7fSLois Curfman McInnes 
6212b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
6222b668275SBarry Smith 
623b850b91aSLisandro Dalcin .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
6249b94acceSBarry Smith @*/
6257087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
6269b94acceSBarry Smith {
6273a40ed3dSBarry Smith   PetscFunctionBegin;
6280700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
6294482741eSBarry Smith   PetscValidIntPointer(iter,2);
6309b94acceSBarry Smith   *iter = snes->iter;
6313a40ed3dSBarry Smith   PetscFunctionReturn(0);
6329b94acceSBarry Smith }
63374679c65SBarry Smith 
6344a2ae208SSatish Balay #undef __FUNCT__
6354a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm"
6369b94acceSBarry Smith /*@
6379b94acceSBarry Smith    SNESGetFunctionNorm - Gets the norm of the current function that was set
6389b94acceSBarry Smith    with SNESSSetFunction().
6399b94acceSBarry Smith 
640c7afd0dbSLois Curfman McInnes    Collective on SNES
641c7afd0dbSLois Curfman McInnes 
6429b94acceSBarry Smith    Input Parameter:
6439b94acceSBarry Smith .  snes - SNES context
6449b94acceSBarry Smith 
6459b94acceSBarry Smith    Output Parameter:
6469b94acceSBarry Smith .  fnorm - 2-norm of function
6479b94acceSBarry Smith 
64836851e7fSLois Curfman McInnes    Level: intermediate
64936851e7fSLois Curfman McInnes 
6509b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm
651a86d99e1SLois Curfman McInnes 
652b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
6539b94acceSBarry Smith @*/
6547087cfbeSBarry Smith PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
6559b94acceSBarry Smith {
6563a40ed3dSBarry Smith   PetscFunctionBegin;
6570700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
6584482741eSBarry Smith   PetscValidScalarPointer(fnorm,2);
6599b94acceSBarry Smith   *fnorm = snes->norm;
6603a40ed3dSBarry Smith   PetscFunctionReturn(0);
6619b94acceSBarry Smith }
66274679c65SBarry Smith 
6634a2ae208SSatish Balay #undef __FUNCT__
664b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
6659b94acceSBarry Smith /*@
666b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
6679b94acceSBarry Smith    attempted by the nonlinear solver.
6689b94acceSBarry Smith 
669c7afd0dbSLois Curfman McInnes    Not Collective
670c7afd0dbSLois Curfman McInnes 
6719b94acceSBarry Smith    Input Parameter:
6729b94acceSBarry Smith .  snes - SNES context
6739b94acceSBarry Smith 
6749b94acceSBarry Smith    Output Parameter:
6759b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
6769b94acceSBarry Smith 
677c96a6f78SLois Curfman McInnes    Notes:
678c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
679c96a6f78SLois Curfman McInnes 
68036851e7fSLois Curfman McInnes    Level: intermediate
68136851e7fSLois Curfman McInnes 
6829b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
68358ebbce7SBarry Smith 
684e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
68558ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
6869b94acceSBarry Smith @*/
6877087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
6889b94acceSBarry Smith {
6893a40ed3dSBarry Smith   PetscFunctionBegin;
6900700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
6914482741eSBarry Smith   PetscValidIntPointer(nfails,2);
69250ffb88aSMatthew Knepley   *nfails = snes->numFailures;
69350ffb88aSMatthew Knepley   PetscFunctionReturn(0);
69450ffb88aSMatthew Knepley }
69550ffb88aSMatthew Knepley 
69650ffb88aSMatthew Knepley #undef __FUNCT__
697b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
69850ffb88aSMatthew Knepley /*@
699b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
70050ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
70150ffb88aSMatthew Knepley 
70250ffb88aSMatthew Knepley    Not Collective
70350ffb88aSMatthew Knepley 
70450ffb88aSMatthew Knepley    Input Parameters:
70550ffb88aSMatthew Knepley +  snes     - SNES context
70650ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
70750ffb88aSMatthew Knepley 
70850ffb88aSMatthew Knepley    Level: intermediate
70950ffb88aSMatthew Knepley 
71050ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
71158ebbce7SBarry Smith 
712e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
71358ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
71450ffb88aSMatthew Knepley @*/
7157087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
71650ffb88aSMatthew Knepley {
71750ffb88aSMatthew Knepley   PetscFunctionBegin;
7180700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
71950ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
72050ffb88aSMatthew Knepley   PetscFunctionReturn(0);
72150ffb88aSMatthew Knepley }
72250ffb88aSMatthew Knepley 
72350ffb88aSMatthew Knepley #undef __FUNCT__
724b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
72550ffb88aSMatthew Knepley /*@
726b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
72750ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
72850ffb88aSMatthew Knepley 
72950ffb88aSMatthew Knepley    Not Collective
73050ffb88aSMatthew Knepley 
73150ffb88aSMatthew Knepley    Input Parameter:
73250ffb88aSMatthew Knepley .  snes     - SNES context
73350ffb88aSMatthew Knepley 
73450ffb88aSMatthew Knepley    Output Parameter:
73550ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
73650ffb88aSMatthew Knepley 
73750ffb88aSMatthew Knepley    Level: intermediate
73850ffb88aSMatthew Knepley 
73950ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
74058ebbce7SBarry Smith 
741e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
74258ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
74358ebbce7SBarry Smith 
74450ffb88aSMatthew Knepley @*/
7457087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
74650ffb88aSMatthew Knepley {
74750ffb88aSMatthew Knepley   PetscFunctionBegin;
7480700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7494482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
75050ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
7513a40ed3dSBarry Smith   PetscFunctionReturn(0);
7529b94acceSBarry Smith }
753a847f771SSatish Balay 
7544a2ae208SSatish Balay #undef __FUNCT__
7552541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
7562541af92SBarry Smith /*@
7572541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
7582541af92SBarry Smith      done by SNES.
7592541af92SBarry Smith 
7602541af92SBarry Smith    Not Collective
7612541af92SBarry Smith 
7622541af92SBarry Smith    Input Parameter:
7632541af92SBarry Smith .  snes     - SNES context
7642541af92SBarry Smith 
7652541af92SBarry Smith    Output Parameter:
7662541af92SBarry Smith .  nfuncs - number of evaluations
7672541af92SBarry Smith 
7682541af92SBarry Smith    Level: intermediate
7692541af92SBarry Smith 
7702541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
77158ebbce7SBarry Smith 
772e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
7732541af92SBarry Smith @*/
7747087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
7752541af92SBarry Smith {
7762541af92SBarry Smith   PetscFunctionBegin;
7770700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7782541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
7792541af92SBarry Smith   *nfuncs = snes->nfuncs;
7802541af92SBarry Smith   PetscFunctionReturn(0);
7812541af92SBarry Smith }
7822541af92SBarry Smith 
7832541af92SBarry Smith #undef __FUNCT__
7843d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
7853d4c4710SBarry Smith /*@
7863d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
7873d4c4710SBarry Smith    linear solvers.
7883d4c4710SBarry Smith 
7893d4c4710SBarry Smith    Not Collective
7903d4c4710SBarry Smith 
7913d4c4710SBarry Smith    Input Parameter:
7923d4c4710SBarry Smith .  snes - SNES context
7933d4c4710SBarry Smith 
7943d4c4710SBarry Smith    Output Parameter:
7953d4c4710SBarry Smith .  nfails - number of failed solves
7963d4c4710SBarry Smith 
7973d4c4710SBarry Smith    Notes:
7983d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
7993d4c4710SBarry Smith 
8003d4c4710SBarry Smith    Level: intermediate
8013d4c4710SBarry Smith 
8023d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
80358ebbce7SBarry Smith 
804e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
8053d4c4710SBarry Smith @*/
8067087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
8073d4c4710SBarry Smith {
8083d4c4710SBarry Smith   PetscFunctionBegin;
8090700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8103d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
8113d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
8123d4c4710SBarry Smith   PetscFunctionReturn(0);
8133d4c4710SBarry Smith }
8143d4c4710SBarry Smith 
8153d4c4710SBarry Smith #undef __FUNCT__
8163d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
8173d4c4710SBarry Smith /*@
8183d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
8193d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
8203d4c4710SBarry Smith 
8213f9fe445SBarry Smith    Logically Collective on SNES
8223d4c4710SBarry Smith 
8233d4c4710SBarry Smith    Input Parameters:
8243d4c4710SBarry Smith +  snes     - SNES context
8253d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
8263d4c4710SBarry Smith 
8273d4c4710SBarry Smith    Level: intermediate
8283d4c4710SBarry Smith 
829a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
8303d4c4710SBarry Smith 
8313d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
8323d4c4710SBarry Smith 
83358ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
8343d4c4710SBarry Smith @*/
8357087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
8363d4c4710SBarry Smith {
8373d4c4710SBarry Smith   PetscFunctionBegin;
8380700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
839c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
8403d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
8413d4c4710SBarry Smith   PetscFunctionReturn(0);
8423d4c4710SBarry Smith }
8433d4c4710SBarry Smith 
8443d4c4710SBarry Smith #undef __FUNCT__
8453d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
8463d4c4710SBarry Smith /*@
8473d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
8483d4c4710SBarry Smith      are allowed before SNES terminates
8493d4c4710SBarry Smith 
8503d4c4710SBarry Smith    Not Collective
8513d4c4710SBarry Smith 
8523d4c4710SBarry Smith    Input Parameter:
8533d4c4710SBarry Smith .  snes     - SNES context
8543d4c4710SBarry Smith 
8553d4c4710SBarry Smith    Output Parameter:
8563d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
8573d4c4710SBarry Smith 
8583d4c4710SBarry Smith    Level: intermediate
8593d4c4710SBarry Smith 
8603d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
8613d4c4710SBarry Smith 
8623d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
8633d4c4710SBarry Smith 
864e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
8653d4c4710SBarry Smith @*/
8667087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
8673d4c4710SBarry Smith {
8683d4c4710SBarry Smith   PetscFunctionBegin;
8690700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8703d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
8713d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
8723d4c4710SBarry Smith   PetscFunctionReturn(0);
8733d4c4710SBarry Smith }
8743d4c4710SBarry Smith 
8753d4c4710SBarry Smith #undef __FUNCT__
876b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
877c96a6f78SLois Curfman McInnes /*@
878b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
879c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
880c96a6f78SLois Curfman McInnes 
881c7afd0dbSLois Curfman McInnes    Not Collective
882c7afd0dbSLois Curfman McInnes 
883c96a6f78SLois Curfman McInnes    Input Parameter:
884c96a6f78SLois Curfman McInnes .  snes - SNES context
885c96a6f78SLois Curfman McInnes 
886c96a6f78SLois Curfman McInnes    Output Parameter:
887c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
888c96a6f78SLois Curfman McInnes 
889c96a6f78SLois Curfman McInnes    Notes:
890c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
891c96a6f78SLois Curfman McInnes 
89236851e7fSLois Curfman McInnes    Level: intermediate
89336851e7fSLois Curfman McInnes 
894c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
8952b668275SBarry Smith 
8968c7482ecSBarry Smith .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
897c96a6f78SLois Curfman McInnes @*/
8987087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
899c96a6f78SLois Curfman McInnes {
9003a40ed3dSBarry Smith   PetscFunctionBegin;
9010700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9024482741eSBarry Smith   PetscValidIntPointer(lits,2);
903c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
9043a40ed3dSBarry Smith   PetscFunctionReturn(0);
905c96a6f78SLois Curfman McInnes }
906c96a6f78SLois Curfman McInnes 
9074a2ae208SSatish Balay #undef __FUNCT__
90894b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP"
90952baeb72SSatish Balay /*@
91094b7f48cSBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
9119b94acceSBarry Smith 
91294b7f48cSBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
913c7afd0dbSLois Curfman McInnes 
9149b94acceSBarry Smith    Input Parameter:
9159b94acceSBarry Smith .  snes - the SNES context
9169b94acceSBarry Smith 
9179b94acceSBarry Smith    Output Parameter:
91894b7f48cSBarry Smith .  ksp - the KSP context
9199b94acceSBarry Smith 
9209b94acceSBarry Smith    Notes:
92194b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
9229b94acceSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
9232999313aSBarry Smith    PC contexts as well.
9249b94acceSBarry Smith 
92536851e7fSLois Curfman McInnes    Level: beginner
92636851e7fSLois Curfman McInnes 
92794b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
9289b94acceSBarry Smith 
9292999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
9309b94acceSBarry Smith @*/
9317087cfbeSBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
9329b94acceSBarry Smith {
9331cee3971SBarry Smith   PetscErrorCode ierr;
9341cee3971SBarry Smith 
9353a40ed3dSBarry Smith   PetscFunctionBegin;
9360700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9374482741eSBarry Smith   PetscValidPointer(ksp,2);
9381cee3971SBarry Smith 
9391cee3971SBarry Smith   if (!snes->ksp) {
9401cee3971SBarry Smith     ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr);
9411cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
9421cee3971SBarry Smith     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
9431cee3971SBarry Smith   }
94494b7f48cSBarry Smith   *ksp = snes->ksp;
9453a40ed3dSBarry Smith   PetscFunctionReturn(0);
9469b94acceSBarry Smith }
94782bf6240SBarry Smith 
9484a2ae208SSatish Balay #undef __FUNCT__
9492999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
9502999313aSBarry Smith /*@
9512999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
9522999313aSBarry Smith 
9532999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
9542999313aSBarry Smith 
9552999313aSBarry Smith    Input Parameters:
9562999313aSBarry Smith +  snes - the SNES context
9572999313aSBarry Smith -  ksp - the KSP context
9582999313aSBarry Smith 
9592999313aSBarry Smith    Notes:
9602999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
9612999313aSBarry Smith    so this routine is rarely needed.
9622999313aSBarry Smith 
9632999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
9642999313aSBarry Smith    decreased by one.
9652999313aSBarry Smith 
9662999313aSBarry Smith    Level: developer
9672999313aSBarry Smith 
9682999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
9692999313aSBarry Smith 
9702999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
9712999313aSBarry Smith @*/
9727087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
9732999313aSBarry Smith {
9742999313aSBarry Smith   PetscErrorCode ierr;
9752999313aSBarry Smith 
9762999313aSBarry Smith   PetscFunctionBegin;
9770700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9780700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
9792999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
9807dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
981906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
9822999313aSBarry Smith   snes->ksp = ksp;
9832999313aSBarry Smith   PetscFunctionReturn(0);
9842999313aSBarry Smith }
9852999313aSBarry Smith 
9867adad957SLisandro Dalcin #if 0
9872999313aSBarry Smith #undef __FUNCT__
9884a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc"
9896849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
990e24b481bSBarry Smith {
991e24b481bSBarry Smith   PetscFunctionBegin;
992e24b481bSBarry Smith   PetscFunctionReturn(0);
993e24b481bSBarry Smith }
9947adad957SLisandro Dalcin #endif
995e24b481bSBarry Smith 
9969b94acceSBarry Smith /* -----------------------------------------------------------*/
9974a2ae208SSatish Balay #undef __FUNCT__
9984a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
99952baeb72SSatish Balay /*@
10009b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
10019b94acceSBarry Smith 
1002c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1003c7afd0dbSLois Curfman McInnes 
1004c7afd0dbSLois Curfman McInnes    Input Parameters:
1005906ed7ccSBarry Smith .  comm - MPI communicator
10069b94acceSBarry Smith 
10079b94acceSBarry Smith    Output Parameter:
10089b94acceSBarry Smith .  outsnes - the new SNES context
10099b94acceSBarry Smith 
1010c7afd0dbSLois Curfman McInnes    Options Database Keys:
1011c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1012c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1013c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1014c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1015c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1016c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1017c1f60f51SBarry Smith 
101836851e7fSLois Curfman McInnes    Level: beginner
101936851e7fSLois Curfman McInnes 
10209b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
10219b94acceSBarry Smith 
1022a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1023a8054027SBarry Smith 
10249b94acceSBarry Smith @*/
10257087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
10269b94acceSBarry Smith {
1027dfbe8321SBarry Smith   PetscErrorCode      ierr;
10289b94acceSBarry Smith   SNES                snes;
1029fa9f3622SBarry Smith   SNESKSPEW           *kctx;
103037fcc0dbSBarry Smith 
10313a40ed3dSBarry Smith   PetscFunctionBegin;
1032ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
10338ba1e511SMatthew Knepley   *outsnes = PETSC_NULL;
10348ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
10358ba1e511SMatthew Knepley   ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr);
10368ba1e511SMatthew Knepley #endif
10378ba1e511SMatthew Knepley 
10380700a824SBarry Smith   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
10397adad957SLisandro Dalcin 
104085385478SLisandro Dalcin   snes->ops->converged    = SNESDefaultConverged;
10419b94acceSBarry Smith   snes->max_its           = 50;
10429750a799SBarry Smith   snes->max_funcs	  = 10000;
10439b94acceSBarry Smith   snes->norm		  = 0.0;
1044b4874afaSBarry Smith   snes->rtol		  = 1.e-8;
1045b4874afaSBarry Smith   snes->ttol              = 0.0;
104670441072SBarry Smith   snes->abstol		  = 1.e-50;
10479b94acceSBarry Smith   snes->xtol		  = 1.e-8;
10484b27c08aSLois Curfman McInnes   snes->deltatol	  = 1.e-12;
10499b94acceSBarry Smith   snes->nfuncs            = 0;
105050ffb88aSMatthew Knepley   snes->numFailures       = 0;
105150ffb88aSMatthew Knepley   snes->maxFailures       = 1;
10527a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1053e35cf81dSBarry Smith   snes->lagjacobian       = 1;
1054a8054027SBarry Smith   snes->lagpreconditioner = 1;
1055639f9d9dSBarry Smith   snes->numbermonitors    = 0;
10569b94acceSBarry Smith   snes->data              = 0;
10574dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1058186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
10596f24a144SLois Curfman McInnes   snes->nwork             = 0;
106058c9b817SLisandro Dalcin   snes->work              = 0;
106158c9b817SLisandro Dalcin   snes->nvwork            = 0;
106258c9b817SLisandro Dalcin   snes->vwork             = 0;
1063758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1064758f92a0SBarry Smith   snes->conv_hist_max     = 0;
1065758f92a0SBarry Smith   snes->conv_hist         = PETSC_NULL;
1066758f92a0SBarry Smith   snes->conv_hist_its     = PETSC_NULL;
1067758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1068184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
10699b94acceSBarry Smith 
10703d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
10713d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
10723d4c4710SBarry Smith 
10739b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
107438f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr);
10759b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
10769b94acceSBarry Smith   kctx->version     = 2;
10779b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
10789b94acceSBarry Smith                              this was too large for some test cases */
107975567043SBarry Smith   kctx->rtol_last   = 0.0;
10809b94acceSBarry Smith   kctx->rtol_max    = .9;
10819b94acceSBarry Smith   kctx->gamma       = 1.0;
108271f87433Sdalcinl   kctx->alpha       = .5*(1.0 + sqrt(5.0));
108371f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
10849b94acceSBarry Smith   kctx->threshold   = .1;
108575567043SBarry Smith   kctx->lresid_last = 0.0;
108675567043SBarry Smith   kctx->norm_last   = 0.0;
10879b94acceSBarry Smith 
10889b94acceSBarry Smith   *outsnes = snes;
10893a40ed3dSBarry Smith   PetscFunctionReturn(0);
10909b94acceSBarry Smith }
10919b94acceSBarry Smith 
10924a2ae208SSatish Balay #undef __FUNCT__
10934a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
10949b94acceSBarry Smith /*@C
10959b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
10969b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
10979b94acceSBarry Smith    equations.
10989b94acceSBarry Smith 
10993f9fe445SBarry Smith    Logically Collective on SNES
1100fee21e36SBarry Smith 
1101c7afd0dbSLois Curfman McInnes    Input Parameters:
1102c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1103c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1104de044059SHong Zhang .  func - function evaluation routine
1105c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1106c7afd0dbSLois Curfman McInnes          function evaluation routine (may be PETSC_NULL)
11079b94acceSBarry Smith 
1108c7afd0dbSLois Curfman McInnes    Calling sequence of func:
11098d76a1e5SLois Curfman McInnes $    func (SNES snes,Vec x,Vec f,void *ctx);
1110c7afd0dbSLois Curfman McInnes 
1111313e4042SLois Curfman McInnes .  f - function vector
1112c7afd0dbSLois Curfman McInnes -  ctx - optional user-defined function context
11139b94acceSBarry Smith 
11149b94acceSBarry Smith    Notes:
11159b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
11169b94acceSBarry Smith $      f'(x) x = -f(x),
1117c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
11189b94acceSBarry Smith 
111936851e7fSLois Curfman McInnes    Level: beginner
112036851e7fSLois Curfman McInnes 
11219b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
11229b94acceSBarry Smith 
1123a86d99e1SLois Curfman McInnes .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
11249b94acceSBarry Smith @*/
11257087cfbeSBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
11269b94acceSBarry Smith {
112785385478SLisandro Dalcin   PetscErrorCode ierr;
11283a40ed3dSBarry Smith   PetscFunctionBegin;
11290700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1130d2a683ecSLisandro Dalcin   if (r) {
1131d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1132d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
113385385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
11346bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
113585385478SLisandro Dalcin     snes->vec_func = r;
1136d2a683ecSLisandro Dalcin   } else if (!snes->vec_func && snes->dm) {
1137d2a683ecSLisandro Dalcin     ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
1138d2a683ecSLisandro Dalcin   }
1139d2a683ecSLisandro Dalcin   if (func) snes->ops->computefunction = func;
1140d2a683ecSLisandro Dalcin   if (ctx)  snes->funP                 = ctx;
11413a40ed3dSBarry Smith   PetscFunctionReturn(0);
11429b94acceSBarry Smith }
11439b94acceSBarry Smith 
1144d25893d9SBarry Smith #undef __FUNCT__
1145d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess"
1146d25893d9SBarry Smith /*@C
1147d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1148d25893d9SBarry Smith 
1149d25893d9SBarry Smith    Logically Collective on SNES
1150d25893d9SBarry Smith 
1151d25893d9SBarry Smith    Input Parameters:
1152d25893d9SBarry Smith +  snes - the SNES context
1153d25893d9SBarry Smith .  func - function evaluation routine
1154d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
1155d25893d9SBarry Smith          function evaluation routine (may be PETSC_NULL)
1156d25893d9SBarry Smith 
1157d25893d9SBarry Smith    Calling sequence of func:
1158d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
1159d25893d9SBarry Smith 
1160d25893d9SBarry Smith .  f - function vector
1161d25893d9SBarry Smith -  ctx - optional user-defined function context
1162d25893d9SBarry Smith 
1163d25893d9SBarry Smith    Level: intermediate
1164d25893d9SBarry Smith 
1165d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
1166d25893d9SBarry Smith 
1167d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1168d25893d9SBarry Smith @*/
1169d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1170d25893d9SBarry Smith {
1171d25893d9SBarry Smith   PetscFunctionBegin;
1172d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1173d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
1174d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
1175d25893d9SBarry Smith   PetscFunctionReturn(0);
1176d25893d9SBarry Smith }
1177d25893d9SBarry Smith 
11783ab0aad5SBarry Smith /* --------------------------------------------------------------- */
11793ab0aad5SBarry Smith #undef __FUNCT__
11801096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
11811096aae1SMatthew Knepley /*@C
11821096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
11831096aae1SMatthew Knepley    it assumes a zero right hand side.
11841096aae1SMatthew Knepley 
11853f9fe445SBarry Smith    Logically Collective on SNES
11861096aae1SMatthew Knepley 
11871096aae1SMatthew Knepley    Input Parameter:
11881096aae1SMatthew Knepley .  snes - the SNES context
11891096aae1SMatthew Knepley 
11901096aae1SMatthew Knepley    Output Parameter:
1191bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
11921096aae1SMatthew Knepley 
11931096aae1SMatthew Knepley    Level: intermediate
11941096aae1SMatthew Knepley 
11951096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
11961096aae1SMatthew Knepley 
119785385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
11981096aae1SMatthew Knepley @*/
11997087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
12001096aae1SMatthew Knepley {
12011096aae1SMatthew Knepley   PetscFunctionBegin;
12020700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12031096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
120485385478SLisandro Dalcin   *rhs = snes->vec_rhs;
12051096aae1SMatthew Knepley   PetscFunctionReturn(0);
12061096aae1SMatthew Knepley }
12071096aae1SMatthew Knepley 
12081096aae1SMatthew Knepley #undef __FUNCT__
12094a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
12109b94acceSBarry Smith /*@
121136851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
12129b94acceSBarry Smith                          SNESSetFunction().
12139b94acceSBarry Smith 
1214c7afd0dbSLois Curfman McInnes    Collective on SNES
1215c7afd0dbSLois Curfman McInnes 
12169b94acceSBarry Smith    Input Parameters:
1217c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1218c7afd0dbSLois Curfman McInnes -  x - input vector
12199b94acceSBarry Smith 
12209b94acceSBarry Smith    Output Parameter:
12213638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
12229b94acceSBarry Smith 
12231bffabb2SLois Curfman McInnes    Notes:
122436851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
122536851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
122636851e7fSLois Curfman McInnes    themselves.
122736851e7fSLois Curfman McInnes 
122836851e7fSLois Curfman McInnes    Level: developer
122936851e7fSLois Curfman McInnes 
12309b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
12319b94acceSBarry Smith 
1232a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
12339b94acceSBarry Smith @*/
12347087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
12359b94acceSBarry Smith {
1236dfbe8321SBarry Smith   PetscErrorCode ierr;
12379b94acceSBarry Smith 
12383a40ed3dSBarry Smith   PetscFunctionBegin;
12390700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12400700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
12410700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
1242c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
1243c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
1244184914b5SBarry Smith 
1245d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
1246e7788613SBarry Smith   if (snes->ops->computefunction) {
1247d64ed03dSBarry Smith     PetscStackPush("SNES user function");
124839d508bbSBarry Smith     ierr = (*snes->ops->computefunction)(snes,x,y,snes->funP);CHKERRQ(ierr);
1249d64ed03dSBarry Smith     PetscStackPop;
125085385478SLisandro Dalcin   } else if (snes->vec_rhs) {
12511096aae1SMatthew Knepley     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
125273250ac0SBarry Smith   } else if (snes->dm) {
1253644e2e5bSBarry Smith     ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr);
1254644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
125585385478SLisandro Dalcin   if (snes->vec_rhs) {
125685385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
12573ab0aad5SBarry Smith   }
1258ae3c334cSLois Curfman McInnes   snes->nfuncs++;
1259d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
12603a40ed3dSBarry Smith   PetscFunctionReturn(0);
12619b94acceSBarry Smith }
12629b94acceSBarry Smith 
12634a2ae208SSatish Balay #undef __FUNCT__
12644a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
126562fef451SLois Curfman McInnes /*@
126662fef451SLois Curfman McInnes    SNESComputeJacobian - Computes the Jacobian matrix that has been
126762fef451SLois Curfman McInnes    set with SNESSetJacobian().
126862fef451SLois Curfman McInnes 
1269c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
1270c7afd0dbSLois Curfman McInnes 
127162fef451SLois Curfman McInnes    Input Parameters:
1272c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1273c7afd0dbSLois Curfman McInnes -  x - input vector
127462fef451SLois Curfman McInnes 
127562fef451SLois Curfman McInnes    Output Parameters:
1276c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
127762fef451SLois Curfman McInnes .  B - optional preconditioning matrix
12782b668275SBarry Smith -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1279fee21e36SBarry Smith 
1280e35cf81dSBarry Smith   Options Database Keys:
1281e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
1282693365a8SJed Brown .    -snes_lag_jacobian <lag>
1283693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
1284693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
1285693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
1286693365a8SJed Brown -    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
1287e35cf81dSBarry Smith 
128862fef451SLois Curfman McInnes    Notes:
128962fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
129062fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
129162fef451SLois Curfman McInnes 
129294b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the
1293dc5a77f8SLois Curfman McInnes    flag parameter.
129462fef451SLois Curfman McInnes 
129536851e7fSLois Curfman McInnes    Level: developer
129636851e7fSLois Curfman McInnes 
129762fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
129862fef451SLois Curfman McInnes 
1299e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
130062fef451SLois Curfman McInnes @*/
13017087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
13029b94acceSBarry Smith {
1303dfbe8321SBarry Smith   PetscErrorCode ierr;
1304ace3abfcSBarry Smith   PetscBool      flag;
13053a40ed3dSBarry Smith 
13063a40ed3dSBarry Smith   PetscFunctionBegin;
13070700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
13080700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
13094482741eSBarry Smith   PetscValidPointer(flg,5);
1310c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
1311e7788613SBarry Smith   if (!snes->ops->computejacobian) PetscFunctionReturn(0);
1312ebd3b9afSBarry Smith 
1313ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
1314ebd3b9afSBarry Smith 
1315fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
1316fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
1317fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
1318fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
1319e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1320e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
1321ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1322ebd3b9afSBarry Smith     if (flag) {
1323ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1324ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1325ebd3b9afSBarry Smith     }
1326e35cf81dSBarry Smith     PetscFunctionReturn(0);
1327e35cf81dSBarry Smith   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
1328e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1329e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
1330ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1331ebd3b9afSBarry Smith     if (flag) {
1332ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1333ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1334ebd3b9afSBarry Smith     }
1335e35cf81dSBarry Smith     PetscFunctionReturn(0);
1336e35cf81dSBarry Smith   }
1337e35cf81dSBarry Smith 
1338c4fc05e7SBarry Smith   *flg = DIFFERENT_NONZERO_PATTERN;
1339e35cf81dSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1340d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
1341e7788613SBarry Smith   ierr = (*snes->ops->computejacobian)(snes,X,A,B,flg,snes->jacP);CHKERRQ(ierr);
1342d64ed03dSBarry Smith   PetscStackPop;
1343d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1344a8054027SBarry Smith 
13453b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
13463b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
13473b4f5425SBarry Smith     snes->lagpreconditioner = -1;
13483b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
1349a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1350a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
1351a8054027SBarry Smith   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
1352a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1353a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
1354a8054027SBarry Smith   }
1355a8054027SBarry Smith 
13566d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
13570700a824SBarry Smith   /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
13580700a824SBarry Smith     PetscValidHeaderSpecific(*B,MAT_CLASSID,4);   */
1359693365a8SJed Brown   {
1360693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
1361693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr);
1362693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
1363693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
1364693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr);
1365693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
1366693365a8SJed Brown       Mat Bexp_mine = PETSC_NULL,Bexp,FDexp;
1367693365a8SJed Brown       MatStructure mstruct;
1368693365a8SJed Brown       PetscViewer vdraw,vstdout;
13696b3a5b13SJed Brown       PetscBool flg;
1370693365a8SJed Brown       if (flag_operator) {
1371693365a8SJed Brown         ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr);
1372693365a8SJed Brown         Bexp = Bexp_mine;
1373693365a8SJed Brown       } else {
1374693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
1375693365a8SJed Brown         ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
1376693365a8SJed Brown         if (flg) Bexp = *B;
1377693365a8SJed Brown         else {
1378693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
1379693365a8SJed Brown           ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr);
1380693365a8SJed Brown           Bexp = Bexp_mine;
1381693365a8SJed Brown         }
1382693365a8SJed Brown       }
1383693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
1384693365a8SJed Brown       ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr);
1385693365a8SJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
1386693365a8SJed Brown       if (flag_draw || flag_contour) {
1387693365a8SJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
1388693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
1389693365a8SJed Brown       } else vdraw = PETSC_NULL;
1390693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr);
1391693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
1392693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
1393693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
1394693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
1395693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
1396693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
1397693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
1398693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
1399693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
1400693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
1401693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
1402693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
1403693365a8SJed Brown       }
1404693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
1405693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
1406693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
1407693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
1408693365a8SJed Brown     }
1409693365a8SJed Brown   }
14103a40ed3dSBarry Smith   PetscFunctionReturn(0);
14119b94acceSBarry Smith }
14129b94acceSBarry Smith 
14134a2ae208SSatish Balay #undef __FUNCT__
14144a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
14159b94acceSBarry Smith /*@C
14169b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
1417044dda88SLois Curfman McInnes    location to store the matrix.
14189b94acceSBarry Smith 
14193f9fe445SBarry Smith    Logically Collective on SNES and Mat
1420c7afd0dbSLois Curfman McInnes 
14219b94acceSBarry Smith    Input Parameters:
1422c7afd0dbSLois Curfman McInnes +  snes - the SNES context
14239b94acceSBarry Smith .  A - Jacobian matrix
14249b94acceSBarry Smith .  B - preconditioner matrix (usually same as the Jacobian)
1425efd51863SBarry Smith .  func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value)
1426c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1427efd51863SBarry Smith          Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value)
14289b94acceSBarry Smith 
14299b94acceSBarry Smith    Calling sequence of func:
14308d76a1e5SLois Curfman McInnes $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
14319b94acceSBarry Smith 
1432c7afd0dbSLois Curfman McInnes +  x - input vector
14339b94acceSBarry Smith .  A - Jacobian matrix
14349b94acceSBarry Smith .  B - preconditioner matrix, usually the same as A
1435ac21db08SLois Curfman McInnes .  flag - flag indicating information about the preconditioner matrix
14362b668275SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
1437c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined Jacobian context
14389b94acceSBarry Smith 
14399b94acceSBarry Smith    Notes:
144094b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the flag
14412cd2dfdcSLois Curfman McInnes    output parameter in the routine func().  Be sure to read this information!
1442ac21db08SLois Curfman McInnes 
1443ac21db08SLois Curfman McInnes    The routine func() takes Mat * as the matrix arguments rather than Mat.
14449b94acceSBarry Smith    This allows the Jacobian evaluation routine to replace A and/or B with a
14459b94acceSBarry Smith    completely new new matrix structure (not just different matrix elements)
14469b94acceSBarry Smith    when appropriate, for instance, if the nonzero structure is changing
14479b94acceSBarry Smith    throughout the global iterations.
14489b94acceSBarry Smith 
144916913363SBarry Smith    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
145016913363SBarry Smith    each matrix.
145116913363SBarry Smith 
1452a8a26c1eSJed Brown    If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument
1453a8a26c1eSJed Brown    must be a MatFDColoring.
1454a8a26c1eSJed Brown 
145536851e7fSLois Curfman McInnes    Level: beginner
145636851e7fSLois Curfman McInnes 
14579b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
14589b94acceSBarry Smith 
14593ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
14609b94acceSBarry Smith @*/
14617087cfbeSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
14629b94acceSBarry Smith {
1463dfbe8321SBarry Smith   PetscErrorCode ierr;
14643a7fca6bSBarry Smith 
14653a40ed3dSBarry Smith   PetscFunctionBegin;
14660700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
14670700a824SBarry Smith   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
14680700a824SBarry Smith   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
1469c9780b6fSBarry Smith   if (A) PetscCheckSameComm(snes,1,A,2);
147006975374SJed Brown   if (B) PetscCheckSameComm(snes,1,B,3);
1471e7788613SBarry Smith   if (func) snes->ops->computejacobian = func;
14723a7fca6bSBarry Smith   if (ctx)  snes->jacP                 = ctx;
14733a7fca6bSBarry Smith   if (A) {
14747dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
14756bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
14769b94acceSBarry Smith     snes->jacobian = A;
14773a7fca6bSBarry Smith   }
14783a7fca6bSBarry Smith   if (B) {
14797dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
14806bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
14819b94acceSBarry Smith     snes->jacobian_pre = B;
14823a7fca6bSBarry Smith   }
14833a40ed3dSBarry Smith   PetscFunctionReturn(0);
14849b94acceSBarry Smith }
148562fef451SLois Curfman McInnes 
14864a2ae208SSatish Balay #undef __FUNCT__
14874a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
1488c2aafc4cSSatish Balay /*@C
1489b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
1490b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
1491b4fd4287SBarry Smith 
1492c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
1493c7afd0dbSLois Curfman McInnes 
1494b4fd4287SBarry Smith    Input Parameter:
1495b4fd4287SBarry Smith .  snes - the nonlinear solver context
1496b4fd4287SBarry Smith 
1497b4fd4287SBarry Smith    Output Parameters:
1498c7afd0dbSLois Curfman McInnes +  A - location to stash Jacobian matrix (or PETSC_NULL)
1499b4fd4287SBarry Smith .  B - location to stash preconditioner matrix (or PETSC_NULL)
150070e92668SMatthew Knepley .  func - location to put Jacobian function (or PETSC_NULL)
150170e92668SMatthew Knepley -  ctx - location to stash Jacobian ctx (or PETSC_NULL)
1502fee21e36SBarry Smith 
150336851e7fSLois Curfman McInnes    Level: advanced
150436851e7fSLois Curfman McInnes 
1505b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian()
1506b4fd4287SBarry Smith @*/
15077087cfbeSBarry Smith PetscErrorCode  SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
1508b4fd4287SBarry Smith {
15093a40ed3dSBarry Smith   PetscFunctionBegin;
15100700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1511b4fd4287SBarry Smith   if (A)    *A    = snes->jacobian;
1512b4fd4287SBarry Smith   if (B)    *B    = snes->jacobian_pre;
1513e7788613SBarry Smith   if (func) *func = snes->ops->computejacobian;
151470e92668SMatthew Knepley   if (ctx)  *ctx  = snes->jacP;
15153a40ed3dSBarry Smith   PetscFunctionReturn(0);
1516b4fd4287SBarry Smith }
1517b4fd4287SBarry Smith 
15189b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
15199b94acceSBarry Smith 
15204a2ae208SSatish Balay #undef __FUNCT__
15214a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
15229b94acceSBarry Smith /*@
15239b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
1524272ac6f2SLois Curfman McInnes    of a nonlinear solver.
15259b94acceSBarry Smith 
1526fee21e36SBarry Smith    Collective on SNES
1527fee21e36SBarry Smith 
1528c7afd0dbSLois Curfman McInnes    Input Parameters:
152970e92668SMatthew Knepley .  snes - the SNES context
1530c7afd0dbSLois Curfman McInnes 
1531272ac6f2SLois Curfman McInnes    Notes:
1532272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
1533272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
1534272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
1535272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
1536272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
1537272ac6f2SLois Curfman McInnes 
153836851e7fSLois Curfman McInnes    Level: advanced
153936851e7fSLois Curfman McInnes 
15409b94acceSBarry Smith .keywords: SNES, nonlinear, setup
15419b94acceSBarry Smith 
15429b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
15439b94acceSBarry Smith @*/
15447087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
15459b94acceSBarry Smith {
1546dfbe8321SBarry Smith   PetscErrorCode ierr;
15473a40ed3dSBarry Smith 
15483a40ed3dSBarry Smith   PetscFunctionBegin;
15490700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15504dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
15519b94acceSBarry Smith 
15527adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
155385385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
155485385478SLisandro Dalcin   }
155585385478SLisandro Dalcin 
1556efd51863SBarry Smith   if (!snes->vec_func && snes->dm && !snes->vec_rhs) {
1557efd51863SBarry Smith     ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
1558efd51863SBarry Smith   }
155917186662SBarry Smith   if (!snes->vec_func && !snes->vec_rhs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
1560644e2e5bSBarry Smith   if (!snes->ops->computefunction && !snes->vec_rhs && !snes->dm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() or SNESSetDM() first");
156117186662SBarry Smith   if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
156258c9b817SLisandro Dalcin   if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
156358c9b817SLisandro Dalcin 
156458c9b817SLisandro Dalcin   if (!snes->vec_func && snes->vec_rhs) {
156558c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_rhs, &snes->vec_func);CHKERRQ(ierr);
156658c9b817SLisandro Dalcin   }
156758c9b817SLisandro Dalcin   if (!snes->vec_sol_update /* && snes->vec_sol */) {
156858c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
156958c9b817SLisandro Dalcin     ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr);
157058c9b817SLisandro Dalcin   }
157158c9b817SLisandro Dalcin 
1572ef8dffc7SBarry Smith   if (!snes->ops->computejacobian && snes->dm) {
1573ef8dffc7SBarry Smith     Mat           J;
1574ef8dffc7SBarry Smith     ierr = DMGetMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr);
1575cab2e9ccSBarry Smith     ierr = SNESSetJacobian(snes,J,J,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr);
1576cab2e9ccSBarry Smith     ierr = MatDestroy(&J);CHKERRQ(ierr);
1577efd51863SBarry Smith   } else if (snes->dm && !snes->jacobian_pre){
1578efd51863SBarry Smith     Mat J;
1579efd51863SBarry Smith     ierr = DMGetMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr);
1580efd51863SBarry Smith     ierr = SNESSetJacobian(snes,J,J,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
1581efd51863SBarry Smith     ierr = MatDestroy(&J);CHKERRQ(ierr);
1582ef8dffc7SBarry Smith   }
1583efd51863SBarry Smith 
1584b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
1585b710008aSBarry Smith 
1586d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
1587d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
1588d25893d9SBarry Smith   }
1589d25893d9SBarry Smith 
1590410397dcSLisandro Dalcin   if (snes->ops->setup) {
1591410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
1592410397dcSLisandro Dalcin   }
159358c9b817SLisandro Dalcin 
15947aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
15953a40ed3dSBarry Smith   PetscFunctionReturn(0);
15969b94acceSBarry Smith }
15979b94acceSBarry Smith 
15984a2ae208SSatish Balay #undef __FUNCT__
159937596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
160037596af1SLisandro Dalcin /*@
160137596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
160237596af1SLisandro Dalcin 
160337596af1SLisandro Dalcin    Collective on SNES
160437596af1SLisandro Dalcin 
160537596af1SLisandro Dalcin    Input Parameter:
160637596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
160737596af1SLisandro Dalcin 
1608d25893d9SBarry Smith    Level: intermediate
1609d25893d9SBarry Smith 
1610d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
161137596af1SLisandro Dalcin 
161237596af1SLisandro Dalcin .keywords: SNES, destroy
161337596af1SLisandro Dalcin 
161437596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
161537596af1SLisandro Dalcin @*/
161637596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
161737596af1SLisandro Dalcin {
161837596af1SLisandro Dalcin   PetscErrorCode ierr;
161937596af1SLisandro Dalcin 
162037596af1SLisandro Dalcin   PetscFunctionBegin;
162137596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1622d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
1623d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
1624d25893d9SBarry Smith     snes->user = PETSC_NULL;
1625d25893d9SBarry Smith   }
1626644e2e5bSBarry Smith   if (snes->ops->computejacobian == SNESDefaultComputeJacobianColor && snes->dm) {
1627644e2e5bSBarry Smith     ierr = MatFDColoringDestroy((MatFDColoring*)&snes->jacP);CHKERRQ(ierr);
1628644e2e5bSBarry Smith     snes->ops->computejacobian = PETSC_NULL;
1629644e2e5bSBarry Smith   }
1630d25893d9SBarry Smith 
163137596af1SLisandro Dalcin   if (snes->ops->reset) {
163237596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
163337596af1SLisandro Dalcin   }
163437596af1SLisandro Dalcin   if (snes->ksp) {ierr = KSPReset(snes->ksp);CHKERRQ(ierr);}
16356bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
16366bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
16376bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
16386bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
16396bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
16406bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
164137596af1SLisandro Dalcin   if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);}
164237596af1SLisandro Dalcin   if (snes->vwork) {ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);}
164337596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
164437596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
164537596af1SLisandro Dalcin   PetscFunctionReturn(0);
164637596af1SLisandro Dalcin }
164737596af1SLisandro Dalcin 
164837596af1SLisandro Dalcin #undef __FUNCT__
16494a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
165052baeb72SSatish Balay /*@
16519b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
16529b94acceSBarry Smith    with SNESCreate().
16539b94acceSBarry Smith 
1654c7afd0dbSLois Curfman McInnes    Collective on SNES
1655c7afd0dbSLois Curfman McInnes 
16569b94acceSBarry Smith    Input Parameter:
16579b94acceSBarry Smith .  snes - the SNES context
16589b94acceSBarry Smith 
165936851e7fSLois Curfman McInnes    Level: beginner
166036851e7fSLois Curfman McInnes 
16619b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
16629b94acceSBarry Smith 
166363a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
16649b94acceSBarry Smith @*/
16656bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
16669b94acceSBarry Smith {
16676849ba73SBarry Smith   PetscErrorCode ierr;
16683a40ed3dSBarry Smith 
16693a40ed3dSBarry Smith   PetscFunctionBegin;
16706bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
16716bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
16726bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
1673d4bb536fSBarry Smith 
16746bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
16756b8b9a38SLisandro Dalcin 
1676be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
16776bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
16786bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
16796d4c513bSLisandro Dalcin 
16806bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
16816bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
16826b8b9a38SLisandro Dalcin 
16836bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
16846bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
16856bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
16866b8b9a38SLisandro Dalcin   }
16876bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
16886bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
16896bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
169058c9b817SLisandro Dalcin   }
16916bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
1692a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
16933a40ed3dSBarry Smith   PetscFunctionReturn(0);
16949b94acceSBarry Smith }
16959b94acceSBarry Smith 
16969b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
16979b94acceSBarry Smith 
16984a2ae208SSatish Balay #undef __FUNCT__
1699a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
1700a8054027SBarry Smith /*@
1701a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
1702a8054027SBarry Smith 
17033f9fe445SBarry Smith    Logically Collective on SNES
1704a8054027SBarry Smith 
1705a8054027SBarry Smith    Input Parameters:
1706a8054027SBarry Smith +  snes - the SNES context
1707a8054027SBarry 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
17083b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
1709a8054027SBarry Smith 
1710a8054027SBarry Smith    Options Database Keys:
1711a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
1712a8054027SBarry Smith 
1713a8054027SBarry Smith    Notes:
1714a8054027SBarry Smith    The default is 1
1715a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1716a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
1717a8054027SBarry Smith 
1718a8054027SBarry Smith    Level: intermediate
1719a8054027SBarry Smith 
1720a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1721a8054027SBarry Smith 
1722e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
1723a8054027SBarry Smith 
1724a8054027SBarry Smith @*/
17257087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
1726a8054027SBarry Smith {
1727a8054027SBarry Smith   PetscFunctionBegin;
17280700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1729e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
1730e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
1731c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
1732a8054027SBarry Smith   snes->lagpreconditioner = lag;
1733a8054027SBarry Smith   PetscFunctionReturn(0);
1734a8054027SBarry Smith }
1735a8054027SBarry Smith 
1736a8054027SBarry Smith #undef __FUNCT__
1737efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
1738efd51863SBarry Smith /*@
1739efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
1740efd51863SBarry Smith 
1741efd51863SBarry Smith    Logically Collective on SNES
1742efd51863SBarry Smith 
1743efd51863SBarry Smith    Input Parameters:
1744efd51863SBarry Smith +  snes - the SNES context
1745efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
1746efd51863SBarry Smith 
1747efd51863SBarry Smith    Options Database Keys:
1748efd51863SBarry Smith .    -snes_grid_sequence <steps>
1749efd51863SBarry Smith 
1750efd51863SBarry Smith    Level: intermediate
1751efd51863SBarry Smith 
1752efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1753efd51863SBarry Smith 
1754efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
1755efd51863SBarry Smith 
1756efd51863SBarry Smith @*/
1757efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
1758efd51863SBarry Smith {
1759efd51863SBarry Smith   PetscFunctionBegin;
1760efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1761efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
1762efd51863SBarry Smith   snes->gridsequence = steps;
1763efd51863SBarry Smith   PetscFunctionReturn(0);
1764efd51863SBarry Smith }
1765efd51863SBarry Smith 
1766efd51863SBarry Smith #undef __FUNCT__
1767a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
1768a8054027SBarry Smith /*@
1769a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
1770a8054027SBarry Smith 
17713f9fe445SBarry Smith    Not Collective
1772a8054027SBarry Smith 
1773a8054027SBarry Smith    Input Parameter:
1774a8054027SBarry Smith .  snes - the SNES context
1775a8054027SBarry Smith 
1776a8054027SBarry Smith    Output Parameter:
1777a8054027SBarry 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
17783b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
1779a8054027SBarry Smith 
1780a8054027SBarry Smith    Options Database Keys:
1781a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
1782a8054027SBarry Smith 
1783a8054027SBarry Smith    Notes:
1784a8054027SBarry Smith    The default is 1
1785a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1786a8054027SBarry Smith 
1787a8054027SBarry Smith    Level: intermediate
1788a8054027SBarry Smith 
1789a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1790a8054027SBarry Smith 
1791a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
1792a8054027SBarry Smith 
1793a8054027SBarry Smith @*/
17947087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
1795a8054027SBarry Smith {
1796a8054027SBarry Smith   PetscFunctionBegin;
17970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1798a8054027SBarry Smith   *lag = snes->lagpreconditioner;
1799a8054027SBarry Smith   PetscFunctionReturn(0);
1800a8054027SBarry Smith }
1801a8054027SBarry Smith 
1802a8054027SBarry Smith #undef __FUNCT__
1803e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
1804e35cf81dSBarry Smith /*@
1805e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
1806e35cf81dSBarry Smith      often the preconditioner is rebuilt.
1807e35cf81dSBarry Smith 
18083f9fe445SBarry Smith    Logically Collective on SNES
1809e35cf81dSBarry Smith 
1810e35cf81dSBarry Smith    Input Parameters:
1811e35cf81dSBarry Smith +  snes - the SNES context
1812e35cf81dSBarry 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
1813fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
1814e35cf81dSBarry Smith 
1815e35cf81dSBarry Smith    Options Database Keys:
1816e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
1817e35cf81dSBarry Smith 
1818e35cf81dSBarry Smith    Notes:
1819e35cf81dSBarry Smith    The default is 1
1820e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1821fe3ffe1eSBarry 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
1822fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
1823e35cf81dSBarry Smith 
1824e35cf81dSBarry Smith    Level: intermediate
1825e35cf81dSBarry Smith 
1826e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1827e35cf81dSBarry Smith 
1828e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
1829e35cf81dSBarry Smith 
1830e35cf81dSBarry Smith @*/
18317087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
1832e35cf81dSBarry Smith {
1833e35cf81dSBarry Smith   PetscFunctionBegin;
18340700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1835e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
1836e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
1837c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
1838e35cf81dSBarry Smith   snes->lagjacobian = lag;
1839e35cf81dSBarry Smith   PetscFunctionReturn(0);
1840e35cf81dSBarry Smith }
1841e35cf81dSBarry Smith 
1842e35cf81dSBarry Smith #undef __FUNCT__
1843e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
1844e35cf81dSBarry Smith /*@
1845e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
1846e35cf81dSBarry Smith 
18473f9fe445SBarry Smith    Not Collective
1848e35cf81dSBarry Smith 
1849e35cf81dSBarry Smith    Input Parameter:
1850e35cf81dSBarry Smith .  snes - the SNES context
1851e35cf81dSBarry Smith 
1852e35cf81dSBarry Smith    Output Parameter:
1853e35cf81dSBarry 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
1854e35cf81dSBarry Smith          the Jacobian is built etc.
1855e35cf81dSBarry Smith 
1856e35cf81dSBarry Smith    Options Database Keys:
1857e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
1858e35cf81dSBarry Smith 
1859e35cf81dSBarry Smith    Notes:
1860e35cf81dSBarry Smith    The default is 1
1861e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1862e35cf81dSBarry Smith 
1863e35cf81dSBarry Smith    Level: intermediate
1864e35cf81dSBarry Smith 
1865e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1866e35cf81dSBarry Smith 
1867e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
1868e35cf81dSBarry Smith 
1869e35cf81dSBarry Smith @*/
18707087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
1871e35cf81dSBarry Smith {
1872e35cf81dSBarry Smith   PetscFunctionBegin;
18730700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1874e35cf81dSBarry Smith   *lag = snes->lagjacobian;
1875e35cf81dSBarry Smith   PetscFunctionReturn(0);
1876e35cf81dSBarry Smith }
1877e35cf81dSBarry Smith 
1878e35cf81dSBarry Smith #undef __FUNCT__
18794a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
18809b94acceSBarry Smith /*@
1881d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
18829b94acceSBarry Smith 
18833f9fe445SBarry Smith    Logically Collective on SNES
1884c7afd0dbSLois Curfman McInnes 
18859b94acceSBarry Smith    Input Parameters:
1886c7afd0dbSLois Curfman McInnes +  snes - the SNES context
188770441072SBarry Smith .  abstol - absolute convergence tolerance
188833174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
188933174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
189033174efeSLois Curfman McInnes            of the change in the solution between steps
189133174efeSLois Curfman McInnes .  maxit - maximum number of iterations
1892c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
1893fee21e36SBarry Smith 
189433174efeSLois Curfman McInnes    Options Database Keys:
189570441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
1896c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
1897c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
1898c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
1899c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
19009b94acceSBarry Smith 
1901d7a720efSLois Curfman McInnes    Notes:
19029b94acceSBarry Smith    The default maximum number of iterations is 50.
19039b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
19049b94acceSBarry Smith 
190536851e7fSLois Curfman McInnes    Level: intermediate
190636851e7fSLois Curfman McInnes 
190733174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
19089b94acceSBarry Smith 
19092492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
19109b94acceSBarry Smith @*/
19117087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
19129b94acceSBarry Smith {
19133a40ed3dSBarry Smith   PetscFunctionBegin;
19140700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1915c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
1916c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
1917c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
1918c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
1919c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
1920c5eb9154SBarry Smith 
192170441072SBarry Smith   if (abstol != PETSC_DEFAULT)  snes->abstol      = abstol;
1922d7a720efSLois Curfman McInnes   if (rtol != PETSC_DEFAULT)  snes->rtol      = rtol;
1923d7a720efSLois Curfman McInnes   if (stol != PETSC_DEFAULT)  snes->xtol      = stol;
1924d7a720efSLois Curfman McInnes   if (maxit != PETSC_DEFAULT) snes->max_its   = maxit;
1925d7a720efSLois Curfman McInnes   if (maxf != PETSC_DEFAULT)  snes->max_funcs = maxf;
19263a40ed3dSBarry Smith   PetscFunctionReturn(0);
19279b94acceSBarry Smith }
19289b94acceSBarry Smith 
19294a2ae208SSatish Balay #undef __FUNCT__
19304a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
19319b94acceSBarry Smith /*@
193233174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
193333174efeSLois Curfman McInnes 
1934c7afd0dbSLois Curfman McInnes    Not Collective
1935c7afd0dbSLois Curfman McInnes 
193633174efeSLois Curfman McInnes    Input Parameters:
1937c7afd0dbSLois Curfman McInnes +  snes - the SNES context
193885385478SLisandro Dalcin .  atol - absolute convergence tolerance
193933174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
194033174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
194133174efeSLois Curfman McInnes            of the change in the solution between steps
194233174efeSLois Curfman McInnes .  maxit - maximum number of iterations
1943c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
1944fee21e36SBarry Smith 
194533174efeSLois Curfman McInnes    Notes:
194633174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
194733174efeSLois Curfman McInnes 
194836851e7fSLois Curfman McInnes    Level: intermediate
194936851e7fSLois Curfman McInnes 
195033174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
195133174efeSLois Curfman McInnes 
195233174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
195333174efeSLois Curfman McInnes @*/
19547087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
195533174efeSLois Curfman McInnes {
19563a40ed3dSBarry Smith   PetscFunctionBegin;
19570700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
195885385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
195933174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
196033174efeSLois Curfman McInnes   if (stol)  *stol  = snes->xtol;
196133174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
196233174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
19633a40ed3dSBarry Smith   PetscFunctionReturn(0);
196433174efeSLois Curfman McInnes }
196533174efeSLois Curfman McInnes 
19664a2ae208SSatish Balay #undef __FUNCT__
19674a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
196833174efeSLois Curfman McInnes /*@
19699b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
19709b94acceSBarry Smith 
19713f9fe445SBarry Smith    Logically Collective on SNES
1972fee21e36SBarry Smith 
1973c7afd0dbSLois Curfman McInnes    Input Parameters:
1974c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1975c7afd0dbSLois Curfman McInnes -  tol - tolerance
1976c7afd0dbSLois Curfman McInnes 
19779b94acceSBarry Smith    Options Database Key:
1978c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
19799b94acceSBarry Smith 
198036851e7fSLois Curfman McInnes    Level: intermediate
198136851e7fSLois Curfman McInnes 
19829b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
19839b94acceSBarry Smith 
19842492ecdbSBarry Smith .seealso: SNESSetTolerances()
19859b94acceSBarry Smith @*/
19867087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
19879b94acceSBarry Smith {
19883a40ed3dSBarry Smith   PetscFunctionBegin;
19890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1990c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
19919b94acceSBarry Smith   snes->deltatol = tol;
19923a40ed3dSBarry Smith   PetscFunctionReturn(0);
19939b94acceSBarry Smith }
19949b94acceSBarry Smith 
1995df9fa365SBarry Smith /*
1996df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
1997df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
1998df9fa365SBarry Smith    macros instead of functions
1999df9fa365SBarry Smith */
20004a2ae208SSatish Balay #undef __FUNCT__
2001a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
20027087cfbeSBarry Smith PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2003ce1608b8SBarry Smith {
2004dfbe8321SBarry Smith   PetscErrorCode ierr;
2005ce1608b8SBarry Smith 
2006ce1608b8SBarry Smith   PetscFunctionBegin;
20070700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2008a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
2009ce1608b8SBarry Smith   PetscFunctionReturn(0);
2010ce1608b8SBarry Smith }
2011ce1608b8SBarry Smith 
20124a2ae208SSatish Balay #undef __FUNCT__
2013a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
20147087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2015df9fa365SBarry Smith {
2016dfbe8321SBarry Smith   PetscErrorCode ierr;
2017df9fa365SBarry Smith 
2018df9fa365SBarry Smith   PetscFunctionBegin;
2019a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2020df9fa365SBarry Smith   PetscFunctionReturn(0);
2021df9fa365SBarry Smith }
2022df9fa365SBarry Smith 
20234a2ae208SSatish Balay #undef __FUNCT__
2024a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
20256bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
2026df9fa365SBarry Smith {
2027dfbe8321SBarry Smith   PetscErrorCode ierr;
2028df9fa365SBarry Smith 
2029df9fa365SBarry Smith   PetscFunctionBegin;
2030a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2031df9fa365SBarry Smith   PetscFunctionReturn(0);
2032df9fa365SBarry Smith }
2033df9fa365SBarry Smith 
20347087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
2035b271bb04SBarry Smith #undef __FUNCT__
2036b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
20377087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2038b271bb04SBarry Smith {
2039b271bb04SBarry Smith   PetscDrawLG      lg;
2040b271bb04SBarry Smith   PetscErrorCode   ierr;
2041b271bb04SBarry Smith   PetscReal        x,y,per;
2042b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
2043b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
2044b271bb04SBarry Smith   PetscDraw        draw;
2045b271bb04SBarry Smith   PetscFunctionBegin;
2046b271bb04SBarry Smith   if (!monctx) {
2047b271bb04SBarry Smith     MPI_Comm    comm;
2048b271bb04SBarry Smith 
2049b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2050b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
2051b271bb04SBarry Smith   }
2052b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
2053b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2054b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2055b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
2056b271bb04SBarry Smith   x = (PetscReal) n;
2057b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
2058b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2059b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2060b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2061b271bb04SBarry Smith   }
2062b271bb04SBarry Smith 
2063b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
2064b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2065b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2066b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
2067b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
2068b271bb04SBarry Smith   x = (PetscReal) n;
2069b271bb04SBarry Smith   y = 100.0*per;
2070b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2071b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2072b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2073b271bb04SBarry Smith   }
2074b271bb04SBarry Smith 
2075b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
2076b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2077b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2078b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
2079b271bb04SBarry Smith   x = (PetscReal) n;
2080b271bb04SBarry Smith   y = (prev - rnorm)/prev;
2081b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2082b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2083b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2084b271bb04SBarry Smith   }
2085b271bb04SBarry Smith 
2086b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
2087b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2088b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2089b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
2090b271bb04SBarry Smith   x = (PetscReal) n;
2091b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
2092b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
2093b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2094b271bb04SBarry Smith   }
2095b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2096b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2097b271bb04SBarry Smith   }
2098b271bb04SBarry Smith   prev = rnorm;
2099b271bb04SBarry Smith   PetscFunctionReturn(0);
2100b271bb04SBarry Smith }
2101b271bb04SBarry Smith 
2102b271bb04SBarry Smith #undef __FUNCT__
2103b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
21047087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2105b271bb04SBarry Smith {
2106b271bb04SBarry Smith   PetscErrorCode ierr;
2107b271bb04SBarry Smith 
2108b271bb04SBarry Smith   PetscFunctionBegin;
2109b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2110b271bb04SBarry Smith   PetscFunctionReturn(0);
2111b271bb04SBarry Smith }
2112b271bb04SBarry Smith 
2113b271bb04SBarry Smith #undef __FUNCT__
2114b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
21156bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG *draw)
2116b271bb04SBarry Smith {
2117b271bb04SBarry Smith   PetscErrorCode ierr;
2118b271bb04SBarry Smith 
2119b271bb04SBarry Smith   PetscFunctionBegin;
2120b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2121b271bb04SBarry Smith   PetscFunctionReturn(0);
2122b271bb04SBarry Smith }
2123b271bb04SBarry Smith 
21247a03ce2fSLisandro Dalcin #undef __FUNCT__
21257a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
21267a03ce2fSLisandro Dalcin /*
21277a03ce2fSLisandro Dalcin      Runs the user provided monitor routines, if they exists.
21287a03ce2fSLisandro Dalcin */
21297a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
21307a03ce2fSLisandro Dalcin {
21317a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
21327a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
21337a03ce2fSLisandro Dalcin 
21347a03ce2fSLisandro Dalcin   PetscFunctionBegin;
21357a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
21367a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
21377a03ce2fSLisandro Dalcin   }
21387a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
21397a03ce2fSLisandro Dalcin }
21407a03ce2fSLisandro Dalcin 
21419b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
21429b94acceSBarry Smith 
21434a2ae208SSatish Balay #undef __FUNCT__
2144a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
21459b94acceSBarry Smith /*@C
2146a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
21479b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
21489b94acceSBarry Smith    progress.
21499b94acceSBarry Smith 
21503f9fe445SBarry Smith    Logically Collective on SNES
2151fee21e36SBarry Smith 
2152c7afd0dbSLois Curfman McInnes    Input Parameters:
2153c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2154c7afd0dbSLois Curfman McInnes .  func - monitoring routine
2155b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
2156e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
2157b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
2158b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
21599b94acceSBarry Smith 
2160c7afd0dbSLois Curfman McInnes    Calling sequence of func:
2161a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
2162c7afd0dbSLois Curfman McInnes 
2163c7afd0dbSLois Curfman McInnes +    snes - the SNES context
2164c7afd0dbSLois Curfman McInnes .    its - iteration number
2165c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
216640a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
21679b94acceSBarry Smith 
21689665c990SLois Curfman McInnes    Options Database Keys:
2169a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
2170a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
2171a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
2172cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
2173c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
2174a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
2175c7afd0dbSLois Curfman McInnes                             does not cancel those set via
2176c7afd0dbSLois Curfman McInnes                             the options database.
21779665c990SLois Curfman McInnes 
2178639f9d9dSBarry Smith    Notes:
21796bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
2180a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
21816bc08f3fSLois Curfman McInnes    order in which they were set.
2182639f9d9dSBarry Smith 
2183025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
2184025f1a04SBarry Smith 
218536851e7fSLois Curfman McInnes    Level: intermediate
218636851e7fSLois Curfman McInnes 
21879b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
21889b94acceSBarry Smith 
2189a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
21909b94acceSBarry Smith @*/
2191c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
21929b94acceSBarry Smith {
2193b90d0a6eSBarry Smith   PetscInt       i;
2194649052a6SBarry Smith   PetscErrorCode ierr;
2195b90d0a6eSBarry Smith 
21963a40ed3dSBarry Smith   PetscFunctionBegin;
21970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
219817186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
2199b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
2200649052a6SBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
2201649052a6SBarry Smith       if (monitordestroy) {
2202c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
2203649052a6SBarry Smith       }
2204b90d0a6eSBarry Smith       PetscFunctionReturn(0);
2205b90d0a6eSBarry Smith     }
2206b90d0a6eSBarry Smith   }
2207b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
2208b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
2209639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
22103a40ed3dSBarry Smith   PetscFunctionReturn(0);
22119b94acceSBarry Smith }
22129b94acceSBarry Smith 
22134a2ae208SSatish Balay #undef __FUNCT__
2214a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
22155cd90555SBarry Smith /*@C
2216a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
22175cd90555SBarry Smith 
22183f9fe445SBarry Smith    Logically Collective on SNES
2219c7afd0dbSLois Curfman McInnes 
22205cd90555SBarry Smith    Input Parameters:
22215cd90555SBarry Smith .  snes - the SNES context
22225cd90555SBarry Smith 
22231a480d89SAdministrator    Options Database Key:
2224a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
2225a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
2226c7afd0dbSLois Curfman McInnes     set via the options database
22275cd90555SBarry Smith 
22285cd90555SBarry Smith    Notes:
22295cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
22305cd90555SBarry Smith 
223136851e7fSLois Curfman McInnes    Level: intermediate
223236851e7fSLois Curfman McInnes 
22335cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
22345cd90555SBarry Smith 
2235a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
22365cd90555SBarry Smith @*/
22377087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
22385cd90555SBarry Smith {
2239d952e501SBarry Smith   PetscErrorCode ierr;
2240d952e501SBarry Smith   PetscInt       i;
2241d952e501SBarry Smith 
22425cd90555SBarry Smith   PetscFunctionBegin;
22430700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2244d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
2245d952e501SBarry Smith     if (snes->monitordestroy[i]) {
22463c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
2247d952e501SBarry Smith     }
2248d952e501SBarry Smith   }
22495cd90555SBarry Smith   snes->numbermonitors = 0;
22505cd90555SBarry Smith   PetscFunctionReturn(0);
22515cd90555SBarry Smith }
22525cd90555SBarry Smith 
22534a2ae208SSatish Balay #undef __FUNCT__
22544a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
22559b94acceSBarry Smith /*@C
22569b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
22579b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
22589b94acceSBarry Smith 
22593f9fe445SBarry Smith    Logically Collective on SNES
2260fee21e36SBarry Smith 
2261c7afd0dbSLois Curfman McInnes    Input Parameters:
2262c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2263c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
22647f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
22657f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
22669b94acceSBarry Smith 
2267c7afd0dbSLois Curfman McInnes    Calling sequence of func:
226806ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
2269c7afd0dbSLois Curfman McInnes 
2270c7afd0dbSLois Curfman McInnes +    snes - the SNES context
227106ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
2272c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
2273184914b5SBarry Smith .    reason - reason for convergence/divergence
2274c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
22754b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
22764b27c08aSLois Curfman McInnes -    f - 2-norm of function
22779b94acceSBarry Smith 
227836851e7fSLois Curfman McInnes    Level: advanced
227936851e7fSLois Curfman McInnes 
22809b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
22819b94acceSBarry Smith 
228285385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
22839b94acceSBarry Smith @*/
22847087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
22859b94acceSBarry Smith {
22867f7931b9SBarry Smith   PetscErrorCode ierr;
22877f7931b9SBarry Smith 
22883a40ed3dSBarry Smith   PetscFunctionBegin;
22890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
229085385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
22917f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
22927f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
22937f7931b9SBarry Smith   }
229485385478SLisandro Dalcin   snes->ops->converged        = func;
22957f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
229685385478SLisandro Dalcin   snes->cnvP                  = cctx;
22973a40ed3dSBarry Smith   PetscFunctionReturn(0);
22989b94acceSBarry Smith }
22999b94acceSBarry Smith 
23004a2ae208SSatish Balay #undef __FUNCT__
23014a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
230252baeb72SSatish Balay /*@
2303184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
2304184914b5SBarry Smith 
2305184914b5SBarry Smith    Not Collective
2306184914b5SBarry Smith 
2307184914b5SBarry Smith    Input Parameter:
2308184914b5SBarry Smith .  snes - the SNES context
2309184914b5SBarry Smith 
2310184914b5SBarry Smith    Output Parameter:
23114d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
2312184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
2313184914b5SBarry Smith 
2314184914b5SBarry Smith    Level: intermediate
2315184914b5SBarry Smith 
2316184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
2317184914b5SBarry Smith 
2318184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
2319184914b5SBarry Smith 
232085385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
2321184914b5SBarry Smith @*/
23227087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
2323184914b5SBarry Smith {
2324184914b5SBarry Smith   PetscFunctionBegin;
23250700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
23264482741eSBarry Smith   PetscValidPointer(reason,2);
2327184914b5SBarry Smith   *reason = snes->reason;
2328184914b5SBarry Smith   PetscFunctionReturn(0);
2329184914b5SBarry Smith }
2330184914b5SBarry Smith 
23314a2ae208SSatish Balay #undef __FUNCT__
23324a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
2333c9005455SLois Curfman McInnes /*@
2334c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
2335c9005455SLois Curfman McInnes 
23363f9fe445SBarry Smith    Logically Collective on SNES
2337fee21e36SBarry Smith 
2338c7afd0dbSLois Curfman McInnes    Input Parameters:
2339c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
23408c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
2341cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
2342758f92a0SBarry Smith .  na  - size of a and its
234364731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
2344758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
2345c7afd0dbSLois Curfman McInnes 
2346308dcc3eSBarry Smith    Notes:
2347308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
2348308dcc3eSBarry Smith    default array of length 10000 is allocated.
2349308dcc3eSBarry Smith 
2350c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
2351c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
2352c9005455SLois Curfman McInnes    during the section of code that is being timed.
2353c9005455SLois Curfman McInnes 
235436851e7fSLois Curfman McInnes    Level: intermediate
235536851e7fSLois Curfman McInnes 
2356c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
2357758f92a0SBarry Smith 
235808405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
2359758f92a0SBarry Smith 
2360c9005455SLois Curfman McInnes @*/
23617087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
2362c9005455SLois Curfman McInnes {
2363308dcc3eSBarry Smith   PetscErrorCode ierr;
2364308dcc3eSBarry Smith 
23653a40ed3dSBarry Smith   PetscFunctionBegin;
23660700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
23674482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
2368a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
2369308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
2370308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
2371308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
2372308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
2373308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
2374308dcc3eSBarry Smith   }
2375c9005455SLois Curfman McInnes   snes->conv_hist       = a;
2376758f92a0SBarry Smith   snes->conv_hist_its   = its;
2377758f92a0SBarry Smith   snes->conv_hist_max   = na;
2378a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
2379758f92a0SBarry Smith   snes->conv_hist_reset = reset;
2380758f92a0SBarry Smith   PetscFunctionReturn(0);
2381758f92a0SBarry Smith }
2382758f92a0SBarry Smith 
2383308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
2384c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
2385c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
2386308dcc3eSBarry Smith EXTERN_C_BEGIN
2387308dcc3eSBarry Smith #undef __FUNCT__
2388308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
2389308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
2390308dcc3eSBarry Smith {
2391308dcc3eSBarry Smith   mxArray        *mat;
2392308dcc3eSBarry Smith   PetscInt       i;
2393308dcc3eSBarry Smith   PetscReal      *ar;
2394308dcc3eSBarry Smith 
2395308dcc3eSBarry Smith   PetscFunctionBegin;
2396308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
2397308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
2398308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
2399308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
2400308dcc3eSBarry Smith   }
2401308dcc3eSBarry Smith   PetscFunctionReturn(mat);
2402308dcc3eSBarry Smith }
2403308dcc3eSBarry Smith EXTERN_C_END
2404308dcc3eSBarry Smith #endif
2405308dcc3eSBarry Smith 
2406308dcc3eSBarry Smith 
24074a2ae208SSatish Balay #undef __FUNCT__
24084a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
24090c4c9dddSBarry Smith /*@C
2410758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
2411758f92a0SBarry Smith 
24123f9fe445SBarry Smith    Not Collective
2413758f92a0SBarry Smith 
2414758f92a0SBarry Smith    Input Parameter:
2415758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
2416758f92a0SBarry Smith 
2417758f92a0SBarry Smith    Output Parameters:
2418758f92a0SBarry Smith .  a   - array to hold history
2419758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
2420758f92a0SBarry Smith          negative if not converged) for each solve.
2421758f92a0SBarry Smith -  na  - size of a and its
2422758f92a0SBarry Smith 
2423758f92a0SBarry Smith    Notes:
2424758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
2425758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
2426758f92a0SBarry Smith 
2427758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
2428758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
2429758f92a0SBarry Smith    during the section of code that is being timed.
2430758f92a0SBarry Smith 
2431758f92a0SBarry Smith    Level: intermediate
2432758f92a0SBarry Smith 
2433758f92a0SBarry Smith .keywords: SNES, get, convergence, history
2434758f92a0SBarry Smith 
2435758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
2436758f92a0SBarry Smith 
2437758f92a0SBarry Smith @*/
24387087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
2439758f92a0SBarry Smith {
2440758f92a0SBarry Smith   PetscFunctionBegin;
24410700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2442758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
2443758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
2444758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
24453a40ed3dSBarry Smith   PetscFunctionReturn(0);
2446c9005455SLois Curfman McInnes }
2447c9005455SLois Curfman McInnes 
2448e74ef692SMatthew Knepley #undef __FUNCT__
2449e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
2450ac226902SBarry Smith /*@C
245176b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
2452eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
24537e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
245476b2cf59SMatthew Knepley 
24553f9fe445SBarry Smith   Logically Collective on SNES
245676b2cf59SMatthew Knepley 
245776b2cf59SMatthew Knepley   Input Parameters:
245876b2cf59SMatthew Knepley . snes - The nonlinear solver context
245976b2cf59SMatthew Knepley . func - The function
246076b2cf59SMatthew Knepley 
246176b2cf59SMatthew Knepley   Calling sequence of func:
2462b5d30489SBarry Smith . func (SNES snes, PetscInt step);
246376b2cf59SMatthew Knepley 
246476b2cf59SMatthew Knepley . step - The current step of the iteration
246576b2cf59SMatthew Knepley 
2466fe97e370SBarry Smith   Level: advanced
2467fe97e370SBarry Smith 
2468fe97e370SBarry Smith   Note: This is NOT what one uses to update the ghost points before a function evaluation, that should be done at the beginning of your FormFunction()
2469fe97e370SBarry Smith         This is not used by most users.
247076b2cf59SMatthew Knepley 
247176b2cf59SMatthew Knepley .keywords: SNES, update
2472b5d30489SBarry Smith 
247385385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
247476b2cf59SMatthew Knepley @*/
24757087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
247676b2cf59SMatthew Knepley {
247776b2cf59SMatthew Knepley   PetscFunctionBegin;
24780700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
2479e7788613SBarry Smith   snes->ops->update = func;
248076b2cf59SMatthew Knepley   PetscFunctionReturn(0);
248176b2cf59SMatthew Knepley }
248276b2cf59SMatthew Knepley 
2483e74ef692SMatthew Knepley #undef __FUNCT__
2484e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
248576b2cf59SMatthew Knepley /*@
248676b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
248776b2cf59SMatthew Knepley 
248876b2cf59SMatthew Knepley   Not collective
248976b2cf59SMatthew Knepley 
249076b2cf59SMatthew Knepley   Input Parameters:
249176b2cf59SMatthew Knepley . snes - The nonlinear solver context
249276b2cf59SMatthew Knepley . step - The current step of the iteration
249376b2cf59SMatthew Knepley 
2494205452f4SMatthew Knepley   Level: intermediate
2495205452f4SMatthew Knepley 
249676b2cf59SMatthew Knepley .keywords: SNES, update
2497a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
249876b2cf59SMatthew Knepley @*/
24997087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
250076b2cf59SMatthew Knepley {
250176b2cf59SMatthew Knepley   PetscFunctionBegin;
250276b2cf59SMatthew Knepley   PetscFunctionReturn(0);
250376b2cf59SMatthew Knepley }
250476b2cf59SMatthew Knepley 
25054a2ae208SSatish Balay #undef __FUNCT__
25064a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
25079b94acceSBarry Smith /*
25089b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
25099b94acceSBarry Smith    positive parameter delta.
25109b94acceSBarry Smith 
25119b94acceSBarry Smith     Input Parameters:
2512c7afd0dbSLois Curfman McInnes +   snes - the SNES context
25139b94acceSBarry Smith .   y - approximate solution of linear system
25149b94acceSBarry Smith .   fnorm - 2-norm of current function
2515c7afd0dbSLois Curfman McInnes -   delta - trust region size
25169b94acceSBarry Smith 
25179b94acceSBarry Smith     Output Parameters:
2518c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
25199b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
25209b94acceSBarry Smith     region, and exceeds zero otherwise.
2521c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
25229b94acceSBarry Smith 
25239b94acceSBarry Smith     Note:
25244b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
25259b94acceSBarry Smith     is set to be the maximum allowable step size.
25269b94acceSBarry Smith 
25279b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
25289b94acceSBarry Smith */
2529dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
25309b94acceSBarry Smith {
2531064f8208SBarry Smith   PetscReal      nrm;
2532ea709b57SSatish Balay   PetscScalar    cnorm;
2533dfbe8321SBarry Smith   PetscErrorCode ierr;
25343a40ed3dSBarry Smith 
25353a40ed3dSBarry Smith   PetscFunctionBegin;
25360700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
25370700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
2538c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
2539184914b5SBarry Smith 
2540064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
2541064f8208SBarry Smith   if (nrm > *delta) {
2542064f8208SBarry Smith      nrm = *delta/nrm;
2543064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
2544064f8208SBarry Smith      cnorm = nrm;
25452dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
25469b94acceSBarry Smith      *ynorm = *delta;
25479b94acceSBarry Smith   } else {
25489b94acceSBarry Smith      *gpnorm = 0.0;
2549064f8208SBarry Smith      *ynorm = nrm;
25509b94acceSBarry Smith   }
25513a40ed3dSBarry Smith   PetscFunctionReturn(0);
25529b94acceSBarry Smith }
25539b94acceSBarry Smith 
25544a2ae208SSatish Balay #undef __FUNCT__
25554a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
25566ce558aeSBarry Smith /*@C
2557f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
2558f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
25599b94acceSBarry Smith 
2560c7afd0dbSLois Curfman McInnes    Collective on SNES
2561c7afd0dbSLois Curfman McInnes 
2562b2002411SLois Curfman McInnes    Input Parameters:
2563c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2564f69a0ea3SMatthew Knepley .  b - the constant part of the equation, or PETSC_NULL to use zero.
256585385478SLisandro Dalcin -  x - the solution vector.
25669b94acceSBarry Smith 
2567b2002411SLois Curfman McInnes    Notes:
25688ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
25698ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
25708ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
25718ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
25728ddd3da0SLois Curfman McInnes 
257336851e7fSLois Curfman McInnes    Level: beginner
257436851e7fSLois Curfman McInnes 
25759b94acceSBarry Smith .keywords: SNES, nonlinear, solve
25769b94acceSBarry Smith 
257785385478SLisandro Dalcin .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian()
25789b94acceSBarry Smith @*/
25797087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
25809b94acceSBarry Smith {
2581dfbe8321SBarry Smith   PetscErrorCode ierr;
2582ace3abfcSBarry Smith   PetscBool      flg;
2583eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
2584eabae89aSBarry Smith   PetscViewer    viewer;
2585efd51863SBarry Smith   PetscInt       grid;
2586052efed2SBarry Smith 
25873a40ed3dSBarry Smith   PetscFunctionBegin;
25880700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
25890700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
2590f69a0ea3SMatthew Knepley   PetscCheckSameComm(snes,1,x,3);
25910700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
259285385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
259385385478SLisandro Dalcin 
2594efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
2595efd51863SBarry Smith 
259685385478SLisandro Dalcin     /* set solution vector */
2597efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
25986bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
259985385478SLisandro Dalcin     snes->vec_sol = x;
260085385478SLisandro Dalcin     /* set afine vector if provided */
260185385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
26026bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
260385385478SLisandro Dalcin     snes->vec_rhs = b;
260485385478SLisandro Dalcin 
260570e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
26063f149594SLisandro Dalcin 
2607d25893d9SBarry Smith     if (!grid && snes->ops->computeinitialguess) {
2608d25893d9SBarry Smith       ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
2609d25893d9SBarry Smith     }
2610d25893d9SBarry Smith 
2611abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
261250ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
2613d5e45103SBarry Smith 
26143f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
26154936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
261685385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
26174936397dSBarry Smith     if (snes->domainerror){
26184936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
26194936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
26204936397dSBarry Smith     }
262117186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
26223f149594SLisandro Dalcin 
26237adad957SLisandro Dalcin     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
2624eabae89aSBarry Smith     if (flg && !PetscPreLoadingOn) {
26257adad957SLisandro Dalcin       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
2626eabae89aSBarry Smith       ierr = SNESView(snes,viewer);CHKERRQ(ierr);
26276bf464f9SBarry Smith       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
2628eabae89aSBarry Smith     }
2629eabae89aSBarry Smith 
263090d69ab7SBarry Smith     flg  = PETSC_FALSE;
2631acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
2632da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
26335968eb51SBarry Smith     if (snes->printreason) {
26345968eb51SBarry Smith       if (snes->reason > 0) {
26357adad957SLisandro Dalcin         ierr = PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr);
26365968eb51SBarry Smith       } else {
26377adad957SLisandro Dalcin         ierr = PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr);
26385968eb51SBarry Smith       }
26395968eb51SBarry Smith     }
26405968eb51SBarry Smith 
2641e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
2642efd51863SBarry Smith     if (grid <  snes->gridsequence) {
2643efd51863SBarry Smith       DM  fine;
2644efd51863SBarry Smith       Vec xnew;
2645efd51863SBarry Smith       Mat interp;
2646efd51863SBarry Smith 
2647efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
2648efd51863SBarry Smith       ierr = DMGetInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
2649efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
2650efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
2651efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
2652efd51863SBarry Smith       x    = xnew;
2653efd51863SBarry Smith 
2654efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
2655efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
2656efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
2657efd51863SBarry Smith     }
2658efd51863SBarry Smith   }
26593a40ed3dSBarry Smith   PetscFunctionReturn(0);
26609b94acceSBarry Smith }
26619b94acceSBarry Smith 
26629b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
26639b94acceSBarry Smith 
26644a2ae208SSatish Balay #undef __FUNCT__
26654a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
266682bf6240SBarry Smith /*@C
26674b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
26689b94acceSBarry Smith 
2669fee21e36SBarry Smith    Collective on SNES
2670fee21e36SBarry Smith 
2671c7afd0dbSLois Curfman McInnes    Input Parameters:
2672c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2673454a90a3SBarry Smith -  type - a known method
2674c7afd0dbSLois Curfman McInnes 
2675c7afd0dbSLois Curfman McInnes    Options Database Key:
2676454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
2677c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
2678ae12b187SLois Curfman McInnes 
26799b94acceSBarry Smith    Notes:
2680e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
26814b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
2682c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
26834b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
2684c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
26859b94acceSBarry Smith 
2686ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
2687ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
2688ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
2689ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
2690ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
2691ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
2692ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
2693ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
2694ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
2695b0a32e0cSBarry Smith   appropriate method.
269636851e7fSLois Curfman McInnes 
269736851e7fSLois Curfman McInnes   Level: intermediate
2698a703fe33SLois Curfman McInnes 
2699454a90a3SBarry Smith .keywords: SNES, set, type
2700435da068SBarry Smith 
2701435da068SBarry Smith .seealso: SNESType, SNESCreate()
2702435da068SBarry Smith 
27039b94acceSBarry Smith @*/
27047087cfbeSBarry Smith PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
27059b94acceSBarry Smith {
2706dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
2707ace3abfcSBarry Smith   PetscBool      match;
27083a40ed3dSBarry Smith 
27093a40ed3dSBarry Smith   PetscFunctionBegin;
27100700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
27114482741eSBarry Smith   PetscValidCharPointer(type,2);
271282bf6240SBarry Smith 
27136831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
27140f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
271592ff6ae8SBarry Smith 
27164b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
2717e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
271875396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
271975396ef9SLisandro Dalcin   if (snes->ops->destroy) { ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); }
272075396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
272175396ef9SLisandro Dalcin   snes->ops->setup          = 0;
272275396ef9SLisandro Dalcin   snes->ops->solve          = 0;
272375396ef9SLisandro Dalcin   snes->ops->view           = 0;
272475396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
272575396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
272675396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
272775396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
2728454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
272903bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
27309fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
27319fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
27329fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
27339fb22e1aSBarry Smith   }
27349fb22e1aSBarry Smith #endif
27353a40ed3dSBarry Smith   PetscFunctionReturn(0);
27369b94acceSBarry Smith }
27379b94acceSBarry Smith 
2738a847f771SSatish Balay 
27399b94acceSBarry Smith /* --------------------------------------------------------------------- */
27404a2ae208SSatish Balay #undef __FUNCT__
27414a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
274252baeb72SSatish Balay /*@
27439b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
2744f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
27459b94acceSBarry Smith 
2746fee21e36SBarry Smith    Not Collective
2747fee21e36SBarry Smith 
274836851e7fSLois Curfman McInnes    Level: advanced
274936851e7fSLois Curfman McInnes 
27509b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
27519b94acceSBarry Smith 
27529b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
27539b94acceSBarry Smith @*/
27547087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
27559b94acceSBarry Smith {
2756dfbe8321SBarry Smith   PetscErrorCode ierr;
275782bf6240SBarry Smith 
27583a40ed3dSBarry Smith   PetscFunctionBegin;
27591441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
27604c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
27613a40ed3dSBarry Smith   PetscFunctionReturn(0);
27629b94acceSBarry Smith }
27639b94acceSBarry Smith 
27644a2ae208SSatish Balay #undef __FUNCT__
27654a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
27669b94acceSBarry Smith /*@C
27679a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
27689b94acceSBarry Smith 
2769c7afd0dbSLois Curfman McInnes    Not Collective
2770c7afd0dbSLois Curfman McInnes 
27719b94acceSBarry Smith    Input Parameter:
27724b0e389bSBarry Smith .  snes - nonlinear solver context
27739b94acceSBarry Smith 
27749b94acceSBarry Smith    Output Parameter:
27753a7fca6bSBarry Smith .  type - SNES method (a character string)
27769b94acceSBarry Smith 
277736851e7fSLois Curfman McInnes    Level: intermediate
277836851e7fSLois Curfman McInnes 
2779454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
27809b94acceSBarry Smith @*/
27817087cfbeSBarry Smith PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
27829b94acceSBarry Smith {
27833a40ed3dSBarry Smith   PetscFunctionBegin;
27840700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
27854482741eSBarry Smith   PetscValidPointer(type,2);
27867adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
27873a40ed3dSBarry Smith   PetscFunctionReturn(0);
27889b94acceSBarry Smith }
27899b94acceSBarry Smith 
27904a2ae208SSatish Balay #undef __FUNCT__
27914a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
279252baeb72SSatish Balay /*@
27939b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
27949b94acceSBarry Smith    stored.
27959b94acceSBarry Smith 
2796c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
2797c7afd0dbSLois Curfman McInnes 
27989b94acceSBarry Smith    Input Parameter:
27999b94acceSBarry Smith .  snes - the SNES context
28009b94acceSBarry Smith 
28019b94acceSBarry Smith    Output Parameter:
28029b94acceSBarry Smith .  x - the solution
28039b94acceSBarry Smith 
280470e92668SMatthew Knepley    Level: intermediate
280536851e7fSLois Curfman McInnes 
28069b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
28079b94acceSBarry Smith 
280885385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
28099b94acceSBarry Smith @*/
28107087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
28119b94acceSBarry Smith {
28123a40ed3dSBarry Smith   PetscFunctionBegin;
28130700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
28144482741eSBarry Smith   PetscValidPointer(x,2);
281585385478SLisandro Dalcin   *x = snes->vec_sol;
281670e92668SMatthew Knepley   PetscFunctionReturn(0);
281770e92668SMatthew Knepley }
281870e92668SMatthew Knepley 
281970e92668SMatthew Knepley #undef __FUNCT__
28204a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
282152baeb72SSatish Balay /*@
28229b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
28239b94acceSBarry Smith    stored.
28249b94acceSBarry Smith 
2825c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
2826c7afd0dbSLois Curfman McInnes 
28279b94acceSBarry Smith    Input Parameter:
28289b94acceSBarry Smith .  snes - the SNES context
28299b94acceSBarry Smith 
28309b94acceSBarry Smith    Output Parameter:
28319b94acceSBarry Smith .  x - the solution update
28329b94acceSBarry Smith 
283336851e7fSLois Curfman McInnes    Level: advanced
283436851e7fSLois Curfman McInnes 
28359b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
28369b94acceSBarry Smith 
283785385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
28389b94acceSBarry Smith @*/
28397087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
28409b94acceSBarry Smith {
28413a40ed3dSBarry Smith   PetscFunctionBegin;
28420700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
28434482741eSBarry Smith   PetscValidPointer(x,2);
284485385478SLisandro Dalcin   *x = snes->vec_sol_update;
28453a40ed3dSBarry Smith   PetscFunctionReturn(0);
28469b94acceSBarry Smith }
28479b94acceSBarry Smith 
28484a2ae208SSatish Balay #undef __FUNCT__
28494a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
28509b94acceSBarry Smith /*@C
28513638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
28529b94acceSBarry Smith 
2853c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
2854c7afd0dbSLois Curfman McInnes 
28559b94acceSBarry Smith    Input Parameter:
28569b94acceSBarry Smith .  snes - the SNES context
28579b94acceSBarry Smith 
28589b94acceSBarry Smith    Output Parameter:
28597bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
286070e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
286170e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
28629b94acceSBarry Smith 
286336851e7fSLois Curfman McInnes    Level: advanced
286436851e7fSLois Curfman McInnes 
2865a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
28669b94acceSBarry Smith 
28674b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
28689b94acceSBarry Smith @*/
28697087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
28709b94acceSBarry Smith {
28713a40ed3dSBarry Smith   PetscFunctionBegin;
28720700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
287385385478SLisandro Dalcin   if (r)    *r    = snes->vec_func;
2874e7788613SBarry Smith   if (func) *func = snes->ops->computefunction;
287570e92668SMatthew Knepley   if (ctx)  *ctx  = snes->funP;
28763a40ed3dSBarry Smith   PetscFunctionReturn(0);
28779b94acceSBarry Smith }
28789b94acceSBarry Smith 
28794a2ae208SSatish Balay #undef __FUNCT__
28804a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
28813c7409f5SSatish Balay /*@C
28823c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
2883d850072dSLois Curfman McInnes    SNES options in the database.
28843c7409f5SSatish Balay 
28853f9fe445SBarry Smith    Logically Collective on SNES
2886fee21e36SBarry Smith 
2887c7afd0dbSLois Curfman McInnes    Input Parameter:
2888c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2889c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
2890c7afd0dbSLois Curfman McInnes 
2891d850072dSLois Curfman McInnes    Notes:
2892a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
2893c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
2894d850072dSLois Curfman McInnes 
289536851e7fSLois Curfman McInnes    Level: advanced
289636851e7fSLois Curfman McInnes 
28973c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
2898a86d99e1SLois Curfman McInnes 
2899a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
29003c7409f5SSatish Balay @*/
29017087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
29023c7409f5SSatish Balay {
2903dfbe8321SBarry Smith   PetscErrorCode ierr;
29043c7409f5SSatish Balay 
29053a40ed3dSBarry Smith   PetscFunctionBegin;
29060700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2907639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
29081cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
290994b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
29103a40ed3dSBarry Smith   PetscFunctionReturn(0);
29113c7409f5SSatish Balay }
29123c7409f5SSatish Balay 
29134a2ae208SSatish Balay #undef __FUNCT__
29144a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
29153c7409f5SSatish Balay /*@C
2916f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
2917d850072dSLois Curfman McInnes    SNES options in the database.
29183c7409f5SSatish Balay 
29193f9fe445SBarry Smith    Logically Collective on SNES
2920fee21e36SBarry Smith 
2921c7afd0dbSLois Curfman McInnes    Input Parameters:
2922c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2923c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
2924c7afd0dbSLois Curfman McInnes 
2925d850072dSLois Curfman McInnes    Notes:
2926a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
2927c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
2928d850072dSLois Curfman McInnes 
292936851e7fSLois Curfman McInnes    Level: advanced
293036851e7fSLois Curfman McInnes 
29313c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
2932a86d99e1SLois Curfman McInnes 
2933a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
29343c7409f5SSatish Balay @*/
29357087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
29363c7409f5SSatish Balay {
2937dfbe8321SBarry Smith   PetscErrorCode ierr;
29383c7409f5SSatish Balay 
29393a40ed3dSBarry Smith   PetscFunctionBegin;
29400700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2941639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
29421cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
294394b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
29443a40ed3dSBarry Smith   PetscFunctionReturn(0);
29453c7409f5SSatish Balay }
29463c7409f5SSatish Balay 
29474a2ae208SSatish Balay #undef __FUNCT__
29484a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
29499ab63eb5SSatish Balay /*@C
29503c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
29513c7409f5SSatish Balay    SNES options in the database.
29523c7409f5SSatish Balay 
2953c7afd0dbSLois Curfman McInnes    Not Collective
2954c7afd0dbSLois Curfman McInnes 
29553c7409f5SSatish Balay    Input Parameter:
29563c7409f5SSatish Balay .  snes - the SNES context
29573c7409f5SSatish Balay 
29583c7409f5SSatish Balay    Output Parameter:
29593c7409f5SSatish Balay .  prefix - pointer to the prefix string used
29603c7409f5SSatish Balay 
29614ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
29629ab63eb5SSatish Balay    sufficient length to hold the prefix.
29639ab63eb5SSatish Balay 
296436851e7fSLois Curfman McInnes    Level: advanced
296536851e7fSLois Curfman McInnes 
29663c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
2967a86d99e1SLois Curfman McInnes 
2968a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
29693c7409f5SSatish Balay @*/
29707087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
29713c7409f5SSatish Balay {
2972dfbe8321SBarry Smith   PetscErrorCode ierr;
29733c7409f5SSatish Balay 
29743a40ed3dSBarry Smith   PetscFunctionBegin;
29750700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2976639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
29773a40ed3dSBarry Smith   PetscFunctionReturn(0);
29783c7409f5SSatish Balay }
29793c7409f5SSatish Balay 
2980b2002411SLois Curfman McInnes 
29814a2ae208SSatish Balay #undef __FUNCT__
29824a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
29833cea93caSBarry Smith /*@C
29843cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
29853cea93caSBarry Smith 
29867f6c08e0SMatthew Knepley   Level: advanced
29873cea93caSBarry Smith @*/
29887087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
2989b2002411SLois Curfman McInnes {
2990e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
2991dfbe8321SBarry Smith   PetscErrorCode ierr;
2992b2002411SLois Curfman McInnes 
2993b2002411SLois Curfman McInnes   PetscFunctionBegin;
2994b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
2995c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
2996b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
2997b2002411SLois Curfman McInnes }
2998da9b6338SBarry Smith 
2999da9b6338SBarry Smith #undef __FUNCT__
3000da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
30017087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
3002da9b6338SBarry Smith {
3003dfbe8321SBarry Smith   PetscErrorCode ierr;
300477431f27SBarry Smith   PetscInt       N,i,j;
3005da9b6338SBarry Smith   Vec            u,uh,fh;
3006da9b6338SBarry Smith   PetscScalar    value;
3007da9b6338SBarry Smith   PetscReal      norm;
3008da9b6338SBarry Smith 
3009da9b6338SBarry Smith   PetscFunctionBegin;
3010da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
3011da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
3012da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
3013da9b6338SBarry Smith 
3014da9b6338SBarry Smith   /* currently only works for sequential */
3015da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
3016da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
3017da9b6338SBarry Smith   for (i=0; i<N; i++) {
3018da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
301977431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
3020da9b6338SBarry Smith     for (j=-10; j<11; j++) {
3021ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
3022da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
30233ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
3024da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
302577431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
3026da9b6338SBarry Smith       value = -value;
3027da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
3028da9b6338SBarry Smith     }
3029da9b6338SBarry Smith   }
30306bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
30316bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
3032da9b6338SBarry Smith   PetscFunctionReturn(0);
3033da9b6338SBarry Smith }
303471f87433Sdalcinl 
303571f87433Sdalcinl #undef __FUNCT__
3036fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
303771f87433Sdalcinl /*@
3038fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
303971f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
304071f87433Sdalcinl    Newton method.
304171f87433Sdalcinl 
30423f9fe445SBarry Smith    Logically Collective on SNES
304371f87433Sdalcinl 
304471f87433Sdalcinl    Input Parameters:
304571f87433Sdalcinl +  snes - SNES context
304671f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
304771f87433Sdalcinl 
304864ba62caSBarry Smith     Options Database:
304964ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
305064ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
305164ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
305264ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
305364ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
305464ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
305564ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
305664ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
305764ba62caSBarry Smith 
305871f87433Sdalcinl    Notes:
305971f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
306071f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
306171f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
306271f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
306371f87433Sdalcinl    solver.
306471f87433Sdalcinl 
306571f87433Sdalcinl    Level: advanced
306671f87433Sdalcinl 
306771f87433Sdalcinl    Reference:
306871f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
306971f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
307071f87433Sdalcinl 
307171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
307271f87433Sdalcinl 
3073fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
307471f87433Sdalcinl @*/
30757087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
307671f87433Sdalcinl {
307771f87433Sdalcinl   PetscFunctionBegin;
30780700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3079acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
308071f87433Sdalcinl   snes->ksp_ewconv = flag;
308171f87433Sdalcinl   PetscFunctionReturn(0);
308271f87433Sdalcinl }
308371f87433Sdalcinl 
308471f87433Sdalcinl #undef __FUNCT__
3085fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
308671f87433Sdalcinl /*@
3087fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
308871f87433Sdalcinl    for computing relative tolerance for linear solvers within an
308971f87433Sdalcinl    inexact Newton method.
309071f87433Sdalcinl 
309171f87433Sdalcinl    Not Collective
309271f87433Sdalcinl 
309371f87433Sdalcinl    Input Parameter:
309471f87433Sdalcinl .  snes - SNES context
309571f87433Sdalcinl 
309671f87433Sdalcinl    Output Parameter:
309771f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
309871f87433Sdalcinl 
309971f87433Sdalcinl    Notes:
310071f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
310171f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
310271f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
310371f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
310471f87433Sdalcinl    solver.
310571f87433Sdalcinl 
310671f87433Sdalcinl    Level: advanced
310771f87433Sdalcinl 
310871f87433Sdalcinl    Reference:
310971f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
311071f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
311171f87433Sdalcinl 
311271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
311371f87433Sdalcinl 
3114fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
311571f87433Sdalcinl @*/
31167087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
311771f87433Sdalcinl {
311871f87433Sdalcinl   PetscFunctionBegin;
31190700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
312071f87433Sdalcinl   PetscValidPointer(flag,2);
312171f87433Sdalcinl   *flag = snes->ksp_ewconv;
312271f87433Sdalcinl   PetscFunctionReturn(0);
312371f87433Sdalcinl }
312471f87433Sdalcinl 
312571f87433Sdalcinl #undef __FUNCT__
3126fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
312771f87433Sdalcinl /*@
3128fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
312971f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
313071f87433Sdalcinl    Newton method.
313171f87433Sdalcinl 
31323f9fe445SBarry Smith    Logically Collective on SNES
313371f87433Sdalcinl 
313471f87433Sdalcinl    Input Parameters:
313571f87433Sdalcinl +    snes - SNES context
313671f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
313771f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
313871f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
313971f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
314071f87433Sdalcinl              (0 <= gamma2 <= 1)
314171f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
314271f87433Sdalcinl .    alpha2 - power for safeguard
314371f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
314471f87433Sdalcinl 
314571f87433Sdalcinl    Note:
314671f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
314771f87433Sdalcinl 
314871f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
314971f87433Sdalcinl 
315071f87433Sdalcinl    Level: advanced
315171f87433Sdalcinl 
315271f87433Sdalcinl    Reference:
315371f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
315471f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
315571f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
315671f87433Sdalcinl 
315771f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
315871f87433Sdalcinl 
3159fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
316071f87433Sdalcinl @*/
31617087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
316271f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
316371f87433Sdalcinl {
3164fa9f3622SBarry Smith   SNESKSPEW *kctx;
316571f87433Sdalcinl   PetscFunctionBegin;
31660700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3167fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3168e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
3169c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
3170c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
3171c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
3172c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
3173c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
3174c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
3175c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
317671f87433Sdalcinl 
317771f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
317871f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
317971f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
318071f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
318171f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
318271f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
318371f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
318471f87433Sdalcinl 
318571f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
3186e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
318771f87433Sdalcinl   }
318871f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
3189e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
319071f87433Sdalcinl   }
319171f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
3192e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
319371f87433Sdalcinl   }
319471f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
3195e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
319671f87433Sdalcinl   }
319771f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
3198e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
319971f87433Sdalcinl   }
320071f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
3201e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
320271f87433Sdalcinl   }
320371f87433Sdalcinl   PetscFunctionReturn(0);
320471f87433Sdalcinl }
320571f87433Sdalcinl 
320671f87433Sdalcinl #undef __FUNCT__
3207fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
320871f87433Sdalcinl /*@
3209fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
321071f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
321171f87433Sdalcinl    Newton method.
321271f87433Sdalcinl 
321371f87433Sdalcinl    Not Collective
321471f87433Sdalcinl 
321571f87433Sdalcinl    Input Parameters:
321671f87433Sdalcinl      snes - SNES context
321771f87433Sdalcinl 
321871f87433Sdalcinl    Output Parameters:
321971f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
322071f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
322171f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
322271f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
322371f87433Sdalcinl              (0 <= gamma2 <= 1)
322471f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
322571f87433Sdalcinl .    alpha2 - power for safeguard
322671f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
322771f87433Sdalcinl 
322871f87433Sdalcinl    Level: advanced
322971f87433Sdalcinl 
323071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
323171f87433Sdalcinl 
3232fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
323371f87433Sdalcinl @*/
32347087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
323571f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
323671f87433Sdalcinl {
3237fa9f3622SBarry Smith   SNESKSPEW *kctx;
323871f87433Sdalcinl   PetscFunctionBegin;
32390700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3240fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3241e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
324271f87433Sdalcinl   if(version)   *version   = kctx->version;
324371f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
324471f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
324571f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
324671f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
324771f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
324871f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
324971f87433Sdalcinl   PetscFunctionReturn(0);
325071f87433Sdalcinl }
325171f87433Sdalcinl 
325271f87433Sdalcinl #undef __FUNCT__
3253fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
3254fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
325571f87433Sdalcinl {
325671f87433Sdalcinl   PetscErrorCode ierr;
3257fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
325871f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
325971f87433Sdalcinl 
326071f87433Sdalcinl   PetscFunctionBegin;
3261e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
326271f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
326371f87433Sdalcinl     rtol = kctx->rtol_0;
326471f87433Sdalcinl   } else {
326571f87433Sdalcinl     if (kctx->version == 1) {
326671f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
326771f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
326871f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
326971f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
327071f87433Sdalcinl     } else if (kctx->version == 2) {
327171f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
327271f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
327371f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
327471f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
327571f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
327671f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
327771f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
327871f87433Sdalcinl       stol = PetscMax(rtol,stol);
327971f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
328071f87433Sdalcinl       /* safeguard: avoid oversolving */
328171f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
328271f87433Sdalcinl       stol = PetscMax(rtol,stol);
328371f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
3284e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
328571f87433Sdalcinl   }
328671f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
328771f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
328871f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
328971f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
329071f87433Sdalcinl   PetscFunctionReturn(0);
329171f87433Sdalcinl }
329271f87433Sdalcinl 
329371f87433Sdalcinl #undef __FUNCT__
3294fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
3295fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
329671f87433Sdalcinl {
329771f87433Sdalcinl   PetscErrorCode ierr;
3298fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
329971f87433Sdalcinl   PCSide         pcside;
330071f87433Sdalcinl   Vec            lres;
330171f87433Sdalcinl 
330271f87433Sdalcinl   PetscFunctionBegin;
3303e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
330471f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
330571f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
330671f87433Sdalcinl   if (kctx->version == 1) {
3307b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
330871f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
330971f87433Sdalcinl       /* KSP residual is true linear residual */
331071f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
331171f87433Sdalcinl     } else {
331271f87433Sdalcinl       /* KSP residual is preconditioned residual */
331371f87433Sdalcinl       /* compute true linear residual norm */
331471f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
331571f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
331671f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
331771f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
33186bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
331971f87433Sdalcinl     }
332071f87433Sdalcinl   }
332171f87433Sdalcinl   PetscFunctionReturn(0);
332271f87433Sdalcinl }
332371f87433Sdalcinl 
332471f87433Sdalcinl #undef __FUNCT__
332571f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
332671f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
332771f87433Sdalcinl {
332871f87433Sdalcinl   PetscErrorCode ierr;
332971f87433Sdalcinl 
333071f87433Sdalcinl   PetscFunctionBegin;
3331fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
333271f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
3333fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
333471f87433Sdalcinl   PetscFunctionReturn(0);
333571f87433Sdalcinl }
33366c699258SBarry Smith 
33376c699258SBarry Smith #undef __FUNCT__
33386c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
33396c699258SBarry Smith /*@
33406c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
33416c699258SBarry Smith 
33423f9fe445SBarry Smith    Logically Collective on SNES
33436c699258SBarry Smith 
33446c699258SBarry Smith    Input Parameters:
33456c699258SBarry Smith +  snes - the preconditioner context
33466c699258SBarry Smith -  dm - the dm
33476c699258SBarry Smith 
33486c699258SBarry Smith    Level: intermediate
33496c699258SBarry Smith 
33506c699258SBarry Smith 
33516c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
33526c699258SBarry Smith @*/
33537087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
33546c699258SBarry Smith {
33556c699258SBarry Smith   PetscErrorCode ierr;
3356345fed2cSBarry Smith   KSP            ksp;
33576c699258SBarry Smith 
33586c699258SBarry Smith   PetscFunctionBegin;
33590700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3360d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
33616bf464f9SBarry Smith   ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
33626c699258SBarry Smith   snes->dm = dm;
3363345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
3364345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
3365f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
33666c699258SBarry Smith   PetscFunctionReturn(0);
33676c699258SBarry Smith }
33686c699258SBarry Smith 
33696c699258SBarry Smith #undef __FUNCT__
33706c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
33716c699258SBarry Smith /*@
33726c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
33736c699258SBarry Smith 
33743f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
33756c699258SBarry Smith 
33766c699258SBarry Smith    Input Parameter:
33776c699258SBarry Smith . snes - the preconditioner context
33786c699258SBarry Smith 
33796c699258SBarry Smith    Output Parameter:
33806c699258SBarry Smith .  dm - the dm
33816c699258SBarry Smith 
33826c699258SBarry Smith    Level: intermediate
33836c699258SBarry Smith 
33846c699258SBarry Smith 
33856c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
33866c699258SBarry Smith @*/
33877087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
33886c699258SBarry Smith {
33896c699258SBarry Smith   PetscFunctionBegin;
33900700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
33916c699258SBarry Smith   *dm = snes->dm;
33926c699258SBarry Smith   PetscFunctionReturn(0);
33936c699258SBarry Smith }
33940807856dSBarry Smith 
3395*31823bd8SMatthew G Knepley #undef __FUNCT__
3396*31823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
3397*31823bd8SMatthew G Knepley /*@
3398*31823bd8SMatthew G Knepley   SNESSetPC - Sets the preconditioner to be used.
3399*31823bd8SMatthew G Knepley 
3400*31823bd8SMatthew G Knepley   Collective on SNES
3401*31823bd8SMatthew G Knepley 
3402*31823bd8SMatthew G Knepley   Input Parameters:
3403*31823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
3404*31823bd8SMatthew G Knepley - pc   - the preconditioner object
3405*31823bd8SMatthew G Knepley 
3406*31823bd8SMatthew G Knepley   Notes:
3407*31823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
3408*31823bd8SMatthew G Knepley   to configure it using the API).
3409*31823bd8SMatthew G Knepley 
3410*31823bd8SMatthew G Knepley   Level: developer
3411*31823bd8SMatthew G Knepley 
3412*31823bd8SMatthew G Knepley .keywords: SNES, set, precondition
3413*31823bd8SMatthew G Knepley .seealso: SNESGetPC()
3414*31823bd8SMatthew G Knepley @*/
3415*31823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
3416*31823bd8SMatthew G Knepley {
3417*31823bd8SMatthew G Knepley   PetscErrorCode ierr;
3418*31823bd8SMatthew G Knepley 
3419*31823bd8SMatthew G Knepley   PetscFunctionBegin;
3420*31823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3421*31823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
3422*31823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
3423*31823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
3424*31823bd8SMatthew G Knepley   ierr = PCDestroy(&snes->pc);CHKERRQ(ierr);
3425*31823bd8SMatthew G Knepley   snes->pc = pc;
3426*31823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
3427*31823bd8SMatthew G Knepley   PetscFunctionReturn(0);
3428*31823bd8SMatthew G Knepley }
3429*31823bd8SMatthew G Knepley 
3430*31823bd8SMatthew G Knepley #undef __FUNCT__
3431*31823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
3432*31823bd8SMatthew G Knepley /*@
3433*31823bd8SMatthew G Knepley   SNESGetPC - Returns a pointer to the preconditioner context set with SNESSetPC().
3434*31823bd8SMatthew G Knepley 
3435*31823bd8SMatthew G Knepley   Not Collective
3436*31823bd8SMatthew G Knepley 
3437*31823bd8SMatthew G Knepley   Input Parameter:
3438*31823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
3439*31823bd8SMatthew G Knepley 
3440*31823bd8SMatthew G Knepley   Output Parameter:
3441*31823bd8SMatthew G Knepley . pc - preconditioner context
3442*31823bd8SMatthew G Knepley 
3443*31823bd8SMatthew G Knepley   Level: developer
3444*31823bd8SMatthew G Knepley 
3445*31823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
3446*31823bd8SMatthew G Knepley .seealso: SNESSetPC()
3447*31823bd8SMatthew G Knepley @*/
3448*31823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
3449*31823bd8SMatthew G Knepley {
3450*31823bd8SMatthew G Knepley   PetscErrorCode ierr;
3451*31823bd8SMatthew G Knepley 
3452*31823bd8SMatthew G Knepley   PetscFunctionBegin;
3453*31823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3454*31823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
3455*31823bd8SMatthew G Knepley   if (!snes->pc) {
3456*31823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr);
3457*31823bd8SMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 0);CHKERRQ(ierr);
3458*31823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
3459*31823bd8SMatthew G Knepley   }
3460*31823bd8SMatthew G Knepley   *pc = snes->pc;
3461*31823bd8SMatthew G Knepley   PetscFunctionReturn(0);
3462*31823bd8SMatthew G Knepley }
3463*31823bd8SMatthew G Knepley 
346469b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3465c6db04a5SJed Brown #include <mex.h>
346669b4f73cSBarry Smith 
34678f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
34688f6e6473SBarry Smith 
34690807856dSBarry Smith #undef __FUNCT__
34700807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
34710807856dSBarry Smith /*
34720807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
34730807856dSBarry Smith                          SNESSetFunctionMatlab().
34740807856dSBarry Smith 
34750807856dSBarry Smith    Collective on SNES
34760807856dSBarry Smith 
34770807856dSBarry Smith    Input Parameters:
34780807856dSBarry Smith +  snes - the SNES context
34790807856dSBarry Smith -  x - input vector
34800807856dSBarry Smith 
34810807856dSBarry Smith    Output Parameter:
34820807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
34830807856dSBarry Smith 
34840807856dSBarry Smith    Notes:
34850807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
34860807856dSBarry Smith    implementations, so most users would not generally call this routine
34870807856dSBarry Smith    themselves.
34880807856dSBarry Smith 
34890807856dSBarry Smith    Level: developer
34900807856dSBarry Smith 
34910807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
34920807856dSBarry Smith 
34930807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
349461b2408cSBarry Smith */
34957087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
34960807856dSBarry Smith {
3497e650e774SBarry Smith   PetscErrorCode    ierr;
34988f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
34998f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
35008f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
350191621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
3502e650e774SBarry Smith 
35030807856dSBarry Smith   PetscFunctionBegin;
35040807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35050807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
35060807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
35070807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
35080807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
35090807856dSBarry Smith 
35100807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
3511e650e774SBarry Smith 
351291621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
3513e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
3514e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
351591621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
351691621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
351791621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
35188f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
35198f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
3520b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
3521e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
3522e650e774SBarry Smith   mxDestroyArray(prhs[0]);
3523e650e774SBarry Smith   mxDestroyArray(prhs[1]);
3524e650e774SBarry Smith   mxDestroyArray(prhs[2]);
35258f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
3526e650e774SBarry Smith   mxDestroyArray(plhs[0]);
35270807856dSBarry Smith   PetscFunctionReturn(0);
35280807856dSBarry Smith }
35290807856dSBarry Smith 
35300807856dSBarry Smith 
35310807856dSBarry Smith #undef __FUNCT__
35320807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
353361b2408cSBarry Smith /*
35340807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
35350807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
3536e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
35370807856dSBarry Smith 
35380807856dSBarry Smith    Logically Collective on SNES
35390807856dSBarry Smith 
35400807856dSBarry Smith    Input Parameters:
35410807856dSBarry Smith +  snes - the SNES context
35420807856dSBarry Smith .  r - vector to store function value
35430807856dSBarry Smith -  func - function evaluation routine
35440807856dSBarry Smith 
35450807856dSBarry Smith    Calling sequence of func:
354661b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
35470807856dSBarry Smith 
35480807856dSBarry Smith 
35490807856dSBarry Smith    Notes:
35500807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
35510807856dSBarry Smith $      f'(x) x = -f(x),
35520807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
35530807856dSBarry Smith 
35540807856dSBarry Smith    Level: beginner
35550807856dSBarry Smith 
35560807856dSBarry Smith .keywords: SNES, nonlinear, set, function
35570807856dSBarry Smith 
35580807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
355961b2408cSBarry Smith */
35607087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
35610807856dSBarry Smith {
35620807856dSBarry Smith   PetscErrorCode    ierr;
35638f6e6473SBarry Smith   SNESMatlabContext *sctx;
35640807856dSBarry Smith 
35650807856dSBarry Smith   PetscFunctionBegin;
35668f6e6473SBarry Smith   /* currently sctx is memory bleed */
35678f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
35688f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
35698f6e6473SBarry Smith   /*
35708f6e6473SBarry Smith      This should work, but it doesn't
35718f6e6473SBarry Smith   sctx->ctx = ctx;
35728f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
35738f6e6473SBarry Smith   */
35748f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
35758f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
35760807856dSBarry Smith   PetscFunctionReturn(0);
35770807856dSBarry Smith }
357869b4f73cSBarry Smith 
357961b2408cSBarry Smith #undef __FUNCT__
358061b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
358161b2408cSBarry Smith /*
358261b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
358361b2408cSBarry Smith                          SNESSetJacobianMatlab().
358461b2408cSBarry Smith 
358561b2408cSBarry Smith    Collective on SNES
358661b2408cSBarry Smith 
358761b2408cSBarry Smith    Input Parameters:
358861b2408cSBarry Smith +  snes - the SNES context
358961b2408cSBarry Smith .  x - input vector
359061b2408cSBarry Smith .  A, B - the matrices
359161b2408cSBarry Smith -  ctx - user context
359261b2408cSBarry Smith 
359361b2408cSBarry Smith    Output Parameter:
359461b2408cSBarry Smith .  flag - structure of the matrix
359561b2408cSBarry Smith 
359661b2408cSBarry Smith    Level: developer
359761b2408cSBarry Smith 
359861b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
359961b2408cSBarry Smith 
360061b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
360161b2408cSBarry Smith @*/
36027087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
360361b2408cSBarry Smith {
360461b2408cSBarry Smith   PetscErrorCode    ierr;
360561b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
360661b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
360761b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
360861b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
360961b2408cSBarry Smith 
361061b2408cSBarry Smith   PetscFunctionBegin;
361161b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
361261b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
361361b2408cSBarry Smith 
361461b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
361561b2408cSBarry Smith 
361661b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
361761b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
361861b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
361961b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
362061b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
362161b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
362261b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
362361b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
362461b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
362561b2408cSBarry Smith   prhs[5] =  sctx->ctx;
3626b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
362761b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
362861b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
362961b2408cSBarry Smith   mxDestroyArray(prhs[0]);
363061b2408cSBarry Smith   mxDestroyArray(prhs[1]);
363161b2408cSBarry Smith   mxDestroyArray(prhs[2]);
363261b2408cSBarry Smith   mxDestroyArray(prhs[3]);
363361b2408cSBarry Smith   mxDestroyArray(prhs[4]);
363461b2408cSBarry Smith   mxDestroyArray(plhs[0]);
363561b2408cSBarry Smith   mxDestroyArray(plhs[1]);
363661b2408cSBarry Smith   PetscFunctionReturn(0);
363761b2408cSBarry Smith }
363861b2408cSBarry Smith 
363961b2408cSBarry Smith 
364061b2408cSBarry Smith #undef __FUNCT__
364161b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
364261b2408cSBarry Smith /*
364361b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
364461b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
3645e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
364661b2408cSBarry Smith 
364761b2408cSBarry Smith    Logically Collective on SNES
364861b2408cSBarry Smith 
364961b2408cSBarry Smith    Input Parameters:
365061b2408cSBarry Smith +  snes - the SNES context
365161b2408cSBarry Smith .  A,B - Jacobian matrices
365261b2408cSBarry Smith .  func - function evaluation routine
365361b2408cSBarry Smith -  ctx - user context
365461b2408cSBarry Smith 
365561b2408cSBarry Smith    Calling sequence of func:
365661b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
365761b2408cSBarry Smith 
365861b2408cSBarry Smith 
365961b2408cSBarry Smith    Level: developer
366061b2408cSBarry Smith 
366161b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
366261b2408cSBarry Smith 
366361b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
366461b2408cSBarry Smith */
36657087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
366661b2408cSBarry Smith {
366761b2408cSBarry Smith   PetscErrorCode    ierr;
366861b2408cSBarry Smith   SNESMatlabContext *sctx;
366961b2408cSBarry Smith 
367061b2408cSBarry Smith   PetscFunctionBegin;
367161b2408cSBarry Smith   /* currently sctx is memory bleed */
367261b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
367361b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
367461b2408cSBarry Smith   /*
367561b2408cSBarry Smith      This should work, but it doesn't
367661b2408cSBarry Smith   sctx->ctx = ctx;
367761b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
367861b2408cSBarry Smith   */
367961b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
368061b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
368161b2408cSBarry Smith   PetscFunctionReturn(0);
368261b2408cSBarry Smith }
368369b4f73cSBarry Smith 
3684f9eb7ae2SShri Abhyankar #undef __FUNCT__
3685f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
3686f9eb7ae2SShri Abhyankar /*
3687f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
3688f9eb7ae2SShri Abhyankar 
3689f9eb7ae2SShri Abhyankar    Collective on SNES
3690f9eb7ae2SShri Abhyankar 
3691f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
3692f9eb7ae2SShri Abhyankar @*/
36937087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
3694f9eb7ae2SShri Abhyankar {
3695f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
369648f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
3697f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
3698f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
3699f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
3700f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
3701f9eb7ae2SShri Abhyankar 
3702f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
3703f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3704f9eb7ae2SShri Abhyankar 
3705f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
3706f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
3707f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
3708f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
3709f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
3710f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
3711f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
3712f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
3713f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
3714f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
3715f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
3716f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
3717f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
3718f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
3719f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
3720f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
3721f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
3722f9eb7ae2SShri Abhyankar }
3723f9eb7ae2SShri Abhyankar 
3724f9eb7ae2SShri Abhyankar 
3725f9eb7ae2SShri Abhyankar #undef __FUNCT__
3726f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
3727f9eb7ae2SShri Abhyankar /*
3728e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
3729f9eb7ae2SShri Abhyankar 
3730f9eb7ae2SShri Abhyankar    Level: developer
3731f9eb7ae2SShri Abhyankar 
3732f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
3733f9eb7ae2SShri Abhyankar 
3734f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
3735f9eb7ae2SShri Abhyankar */
37367087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
3737f9eb7ae2SShri Abhyankar {
3738f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
3739f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
3740f9eb7ae2SShri Abhyankar 
3741f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
3742f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
3743f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
3744f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
3745f9eb7ae2SShri Abhyankar   /*
3746f9eb7ae2SShri Abhyankar      This should work, but it doesn't
3747f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
3748f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
3749f9eb7ae2SShri Abhyankar   */
3750f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
3751f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
3752f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
3753f9eb7ae2SShri Abhyankar }
3754f9eb7ae2SShri Abhyankar 
375569b4f73cSBarry Smith #endif
3756