xref: /petsc/src/snes/interface/snes.c (revision 3cbb28f5ba2ee165d8cc2325b975768eb2ce2de7)
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
266a8248277SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
267aa3661deSLisandro Dalcin 
268aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
269d3462f78SMatthew Knepley   if (hasOperator) {
270aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
271aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
272aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
273aa3661deSLisandro Dalcin   } else {
274aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
275aa3661deSLisandro Dalcin        provided preconditioner matrix with the default matrix free version. */
276aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);CHKERRQ(ierr);
277aa3661deSLisandro Dalcin     /* Force no preconditioner */
278aa3661deSLisandro Dalcin     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
279aa3661deSLisandro Dalcin     ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
280aa3661deSLisandro Dalcin     ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
281aa3661deSLisandro Dalcin     if (!match) {
282aa3661deSLisandro Dalcin       ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
283aa3661deSLisandro Dalcin       ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
284aa3661deSLisandro Dalcin     }
285aa3661deSLisandro Dalcin   }
2866bf464f9SBarry Smith   ierr = MatDestroy(&J);CHKERRQ(ierr);
287aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
288aa3661deSLisandro Dalcin }
289aa3661deSLisandro Dalcin 
2904a2ae208SSatish Balay #undef __FUNCT__
2914a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions"
2929b94acceSBarry Smith /*@
29394b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
2949b94acceSBarry Smith 
295c7afd0dbSLois Curfman McInnes    Collective on SNES
296c7afd0dbSLois Curfman McInnes 
2979b94acceSBarry Smith    Input Parameter:
2989b94acceSBarry Smith .  snes - the SNES context
2999b94acceSBarry Smith 
30036851e7fSLois Curfman McInnes    Options Database Keys:
3016831982aSBarry Smith +  -snes_type <type> - ls, tr, umls, umtr, test
30282738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
30382738288SBarry Smith                 of the change in the solution between steps
30470441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
305b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
306b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
307b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
30850ffb88aSMatthew Knepley .  -snes_max_fail <max_fail> - maximum number of failures
309ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
310a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
311e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
312b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
3132492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
31482738288SBarry Smith                                solver; hence iterations will continue until max_it
3151fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
31682738288SBarry Smith                                of convergence test
317e8105e01SRichard Katz .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
318e8105e01SRichard Katz                                        filename given prints to stdout
319a6570f20SBarry Smith .  -snes_monitor_solution - plots solution at each iteration
320a6570f20SBarry Smith .  -snes_monitor_residual - plots residual (not its norm) at each iteration
321a6570f20SBarry Smith .  -snes_monitor_solution_update - plots update to solution at each iteration
322a6570f20SBarry Smith .  -snes_monitor_draw - plots residual norm at each iteration
323e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
3245968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
325fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
32682738288SBarry Smith 
32782738288SBarry Smith     Options Database for Eisenstat-Walker method:
328fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
3294b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
33036851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
33136851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
33236851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
33336851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
33436851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
33536851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
33682738288SBarry Smith 
33711ca99fdSLois Curfman McInnes    Notes:
33811ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
3390598bfebSBarry Smith    the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>.
34083e2fdc7SBarry Smith 
34136851e7fSLois Curfman McInnes    Level: beginner
34236851e7fSLois Curfman McInnes 
3439b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
3449b94acceSBarry Smith 
34569ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
3469b94acceSBarry Smith @*/
3477087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
3489b94acceSBarry Smith {
349ace3abfcSBarry Smith   PetscBool               flg,mf,mf_operator;
350efd51863SBarry Smith   PetscInt                i,indx,lag,mf_version,grids;
351aa3661deSLisandro Dalcin   MatStructure            matflag;
35285385478SLisandro Dalcin   const char              *deft = SNESLS;
35385385478SLisandro Dalcin   const char              *convtests[] = {"default","skip"};
35485385478SLisandro Dalcin   SNESKSPEW               *kctx = NULL;
355e8105e01SRichard Katz   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
356649052a6SBarry Smith   PetscViewer             monviewer;
35785385478SLisandro Dalcin   PetscErrorCode          ierr;
3589b94acceSBarry Smith 
3593a40ed3dSBarry Smith   PetscFunctionBegin;
3600700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
361ca161407SBarry Smith 
362186905e3SBarry Smith   if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
363cce0b1b2SLisandro Dalcin   ierr = PetscOptionsBegin(((PetscObject)snes)->comm,((PetscObject)snes)->prefix,"Nonlinear solver (SNES) options","SNES");CHKERRQ(ierr);
3647adad957SLisandro Dalcin     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
365b0a32e0cSBarry Smith     ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
366d64ed03dSBarry Smith     if (flg) {
367186905e3SBarry Smith       ierr = SNESSetType(snes,type);CHKERRQ(ierr);
3687adad957SLisandro Dalcin     } else if (!((PetscObject)snes)->type_name) {
369186905e3SBarry Smith       ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
370d64ed03dSBarry Smith     }
37190d69ab7SBarry Smith     /* not used here, but called so will go into help messaage */
372909c8a9fSBarry Smith     ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr);
37393c39befSBarry Smith 
37457034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->xtol,&snes->xtol,0);CHKERRQ(ierr);
37557034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr);
376186905e3SBarry Smith 
37757034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr);
378b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr);
379b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr);
38050ffb88aSMatthew Knepley     ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr);
381ddf469c8SBarry Smith     ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr);
382acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr);
38385385478SLisandro Dalcin 
384a8054027SBarry Smith     ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
385a8054027SBarry Smith     if (flg) {
386a8054027SBarry Smith       ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
387a8054027SBarry Smith     }
388e35cf81dSBarry Smith     ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
389e35cf81dSBarry Smith     if (flg) {
390e35cf81dSBarry Smith       ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
391e35cf81dSBarry Smith     }
392efd51863SBarry Smith     ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
393efd51863SBarry Smith     if (flg) {
394efd51863SBarry Smith       ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
395efd51863SBarry Smith     }
396a8054027SBarry Smith 
39785385478SLisandro Dalcin     ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
39885385478SLisandro Dalcin     if (flg) {
39985385478SLisandro Dalcin       switch (indx) {
4007f7931b9SBarry Smith       case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break;
4017f7931b9SBarry Smith       case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);    break;
40285385478SLisandro Dalcin       }
40385385478SLisandro Dalcin     }
40485385478SLisandro Dalcin 
405acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr);
406186905e3SBarry Smith 
40785385478SLisandro Dalcin     kctx = (SNESKSPEW *)snes->kspconvctx;
40885385478SLisandro Dalcin 
409acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr);
410186905e3SBarry Smith 
411fa9f3622SBarry Smith     ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr);
412fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr);
413fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr);
414fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr);
415fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr);
416fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr);
417fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr);
418186905e3SBarry Smith 
41990d69ab7SBarry Smith     flg  = PETSC_FALSE;
420acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
421a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
422eabae89aSBarry Smith 
423a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
424e8105e01SRichard Katz     if (flg) {
425649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
426649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
427e8105e01SRichard Katz     }
428eabae89aSBarry Smith 
429b271bb04SBarry Smith     ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
430b271bb04SBarry Smith     if (flg) {
431b271bb04SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr);
432b271bb04SBarry Smith     }
433b271bb04SBarry Smith 
434a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
435eabae89aSBarry Smith     if (flg) {
436649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
437f1bef1bcSMatthew Knepley       ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr);
438e8105e01SRichard Katz     }
439eabae89aSBarry Smith 
440a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
441eabae89aSBarry Smith     if (flg) {
442649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
443649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
444eabae89aSBarry Smith     }
445eabae89aSBarry Smith 
44690d69ab7SBarry Smith     flg  = PETSC_FALSE;
447acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
448a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
44990d69ab7SBarry Smith     flg  = PETSC_FALSE;
450acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
451a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
45290d69ab7SBarry Smith     flg  = PETSC_FALSE;
453acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
454a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
45590d69ab7SBarry Smith     flg  = PETSC_FALSE;
456acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
457a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
45890d69ab7SBarry Smith     flg  = PETSC_FALSE;
459acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
460b271bb04SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
461e24b481bSBarry Smith 
46290d69ab7SBarry Smith     flg  = PETSC_FALSE;
463acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
4644b27c08aSLois Curfman McInnes     if (flg) {
465186905e3SBarry Smith       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);CHKERRQ(ierr);
466ae15b995SBarry Smith       ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
4679b94acceSBarry Smith     }
468639f9d9dSBarry Smith 
469aa3661deSLisandro Dalcin     mf = mf_operator = PETSC_FALSE;
470aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
471acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr);
472a8248277SBarry Smith     if (flg && mf_operator) {
473a8248277SBarry Smith       snes->mf_operator = PETSC_TRUE;
474a8248277SBarry Smith       mf = PETSC_TRUE;
475a8248277SBarry Smith     }
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);
1577a8248277SBarry Smith   } else if (snes->ops->computejacobian == MatMFFDComputeJacobian) {
1578a8248277SBarry Smith     Mat J;
1579a8248277SBarry Smith     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
1580a8248277SBarry Smith     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
1581a8248277SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
1582a8248277SBarry Smith     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);CHKERRQ(ierr);
1583a8248277SBarry Smith     ierr = MatDestroy(&J);CHKERRQ(ierr);
1584a8248277SBarry Smith   } else if (snes->dm && snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
1585a8248277SBarry Smith     Mat J,B;
1586a8248277SBarry Smith     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
1587a8248277SBarry Smith     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
1588a8248277SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
1589a8248277SBarry Smith     ierr = DMGetMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
1590a8248277SBarry Smith     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,snes->funP);CHKERRQ(ierr);
1591a8248277SBarry Smith     ierr = MatDestroy(&J);CHKERRQ(ierr);
1592a8248277SBarry Smith     ierr = MatDestroy(&B);CHKERRQ(ierr);
1593efd51863SBarry Smith   } else if (snes->dm && !snes->jacobian_pre){
1594efd51863SBarry Smith     Mat J;
1595efd51863SBarry Smith     ierr = DMGetMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr);
1596*3cbb28f5SBarry Smith     ierr = SNESSetJacobian(snes,J,J,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
1597efd51863SBarry Smith     ierr = MatDestroy(&J);CHKERRQ(ierr);
1598ef8dffc7SBarry Smith   }
1599efd51863SBarry Smith 
1600b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
1601b710008aSBarry Smith 
1602d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
1603d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
1604d25893d9SBarry Smith   }
1605d25893d9SBarry Smith 
1606410397dcSLisandro Dalcin   if (snes->ops->setup) {
1607410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
1608410397dcSLisandro Dalcin   }
160958c9b817SLisandro Dalcin 
16107aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
16113a40ed3dSBarry Smith   PetscFunctionReturn(0);
16129b94acceSBarry Smith }
16139b94acceSBarry Smith 
16144a2ae208SSatish Balay #undef __FUNCT__
161537596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
161637596af1SLisandro Dalcin /*@
161737596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
161837596af1SLisandro Dalcin 
161937596af1SLisandro Dalcin    Collective on SNES
162037596af1SLisandro Dalcin 
162137596af1SLisandro Dalcin    Input Parameter:
162237596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
162337596af1SLisandro Dalcin 
1624d25893d9SBarry Smith    Level: intermediate
1625d25893d9SBarry Smith 
1626d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
162737596af1SLisandro Dalcin 
162837596af1SLisandro Dalcin .keywords: SNES, destroy
162937596af1SLisandro Dalcin 
163037596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
163137596af1SLisandro Dalcin @*/
163237596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
163337596af1SLisandro Dalcin {
163437596af1SLisandro Dalcin   PetscErrorCode ierr;
163537596af1SLisandro Dalcin 
163637596af1SLisandro Dalcin   PetscFunctionBegin;
163737596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1638d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
1639d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
1640d25893d9SBarry Smith     snes->user = PETSC_NULL;
1641d25893d9SBarry Smith   }
1642644e2e5bSBarry Smith   if (snes->ops->computejacobian == SNESDefaultComputeJacobianColor && snes->dm) {
1643644e2e5bSBarry Smith     ierr = MatFDColoringDestroy((MatFDColoring*)&snes->jacP);CHKERRQ(ierr);
1644644e2e5bSBarry Smith     snes->ops->computejacobian = PETSC_NULL;
1645644e2e5bSBarry Smith   }
1646d25893d9SBarry Smith 
164737596af1SLisandro Dalcin   if (snes->ops->reset) {
164837596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
164937596af1SLisandro Dalcin   }
165037596af1SLisandro Dalcin   if (snes->ksp) {ierr = KSPReset(snes->ksp);CHKERRQ(ierr);}
16516bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
16526bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
16536bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
16546bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
16556bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
16566bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
165737596af1SLisandro Dalcin   if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);}
165837596af1SLisandro Dalcin   if (snes->vwork) {ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);}
165937596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
166037596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
166137596af1SLisandro Dalcin   PetscFunctionReturn(0);
166237596af1SLisandro Dalcin }
166337596af1SLisandro Dalcin 
166437596af1SLisandro Dalcin #undef __FUNCT__
16654a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
166652baeb72SSatish Balay /*@
16679b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
16689b94acceSBarry Smith    with SNESCreate().
16699b94acceSBarry Smith 
1670c7afd0dbSLois Curfman McInnes    Collective on SNES
1671c7afd0dbSLois Curfman McInnes 
16729b94acceSBarry Smith    Input Parameter:
16739b94acceSBarry Smith .  snes - the SNES context
16749b94acceSBarry Smith 
167536851e7fSLois Curfman McInnes    Level: beginner
167636851e7fSLois Curfman McInnes 
16779b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
16789b94acceSBarry Smith 
167963a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
16809b94acceSBarry Smith @*/
16816bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
16829b94acceSBarry Smith {
16836849ba73SBarry Smith   PetscErrorCode ierr;
16843a40ed3dSBarry Smith 
16853a40ed3dSBarry Smith   PetscFunctionBegin;
16866bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
16876bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
16886bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
1689d4bb536fSBarry Smith 
16906bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
16916b8b9a38SLisandro Dalcin 
1692be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
16936bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
16946bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
16956d4c513bSLisandro Dalcin 
16966bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
16976bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
16986b8b9a38SLisandro Dalcin 
16996bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
17006bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
17016bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
17026b8b9a38SLisandro Dalcin   }
17036bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
17046bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
17056bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
170658c9b817SLisandro Dalcin   }
17076bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
1708a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
17093a40ed3dSBarry Smith   PetscFunctionReturn(0);
17109b94acceSBarry Smith }
17119b94acceSBarry Smith 
17129b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
17139b94acceSBarry Smith 
17144a2ae208SSatish Balay #undef __FUNCT__
1715a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
1716a8054027SBarry Smith /*@
1717a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
1718a8054027SBarry Smith 
17193f9fe445SBarry Smith    Logically Collective on SNES
1720a8054027SBarry Smith 
1721a8054027SBarry Smith    Input Parameters:
1722a8054027SBarry Smith +  snes - the SNES context
1723a8054027SBarry 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
17243b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
1725a8054027SBarry Smith 
1726a8054027SBarry Smith    Options Database Keys:
1727a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
1728a8054027SBarry Smith 
1729a8054027SBarry Smith    Notes:
1730a8054027SBarry Smith    The default is 1
1731a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1732a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
1733a8054027SBarry Smith 
1734a8054027SBarry Smith    Level: intermediate
1735a8054027SBarry Smith 
1736a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1737a8054027SBarry Smith 
1738e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
1739a8054027SBarry Smith 
1740a8054027SBarry Smith @*/
17417087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
1742a8054027SBarry Smith {
1743a8054027SBarry Smith   PetscFunctionBegin;
17440700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1745e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
1746e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
1747c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
1748a8054027SBarry Smith   snes->lagpreconditioner = lag;
1749a8054027SBarry Smith   PetscFunctionReturn(0);
1750a8054027SBarry Smith }
1751a8054027SBarry Smith 
1752a8054027SBarry Smith #undef __FUNCT__
1753efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
1754efd51863SBarry Smith /*@
1755efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
1756efd51863SBarry Smith 
1757efd51863SBarry Smith    Logically Collective on SNES
1758efd51863SBarry Smith 
1759efd51863SBarry Smith    Input Parameters:
1760efd51863SBarry Smith +  snes - the SNES context
1761efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
1762efd51863SBarry Smith 
1763efd51863SBarry Smith    Options Database Keys:
1764efd51863SBarry Smith .    -snes_grid_sequence <steps>
1765efd51863SBarry Smith 
1766efd51863SBarry Smith    Level: intermediate
1767efd51863SBarry Smith 
1768efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1769efd51863SBarry Smith 
1770efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
1771efd51863SBarry Smith 
1772efd51863SBarry Smith @*/
1773efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
1774efd51863SBarry Smith {
1775efd51863SBarry Smith   PetscFunctionBegin;
1776efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1777efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
1778efd51863SBarry Smith   snes->gridsequence = steps;
1779efd51863SBarry Smith   PetscFunctionReturn(0);
1780efd51863SBarry Smith }
1781efd51863SBarry Smith 
1782efd51863SBarry Smith #undef __FUNCT__
1783a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
1784a8054027SBarry Smith /*@
1785a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
1786a8054027SBarry Smith 
17873f9fe445SBarry Smith    Not Collective
1788a8054027SBarry Smith 
1789a8054027SBarry Smith    Input Parameter:
1790a8054027SBarry Smith .  snes - the SNES context
1791a8054027SBarry Smith 
1792a8054027SBarry Smith    Output Parameter:
1793a8054027SBarry 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
17943b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
1795a8054027SBarry Smith 
1796a8054027SBarry Smith    Options Database Keys:
1797a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
1798a8054027SBarry Smith 
1799a8054027SBarry Smith    Notes:
1800a8054027SBarry Smith    The default is 1
1801a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1802a8054027SBarry Smith 
1803a8054027SBarry Smith    Level: intermediate
1804a8054027SBarry Smith 
1805a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1806a8054027SBarry Smith 
1807a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
1808a8054027SBarry Smith 
1809a8054027SBarry Smith @*/
18107087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
1811a8054027SBarry Smith {
1812a8054027SBarry Smith   PetscFunctionBegin;
18130700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1814a8054027SBarry Smith   *lag = snes->lagpreconditioner;
1815a8054027SBarry Smith   PetscFunctionReturn(0);
1816a8054027SBarry Smith }
1817a8054027SBarry Smith 
1818a8054027SBarry Smith #undef __FUNCT__
1819e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
1820e35cf81dSBarry Smith /*@
1821e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
1822e35cf81dSBarry Smith      often the preconditioner is rebuilt.
1823e35cf81dSBarry Smith 
18243f9fe445SBarry Smith    Logically Collective on SNES
1825e35cf81dSBarry Smith 
1826e35cf81dSBarry Smith    Input Parameters:
1827e35cf81dSBarry Smith +  snes - the SNES context
1828e35cf81dSBarry 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
1829fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
1830e35cf81dSBarry Smith 
1831e35cf81dSBarry Smith    Options Database Keys:
1832e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
1833e35cf81dSBarry Smith 
1834e35cf81dSBarry Smith    Notes:
1835e35cf81dSBarry Smith    The default is 1
1836e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1837fe3ffe1eSBarry 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
1838fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
1839e35cf81dSBarry Smith 
1840e35cf81dSBarry Smith    Level: intermediate
1841e35cf81dSBarry Smith 
1842e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1843e35cf81dSBarry Smith 
1844e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
1845e35cf81dSBarry Smith 
1846e35cf81dSBarry Smith @*/
18477087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
1848e35cf81dSBarry Smith {
1849e35cf81dSBarry Smith   PetscFunctionBegin;
18500700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1851e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
1852e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
1853c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
1854e35cf81dSBarry Smith   snes->lagjacobian = lag;
1855e35cf81dSBarry Smith   PetscFunctionReturn(0);
1856e35cf81dSBarry Smith }
1857e35cf81dSBarry Smith 
1858e35cf81dSBarry Smith #undef __FUNCT__
1859e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
1860e35cf81dSBarry Smith /*@
1861e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
1862e35cf81dSBarry Smith 
18633f9fe445SBarry Smith    Not Collective
1864e35cf81dSBarry Smith 
1865e35cf81dSBarry Smith    Input Parameter:
1866e35cf81dSBarry Smith .  snes - the SNES context
1867e35cf81dSBarry Smith 
1868e35cf81dSBarry Smith    Output Parameter:
1869e35cf81dSBarry 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
1870e35cf81dSBarry Smith          the Jacobian is built etc.
1871e35cf81dSBarry Smith 
1872e35cf81dSBarry Smith    Options Database Keys:
1873e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
1874e35cf81dSBarry Smith 
1875e35cf81dSBarry Smith    Notes:
1876e35cf81dSBarry Smith    The default is 1
1877e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1878e35cf81dSBarry Smith 
1879e35cf81dSBarry Smith    Level: intermediate
1880e35cf81dSBarry Smith 
1881e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1882e35cf81dSBarry Smith 
1883e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
1884e35cf81dSBarry Smith 
1885e35cf81dSBarry Smith @*/
18867087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
1887e35cf81dSBarry Smith {
1888e35cf81dSBarry Smith   PetscFunctionBegin;
18890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1890e35cf81dSBarry Smith   *lag = snes->lagjacobian;
1891e35cf81dSBarry Smith   PetscFunctionReturn(0);
1892e35cf81dSBarry Smith }
1893e35cf81dSBarry Smith 
1894e35cf81dSBarry Smith #undef __FUNCT__
18954a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
18969b94acceSBarry Smith /*@
1897d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
18989b94acceSBarry Smith 
18993f9fe445SBarry Smith    Logically Collective on SNES
1900c7afd0dbSLois Curfman McInnes 
19019b94acceSBarry Smith    Input Parameters:
1902c7afd0dbSLois Curfman McInnes +  snes - the SNES context
190370441072SBarry Smith .  abstol - absolute convergence tolerance
190433174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
190533174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
190633174efeSLois Curfman McInnes            of the change in the solution between steps
190733174efeSLois Curfman McInnes .  maxit - maximum number of iterations
1908c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
1909fee21e36SBarry Smith 
191033174efeSLois Curfman McInnes    Options Database Keys:
191170441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
1912c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
1913c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
1914c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
1915c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
19169b94acceSBarry Smith 
1917d7a720efSLois Curfman McInnes    Notes:
19189b94acceSBarry Smith    The default maximum number of iterations is 50.
19199b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
19209b94acceSBarry Smith 
192136851e7fSLois Curfman McInnes    Level: intermediate
192236851e7fSLois Curfman McInnes 
192333174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
19249b94acceSBarry Smith 
19252492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
19269b94acceSBarry Smith @*/
19277087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
19289b94acceSBarry Smith {
19293a40ed3dSBarry Smith   PetscFunctionBegin;
19300700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1931c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
1932c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
1933c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
1934c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
1935c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
1936c5eb9154SBarry Smith 
193770441072SBarry Smith   if (abstol != PETSC_DEFAULT)  snes->abstol      = abstol;
1938d7a720efSLois Curfman McInnes   if (rtol != PETSC_DEFAULT)  snes->rtol      = rtol;
1939d7a720efSLois Curfman McInnes   if (stol != PETSC_DEFAULT)  snes->xtol      = stol;
1940d7a720efSLois Curfman McInnes   if (maxit != PETSC_DEFAULT) snes->max_its   = maxit;
1941d7a720efSLois Curfman McInnes   if (maxf != PETSC_DEFAULT)  snes->max_funcs = maxf;
19423a40ed3dSBarry Smith   PetscFunctionReturn(0);
19439b94acceSBarry Smith }
19449b94acceSBarry Smith 
19454a2ae208SSatish Balay #undef __FUNCT__
19464a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
19479b94acceSBarry Smith /*@
194833174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
194933174efeSLois Curfman McInnes 
1950c7afd0dbSLois Curfman McInnes    Not Collective
1951c7afd0dbSLois Curfman McInnes 
195233174efeSLois Curfman McInnes    Input Parameters:
1953c7afd0dbSLois Curfman McInnes +  snes - the SNES context
195485385478SLisandro Dalcin .  atol - absolute convergence tolerance
195533174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
195633174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
195733174efeSLois Curfman McInnes            of the change in the solution between steps
195833174efeSLois Curfman McInnes .  maxit - maximum number of iterations
1959c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
1960fee21e36SBarry Smith 
196133174efeSLois Curfman McInnes    Notes:
196233174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
196333174efeSLois Curfman McInnes 
196436851e7fSLois Curfman McInnes    Level: intermediate
196536851e7fSLois Curfman McInnes 
196633174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
196733174efeSLois Curfman McInnes 
196833174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
196933174efeSLois Curfman McInnes @*/
19707087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
197133174efeSLois Curfman McInnes {
19723a40ed3dSBarry Smith   PetscFunctionBegin;
19730700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
197485385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
197533174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
197633174efeSLois Curfman McInnes   if (stol)  *stol  = snes->xtol;
197733174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
197833174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
19793a40ed3dSBarry Smith   PetscFunctionReturn(0);
198033174efeSLois Curfman McInnes }
198133174efeSLois Curfman McInnes 
19824a2ae208SSatish Balay #undef __FUNCT__
19834a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
198433174efeSLois Curfman McInnes /*@
19859b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
19869b94acceSBarry Smith 
19873f9fe445SBarry Smith    Logically Collective on SNES
1988fee21e36SBarry Smith 
1989c7afd0dbSLois Curfman McInnes    Input Parameters:
1990c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1991c7afd0dbSLois Curfman McInnes -  tol - tolerance
1992c7afd0dbSLois Curfman McInnes 
19939b94acceSBarry Smith    Options Database Key:
1994c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
19959b94acceSBarry Smith 
199636851e7fSLois Curfman McInnes    Level: intermediate
199736851e7fSLois Curfman McInnes 
19989b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
19999b94acceSBarry Smith 
20002492ecdbSBarry Smith .seealso: SNESSetTolerances()
20019b94acceSBarry Smith @*/
20027087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
20039b94acceSBarry Smith {
20043a40ed3dSBarry Smith   PetscFunctionBegin;
20050700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2006c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
20079b94acceSBarry Smith   snes->deltatol = tol;
20083a40ed3dSBarry Smith   PetscFunctionReturn(0);
20099b94acceSBarry Smith }
20109b94acceSBarry Smith 
2011df9fa365SBarry Smith /*
2012df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
2013df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
2014df9fa365SBarry Smith    macros instead of functions
2015df9fa365SBarry Smith */
20164a2ae208SSatish Balay #undef __FUNCT__
2017a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
20187087cfbeSBarry Smith PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2019ce1608b8SBarry Smith {
2020dfbe8321SBarry Smith   PetscErrorCode ierr;
2021ce1608b8SBarry Smith 
2022ce1608b8SBarry Smith   PetscFunctionBegin;
20230700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2024a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
2025ce1608b8SBarry Smith   PetscFunctionReturn(0);
2026ce1608b8SBarry Smith }
2027ce1608b8SBarry Smith 
20284a2ae208SSatish Balay #undef __FUNCT__
2029a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
20307087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2031df9fa365SBarry Smith {
2032dfbe8321SBarry Smith   PetscErrorCode ierr;
2033df9fa365SBarry Smith 
2034df9fa365SBarry Smith   PetscFunctionBegin;
2035a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2036df9fa365SBarry Smith   PetscFunctionReturn(0);
2037df9fa365SBarry Smith }
2038df9fa365SBarry Smith 
20394a2ae208SSatish Balay #undef __FUNCT__
2040a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
20416bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
2042df9fa365SBarry Smith {
2043dfbe8321SBarry Smith   PetscErrorCode ierr;
2044df9fa365SBarry Smith 
2045df9fa365SBarry Smith   PetscFunctionBegin;
2046a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2047df9fa365SBarry Smith   PetscFunctionReturn(0);
2048df9fa365SBarry Smith }
2049df9fa365SBarry Smith 
20507087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
2051b271bb04SBarry Smith #undef __FUNCT__
2052b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
20537087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2054b271bb04SBarry Smith {
2055b271bb04SBarry Smith   PetscDrawLG      lg;
2056b271bb04SBarry Smith   PetscErrorCode   ierr;
2057b271bb04SBarry Smith   PetscReal        x,y,per;
2058b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
2059b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
2060b271bb04SBarry Smith   PetscDraw        draw;
2061b271bb04SBarry Smith   PetscFunctionBegin;
2062b271bb04SBarry Smith   if (!monctx) {
2063b271bb04SBarry Smith     MPI_Comm    comm;
2064b271bb04SBarry Smith 
2065b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2066b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
2067b271bb04SBarry Smith   }
2068b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
2069b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2070b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2071b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
2072b271bb04SBarry Smith   x = (PetscReal) n;
2073b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
2074b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2075b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2076b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2077b271bb04SBarry Smith   }
2078b271bb04SBarry Smith 
2079b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
2080b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2081b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2082b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
2083b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
2084b271bb04SBarry Smith   x = (PetscReal) n;
2085b271bb04SBarry Smith   y = 100.0*per;
2086b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2087b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2088b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2089b271bb04SBarry Smith   }
2090b271bb04SBarry Smith 
2091b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
2092b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2093b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2094b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
2095b271bb04SBarry Smith   x = (PetscReal) n;
2096b271bb04SBarry Smith   y = (prev - rnorm)/prev;
2097b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2098b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2099b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2100b271bb04SBarry Smith   }
2101b271bb04SBarry Smith 
2102b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
2103b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2104b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2105b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
2106b271bb04SBarry Smith   x = (PetscReal) n;
2107b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
2108b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
2109b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2110b271bb04SBarry Smith   }
2111b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2112b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2113b271bb04SBarry Smith   }
2114b271bb04SBarry Smith   prev = rnorm;
2115b271bb04SBarry Smith   PetscFunctionReturn(0);
2116b271bb04SBarry Smith }
2117b271bb04SBarry Smith 
2118b271bb04SBarry Smith #undef __FUNCT__
2119b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
21207087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2121b271bb04SBarry Smith {
2122b271bb04SBarry Smith   PetscErrorCode ierr;
2123b271bb04SBarry Smith 
2124b271bb04SBarry Smith   PetscFunctionBegin;
2125b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2126b271bb04SBarry Smith   PetscFunctionReturn(0);
2127b271bb04SBarry Smith }
2128b271bb04SBarry Smith 
2129b271bb04SBarry Smith #undef __FUNCT__
2130b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
21316bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG *draw)
2132b271bb04SBarry Smith {
2133b271bb04SBarry Smith   PetscErrorCode ierr;
2134b271bb04SBarry Smith 
2135b271bb04SBarry Smith   PetscFunctionBegin;
2136b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2137b271bb04SBarry Smith   PetscFunctionReturn(0);
2138b271bb04SBarry Smith }
2139b271bb04SBarry Smith 
21407a03ce2fSLisandro Dalcin #undef __FUNCT__
21417a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
21427a03ce2fSLisandro Dalcin /*
21437a03ce2fSLisandro Dalcin      Runs the user provided monitor routines, if they exists.
21447a03ce2fSLisandro Dalcin */
21457a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
21467a03ce2fSLisandro Dalcin {
21477a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
21487a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
21497a03ce2fSLisandro Dalcin 
21507a03ce2fSLisandro Dalcin   PetscFunctionBegin;
21517a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
21527a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
21537a03ce2fSLisandro Dalcin   }
21547a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
21557a03ce2fSLisandro Dalcin }
21567a03ce2fSLisandro Dalcin 
21579b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
21589b94acceSBarry Smith 
21594a2ae208SSatish Balay #undef __FUNCT__
2160a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
21619b94acceSBarry Smith /*@C
2162a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
21639b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
21649b94acceSBarry Smith    progress.
21659b94acceSBarry Smith 
21663f9fe445SBarry Smith    Logically Collective on SNES
2167fee21e36SBarry Smith 
2168c7afd0dbSLois Curfman McInnes    Input Parameters:
2169c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2170c7afd0dbSLois Curfman McInnes .  func - monitoring routine
2171b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
2172e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
2173b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
2174b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
21759b94acceSBarry Smith 
2176c7afd0dbSLois Curfman McInnes    Calling sequence of func:
2177a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
2178c7afd0dbSLois Curfman McInnes 
2179c7afd0dbSLois Curfman McInnes +    snes - the SNES context
2180c7afd0dbSLois Curfman McInnes .    its - iteration number
2181c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
218240a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
21839b94acceSBarry Smith 
21849665c990SLois Curfman McInnes    Options Database Keys:
2185a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
2186a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
2187a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
2188cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
2189c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
2190a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
2191c7afd0dbSLois Curfman McInnes                             does not cancel those set via
2192c7afd0dbSLois Curfman McInnes                             the options database.
21939665c990SLois Curfman McInnes 
2194639f9d9dSBarry Smith    Notes:
21956bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
2196a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
21976bc08f3fSLois Curfman McInnes    order in which they were set.
2198639f9d9dSBarry Smith 
2199025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
2200025f1a04SBarry Smith 
220136851e7fSLois Curfman McInnes    Level: intermediate
220236851e7fSLois Curfman McInnes 
22039b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
22049b94acceSBarry Smith 
2205a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
22069b94acceSBarry Smith @*/
2207c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
22089b94acceSBarry Smith {
2209b90d0a6eSBarry Smith   PetscInt       i;
2210649052a6SBarry Smith   PetscErrorCode ierr;
2211b90d0a6eSBarry Smith 
22123a40ed3dSBarry Smith   PetscFunctionBegin;
22130700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
221417186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
2215b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
2216649052a6SBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
2217649052a6SBarry Smith       if (monitordestroy) {
2218c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
2219649052a6SBarry Smith       }
2220b90d0a6eSBarry Smith       PetscFunctionReturn(0);
2221b90d0a6eSBarry Smith     }
2222b90d0a6eSBarry Smith   }
2223b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
2224b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
2225639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
22263a40ed3dSBarry Smith   PetscFunctionReturn(0);
22279b94acceSBarry Smith }
22289b94acceSBarry Smith 
22294a2ae208SSatish Balay #undef __FUNCT__
2230a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
22315cd90555SBarry Smith /*@C
2232a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
22335cd90555SBarry Smith 
22343f9fe445SBarry Smith    Logically Collective on SNES
2235c7afd0dbSLois Curfman McInnes 
22365cd90555SBarry Smith    Input Parameters:
22375cd90555SBarry Smith .  snes - the SNES context
22385cd90555SBarry Smith 
22391a480d89SAdministrator    Options Database Key:
2240a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
2241a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
2242c7afd0dbSLois Curfman McInnes     set via the options database
22435cd90555SBarry Smith 
22445cd90555SBarry Smith    Notes:
22455cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
22465cd90555SBarry Smith 
224736851e7fSLois Curfman McInnes    Level: intermediate
224836851e7fSLois Curfman McInnes 
22495cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
22505cd90555SBarry Smith 
2251a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
22525cd90555SBarry Smith @*/
22537087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
22545cd90555SBarry Smith {
2255d952e501SBarry Smith   PetscErrorCode ierr;
2256d952e501SBarry Smith   PetscInt       i;
2257d952e501SBarry Smith 
22585cd90555SBarry Smith   PetscFunctionBegin;
22590700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2260d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
2261d952e501SBarry Smith     if (snes->monitordestroy[i]) {
22623c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
2263d952e501SBarry Smith     }
2264d952e501SBarry Smith   }
22655cd90555SBarry Smith   snes->numbermonitors = 0;
22665cd90555SBarry Smith   PetscFunctionReturn(0);
22675cd90555SBarry Smith }
22685cd90555SBarry Smith 
22694a2ae208SSatish Balay #undef __FUNCT__
22704a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
22719b94acceSBarry Smith /*@C
22729b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
22739b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
22749b94acceSBarry Smith 
22753f9fe445SBarry Smith    Logically Collective on SNES
2276fee21e36SBarry Smith 
2277c7afd0dbSLois Curfman McInnes    Input Parameters:
2278c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2279c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
22807f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
22817f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
22829b94acceSBarry Smith 
2283c7afd0dbSLois Curfman McInnes    Calling sequence of func:
228406ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
2285c7afd0dbSLois Curfman McInnes 
2286c7afd0dbSLois Curfman McInnes +    snes - the SNES context
228706ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
2288c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
2289184914b5SBarry Smith .    reason - reason for convergence/divergence
2290c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
22914b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
22924b27c08aSLois Curfman McInnes -    f - 2-norm of function
22939b94acceSBarry Smith 
229436851e7fSLois Curfman McInnes    Level: advanced
229536851e7fSLois Curfman McInnes 
22969b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
22979b94acceSBarry Smith 
229885385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
22999b94acceSBarry Smith @*/
23007087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
23019b94acceSBarry Smith {
23027f7931b9SBarry Smith   PetscErrorCode ierr;
23037f7931b9SBarry Smith 
23043a40ed3dSBarry Smith   PetscFunctionBegin;
23050700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
230685385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
23077f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
23087f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
23097f7931b9SBarry Smith   }
231085385478SLisandro Dalcin   snes->ops->converged        = func;
23117f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
231285385478SLisandro Dalcin   snes->cnvP                  = cctx;
23133a40ed3dSBarry Smith   PetscFunctionReturn(0);
23149b94acceSBarry Smith }
23159b94acceSBarry Smith 
23164a2ae208SSatish Balay #undef __FUNCT__
23174a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
231852baeb72SSatish Balay /*@
2319184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
2320184914b5SBarry Smith 
2321184914b5SBarry Smith    Not Collective
2322184914b5SBarry Smith 
2323184914b5SBarry Smith    Input Parameter:
2324184914b5SBarry Smith .  snes - the SNES context
2325184914b5SBarry Smith 
2326184914b5SBarry Smith    Output Parameter:
23274d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
2328184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
2329184914b5SBarry Smith 
2330184914b5SBarry Smith    Level: intermediate
2331184914b5SBarry Smith 
2332184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
2333184914b5SBarry Smith 
2334184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
2335184914b5SBarry Smith 
233685385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
2337184914b5SBarry Smith @*/
23387087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
2339184914b5SBarry Smith {
2340184914b5SBarry Smith   PetscFunctionBegin;
23410700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
23424482741eSBarry Smith   PetscValidPointer(reason,2);
2343184914b5SBarry Smith   *reason = snes->reason;
2344184914b5SBarry Smith   PetscFunctionReturn(0);
2345184914b5SBarry Smith }
2346184914b5SBarry Smith 
23474a2ae208SSatish Balay #undef __FUNCT__
23484a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
2349c9005455SLois Curfman McInnes /*@
2350c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
2351c9005455SLois Curfman McInnes 
23523f9fe445SBarry Smith    Logically Collective on SNES
2353fee21e36SBarry Smith 
2354c7afd0dbSLois Curfman McInnes    Input Parameters:
2355c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
23568c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
2357cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
2358758f92a0SBarry Smith .  na  - size of a and its
235964731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
2360758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
2361c7afd0dbSLois Curfman McInnes 
2362308dcc3eSBarry Smith    Notes:
2363308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
2364308dcc3eSBarry Smith    default array of length 10000 is allocated.
2365308dcc3eSBarry Smith 
2366c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
2367c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
2368c9005455SLois Curfman McInnes    during the section of code that is being timed.
2369c9005455SLois Curfman McInnes 
237036851e7fSLois Curfman McInnes    Level: intermediate
237136851e7fSLois Curfman McInnes 
2372c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
2373758f92a0SBarry Smith 
237408405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
2375758f92a0SBarry Smith 
2376c9005455SLois Curfman McInnes @*/
23777087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
2378c9005455SLois Curfman McInnes {
2379308dcc3eSBarry Smith   PetscErrorCode ierr;
2380308dcc3eSBarry Smith 
23813a40ed3dSBarry Smith   PetscFunctionBegin;
23820700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
23834482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
2384a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
2385308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
2386308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
2387308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
2388308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
2389308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
2390308dcc3eSBarry Smith   }
2391c9005455SLois Curfman McInnes   snes->conv_hist       = a;
2392758f92a0SBarry Smith   snes->conv_hist_its   = its;
2393758f92a0SBarry Smith   snes->conv_hist_max   = na;
2394a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
2395758f92a0SBarry Smith   snes->conv_hist_reset = reset;
2396758f92a0SBarry Smith   PetscFunctionReturn(0);
2397758f92a0SBarry Smith }
2398758f92a0SBarry Smith 
2399308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
2400c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
2401c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
2402308dcc3eSBarry Smith EXTERN_C_BEGIN
2403308dcc3eSBarry Smith #undef __FUNCT__
2404308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
2405308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
2406308dcc3eSBarry Smith {
2407308dcc3eSBarry Smith   mxArray        *mat;
2408308dcc3eSBarry Smith   PetscInt       i;
2409308dcc3eSBarry Smith   PetscReal      *ar;
2410308dcc3eSBarry Smith 
2411308dcc3eSBarry Smith   PetscFunctionBegin;
2412308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
2413308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
2414308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
2415308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
2416308dcc3eSBarry Smith   }
2417308dcc3eSBarry Smith   PetscFunctionReturn(mat);
2418308dcc3eSBarry Smith }
2419308dcc3eSBarry Smith EXTERN_C_END
2420308dcc3eSBarry Smith #endif
2421308dcc3eSBarry Smith 
2422308dcc3eSBarry Smith 
24234a2ae208SSatish Balay #undef __FUNCT__
24244a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
24250c4c9dddSBarry Smith /*@C
2426758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
2427758f92a0SBarry Smith 
24283f9fe445SBarry Smith    Not Collective
2429758f92a0SBarry Smith 
2430758f92a0SBarry Smith    Input Parameter:
2431758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
2432758f92a0SBarry Smith 
2433758f92a0SBarry Smith    Output Parameters:
2434758f92a0SBarry Smith .  a   - array to hold history
2435758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
2436758f92a0SBarry Smith          negative if not converged) for each solve.
2437758f92a0SBarry Smith -  na  - size of a and its
2438758f92a0SBarry Smith 
2439758f92a0SBarry Smith    Notes:
2440758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
2441758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
2442758f92a0SBarry Smith 
2443758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
2444758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
2445758f92a0SBarry Smith    during the section of code that is being timed.
2446758f92a0SBarry Smith 
2447758f92a0SBarry Smith    Level: intermediate
2448758f92a0SBarry Smith 
2449758f92a0SBarry Smith .keywords: SNES, get, convergence, history
2450758f92a0SBarry Smith 
2451758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
2452758f92a0SBarry Smith 
2453758f92a0SBarry Smith @*/
24547087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
2455758f92a0SBarry Smith {
2456758f92a0SBarry Smith   PetscFunctionBegin;
24570700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2458758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
2459758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
2460758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
24613a40ed3dSBarry Smith   PetscFunctionReturn(0);
2462c9005455SLois Curfman McInnes }
2463c9005455SLois Curfman McInnes 
2464e74ef692SMatthew Knepley #undef __FUNCT__
2465e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
2466ac226902SBarry Smith /*@C
246776b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
2468eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
24697e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
247076b2cf59SMatthew Knepley 
24713f9fe445SBarry Smith   Logically Collective on SNES
247276b2cf59SMatthew Knepley 
247376b2cf59SMatthew Knepley   Input Parameters:
247476b2cf59SMatthew Knepley . snes - The nonlinear solver context
247576b2cf59SMatthew Knepley . func - The function
247676b2cf59SMatthew Knepley 
247776b2cf59SMatthew Knepley   Calling sequence of func:
2478b5d30489SBarry Smith . func (SNES snes, PetscInt step);
247976b2cf59SMatthew Knepley 
248076b2cf59SMatthew Knepley . step - The current step of the iteration
248176b2cf59SMatthew Knepley 
2482fe97e370SBarry Smith   Level: advanced
2483fe97e370SBarry Smith 
2484fe97e370SBarry 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()
2485fe97e370SBarry Smith         This is not used by most users.
248676b2cf59SMatthew Knepley 
248776b2cf59SMatthew Knepley .keywords: SNES, update
2488b5d30489SBarry Smith 
248985385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
249076b2cf59SMatthew Knepley @*/
24917087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
249276b2cf59SMatthew Knepley {
249376b2cf59SMatthew Knepley   PetscFunctionBegin;
24940700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
2495e7788613SBarry Smith   snes->ops->update = func;
249676b2cf59SMatthew Knepley   PetscFunctionReturn(0);
249776b2cf59SMatthew Knepley }
249876b2cf59SMatthew Knepley 
2499e74ef692SMatthew Knepley #undef __FUNCT__
2500e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
250176b2cf59SMatthew Knepley /*@
250276b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
250376b2cf59SMatthew Knepley 
250476b2cf59SMatthew Knepley   Not collective
250576b2cf59SMatthew Knepley 
250676b2cf59SMatthew Knepley   Input Parameters:
250776b2cf59SMatthew Knepley . snes - The nonlinear solver context
250876b2cf59SMatthew Knepley . step - The current step of the iteration
250976b2cf59SMatthew Knepley 
2510205452f4SMatthew Knepley   Level: intermediate
2511205452f4SMatthew Knepley 
251276b2cf59SMatthew Knepley .keywords: SNES, update
2513a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
251476b2cf59SMatthew Knepley @*/
25157087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
251676b2cf59SMatthew Knepley {
251776b2cf59SMatthew Knepley   PetscFunctionBegin;
251876b2cf59SMatthew Knepley   PetscFunctionReturn(0);
251976b2cf59SMatthew Knepley }
252076b2cf59SMatthew Knepley 
25214a2ae208SSatish Balay #undef __FUNCT__
25224a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
25239b94acceSBarry Smith /*
25249b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
25259b94acceSBarry Smith    positive parameter delta.
25269b94acceSBarry Smith 
25279b94acceSBarry Smith     Input Parameters:
2528c7afd0dbSLois Curfman McInnes +   snes - the SNES context
25299b94acceSBarry Smith .   y - approximate solution of linear system
25309b94acceSBarry Smith .   fnorm - 2-norm of current function
2531c7afd0dbSLois Curfman McInnes -   delta - trust region size
25329b94acceSBarry Smith 
25339b94acceSBarry Smith     Output Parameters:
2534c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
25359b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
25369b94acceSBarry Smith     region, and exceeds zero otherwise.
2537c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
25389b94acceSBarry Smith 
25399b94acceSBarry Smith     Note:
25404b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
25419b94acceSBarry Smith     is set to be the maximum allowable step size.
25429b94acceSBarry Smith 
25439b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
25449b94acceSBarry Smith */
2545dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
25469b94acceSBarry Smith {
2547064f8208SBarry Smith   PetscReal      nrm;
2548ea709b57SSatish Balay   PetscScalar    cnorm;
2549dfbe8321SBarry Smith   PetscErrorCode ierr;
25503a40ed3dSBarry Smith 
25513a40ed3dSBarry Smith   PetscFunctionBegin;
25520700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
25530700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
2554c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
2555184914b5SBarry Smith 
2556064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
2557064f8208SBarry Smith   if (nrm > *delta) {
2558064f8208SBarry Smith      nrm = *delta/nrm;
2559064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
2560064f8208SBarry Smith      cnorm = nrm;
25612dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
25629b94acceSBarry Smith      *ynorm = *delta;
25639b94acceSBarry Smith   } else {
25649b94acceSBarry Smith      *gpnorm = 0.0;
2565064f8208SBarry Smith      *ynorm = nrm;
25669b94acceSBarry Smith   }
25673a40ed3dSBarry Smith   PetscFunctionReturn(0);
25689b94acceSBarry Smith }
25699b94acceSBarry Smith 
25704a2ae208SSatish Balay #undef __FUNCT__
25714a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
25726ce558aeSBarry Smith /*@C
2573f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
2574f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
25759b94acceSBarry Smith 
2576c7afd0dbSLois Curfman McInnes    Collective on SNES
2577c7afd0dbSLois Curfman McInnes 
2578b2002411SLois Curfman McInnes    Input Parameters:
2579c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2580f69a0ea3SMatthew Knepley .  b - the constant part of the equation, or PETSC_NULL to use zero.
258185385478SLisandro Dalcin -  x - the solution vector.
25829b94acceSBarry Smith 
2583b2002411SLois Curfman McInnes    Notes:
25848ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
25858ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
25868ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
25878ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
25888ddd3da0SLois Curfman McInnes 
258936851e7fSLois Curfman McInnes    Level: beginner
259036851e7fSLois Curfman McInnes 
25919b94acceSBarry Smith .keywords: SNES, nonlinear, solve
25929b94acceSBarry Smith 
259385385478SLisandro Dalcin .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian()
25949b94acceSBarry Smith @*/
25957087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
25969b94acceSBarry Smith {
2597dfbe8321SBarry Smith   PetscErrorCode ierr;
2598ace3abfcSBarry Smith   PetscBool      flg;
2599eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
2600eabae89aSBarry Smith   PetscViewer    viewer;
2601efd51863SBarry Smith   PetscInt       grid;
2602052efed2SBarry Smith 
26033a40ed3dSBarry Smith   PetscFunctionBegin;
26040700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
26050700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
2606f69a0ea3SMatthew Knepley   PetscCheckSameComm(snes,1,x,3);
26070700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
260885385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
260985385478SLisandro Dalcin 
2610a8248277SBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);}
2611efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
2612efd51863SBarry Smith 
261385385478SLisandro Dalcin     /* set solution vector */
2614efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
26156bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
261685385478SLisandro Dalcin     snes->vec_sol = x;
261785385478SLisandro Dalcin     /* set afine vector if provided */
261885385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
26196bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
262085385478SLisandro Dalcin     snes->vec_rhs = b;
262185385478SLisandro Dalcin 
262270e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
26233f149594SLisandro Dalcin 
2624d25893d9SBarry Smith     if (!grid && snes->ops->computeinitialguess) {
2625d25893d9SBarry Smith       ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
2626d25893d9SBarry Smith     }
2627d25893d9SBarry Smith 
2628abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
262950ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
2630d5e45103SBarry Smith 
26313f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
26324936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
263385385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
26344936397dSBarry Smith     if (snes->domainerror){
26354936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
26364936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
26374936397dSBarry Smith     }
263817186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
26393f149594SLisandro Dalcin 
26407adad957SLisandro Dalcin     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
2641eabae89aSBarry Smith     if (flg && !PetscPreLoadingOn) {
26427adad957SLisandro Dalcin       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
2643eabae89aSBarry Smith       ierr = SNESView(snes,viewer);CHKERRQ(ierr);
26446bf464f9SBarry Smith       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
2645eabae89aSBarry Smith     }
2646eabae89aSBarry Smith 
264790d69ab7SBarry Smith     flg  = PETSC_FALSE;
2648acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
2649da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
26505968eb51SBarry Smith     if (snes->printreason) {
2651a8248277SBarry Smith       ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
26525968eb51SBarry Smith       if (snes->reason > 0) {
2653a8248277SBarry Smith         ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr);
26545968eb51SBarry Smith       } else {
2655a8248277SBarry Smith         ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr);
26565968eb51SBarry Smith       }
2657a8248277SBarry Smith       ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
26585968eb51SBarry Smith     }
26595968eb51SBarry Smith 
2660e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
2661efd51863SBarry Smith     if (grid <  snes->gridsequence) {
2662efd51863SBarry Smith       DM  fine;
2663efd51863SBarry Smith       Vec xnew;
2664efd51863SBarry Smith       Mat interp;
2665efd51863SBarry Smith 
2666efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
2667efd51863SBarry Smith       ierr = DMGetInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
2668efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
2669efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
2670efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
2671efd51863SBarry Smith       x    = xnew;
2672efd51863SBarry Smith 
2673efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
2674efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
2675efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
2676a8248277SBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);
2677efd51863SBarry Smith     }
2678efd51863SBarry Smith   }
26793a40ed3dSBarry Smith   PetscFunctionReturn(0);
26809b94acceSBarry Smith }
26819b94acceSBarry Smith 
26829b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
26839b94acceSBarry Smith 
26844a2ae208SSatish Balay #undef __FUNCT__
26854a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
268682bf6240SBarry Smith /*@C
26874b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
26889b94acceSBarry Smith 
2689fee21e36SBarry Smith    Collective on SNES
2690fee21e36SBarry Smith 
2691c7afd0dbSLois Curfman McInnes    Input Parameters:
2692c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2693454a90a3SBarry Smith -  type - a known method
2694c7afd0dbSLois Curfman McInnes 
2695c7afd0dbSLois Curfman McInnes    Options Database Key:
2696454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
2697c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
2698ae12b187SLois Curfman McInnes 
26999b94acceSBarry Smith    Notes:
2700e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
27014b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
2702c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
27034b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
2704c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
27059b94acceSBarry Smith 
2706ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
2707ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
2708ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
2709ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
2710ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
2711ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
2712ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
2713ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
2714ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
2715b0a32e0cSBarry Smith   appropriate method.
271636851e7fSLois Curfman McInnes 
271736851e7fSLois Curfman McInnes   Level: intermediate
2718a703fe33SLois Curfman McInnes 
2719454a90a3SBarry Smith .keywords: SNES, set, type
2720435da068SBarry Smith 
2721435da068SBarry Smith .seealso: SNESType, SNESCreate()
2722435da068SBarry Smith 
27239b94acceSBarry Smith @*/
27247087cfbeSBarry Smith PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
27259b94acceSBarry Smith {
2726dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
2727ace3abfcSBarry Smith   PetscBool      match;
27283a40ed3dSBarry Smith 
27293a40ed3dSBarry Smith   PetscFunctionBegin;
27300700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
27314482741eSBarry Smith   PetscValidCharPointer(type,2);
273282bf6240SBarry Smith 
27336831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
27340f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
273592ff6ae8SBarry Smith 
27364b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
2737e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
273875396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
273975396ef9SLisandro Dalcin   if (snes->ops->destroy) { ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); }
274075396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
274175396ef9SLisandro Dalcin   snes->ops->setup          = 0;
274275396ef9SLisandro Dalcin   snes->ops->solve          = 0;
274375396ef9SLisandro Dalcin   snes->ops->view           = 0;
274475396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
274575396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
274675396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
274775396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
2748454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
274903bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
27509fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
27519fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
27529fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
27539fb22e1aSBarry Smith   }
27549fb22e1aSBarry Smith #endif
27553a40ed3dSBarry Smith   PetscFunctionReturn(0);
27569b94acceSBarry Smith }
27579b94acceSBarry Smith 
2758a847f771SSatish Balay 
27599b94acceSBarry Smith /* --------------------------------------------------------------------- */
27604a2ae208SSatish Balay #undef __FUNCT__
27614a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
276252baeb72SSatish Balay /*@
27639b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
2764f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
27659b94acceSBarry Smith 
2766fee21e36SBarry Smith    Not Collective
2767fee21e36SBarry Smith 
276836851e7fSLois Curfman McInnes    Level: advanced
276936851e7fSLois Curfman McInnes 
27709b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
27719b94acceSBarry Smith 
27729b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
27739b94acceSBarry Smith @*/
27747087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
27759b94acceSBarry Smith {
2776dfbe8321SBarry Smith   PetscErrorCode ierr;
277782bf6240SBarry Smith 
27783a40ed3dSBarry Smith   PetscFunctionBegin;
27791441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
27804c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
27813a40ed3dSBarry Smith   PetscFunctionReturn(0);
27829b94acceSBarry Smith }
27839b94acceSBarry Smith 
27844a2ae208SSatish Balay #undef __FUNCT__
27854a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
27869b94acceSBarry Smith /*@C
27879a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
27889b94acceSBarry Smith 
2789c7afd0dbSLois Curfman McInnes    Not Collective
2790c7afd0dbSLois Curfman McInnes 
27919b94acceSBarry Smith    Input Parameter:
27924b0e389bSBarry Smith .  snes - nonlinear solver context
27939b94acceSBarry Smith 
27949b94acceSBarry Smith    Output Parameter:
27953a7fca6bSBarry Smith .  type - SNES method (a character string)
27969b94acceSBarry Smith 
279736851e7fSLois Curfman McInnes    Level: intermediate
279836851e7fSLois Curfman McInnes 
2799454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
28009b94acceSBarry Smith @*/
28017087cfbeSBarry Smith PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
28029b94acceSBarry Smith {
28033a40ed3dSBarry Smith   PetscFunctionBegin;
28040700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
28054482741eSBarry Smith   PetscValidPointer(type,2);
28067adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
28073a40ed3dSBarry Smith   PetscFunctionReturn(0);
28089b94acceSBarry Smith }
28099b94acceSBarry Smith 
28104a2ae208SSatish Balay #undef __FUNCT__
28114a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
281252baeb72SSatish Balay /*@
28139b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
28149b94acceSBarry Smith    stored.
28159b94acceSBarry Smith 
2816c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
2817c7afd0dbSLois Curfman McInnes 
28189b94acceSBarry Smith    Input Parameter:
28199b94acceSBarry Smith .  snes - the SNES context
28209b94acceSBarry Smith 
28219b94acceSBarry Smith    Output Parameter:
28229b94acceSBarry Smith .  x - the solution
28239b94acceSBarry Smith 
282470e92668SMatthew Knepley    Level: intermediate
282536851e7fSLois Curfman McInnes 
28269b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
28279b94acceSBarry Smith 
282885385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
28299b94acceSBarry Smith @*/
28307087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
28319b94acceSBarry Smith {
28323a40ed3dSBarry Smith   PetscFunctionBegin;
28330700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
28344482741eSBarry Smith   PetscValidPointer(x,2);
283585385478SLisandro Dalcin   *x = snes->vec_sol;
283670e92668SMatthew Knepley   PetscFunctionReturn(0);
283770e92668SMatthew Knepley }
283870e92668SMatthew Knepley 
283970e92668SMatthew Knepley #undef __FUNCT__
28404a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
284152baeb72SSatish Balay /*@
28429b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
28439b94acceSBarry Smith    stored.
28449b94acceSBarry Smith 
2845c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
2846c7afd0dbSLois Curfman McInnes 
28479b94acceSBarry Smith    Input Parameter:
28489b94acceSBarry Smith .  snes - the SNES context
28499b94acceSBarry Smith 
28509b94acceSBarry Smith    Output Parameter:
28519b94acceSBarry Smith .  x - the solution update
28529b94acceSBarry Smith 
285336851e7fSLois Curfman McInnes    Level: advanced
285436851e7fSLois Curfman McInnes 
28559b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
28569b94acceSBarry Smith 
285785385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
28589b94acceSBarry Smith @*/
28597087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
28609b94acceSBarry Smith {
28613a40ed3dSBarry Smith   PetscFunctionBegin;
28620700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
28634482741eSBarry Smith   PetscValidPointer(x,2);
286485385478SLisandro Dalcin   *x = snes->vec_sol_update;
28653a40ed3dSBarry Smith   PetscFunctionReturn(0);
28669b94acceSBarry Smith }
28679b94acceSBarry Smith 
28684a2ae208SSatish Balay #undef __FUNCT__
28694a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
28709b94acceSBarry Smith /*@C
28713638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
28729b94acceSBarry Smith 
2873c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
2874c7afd0dbSLois Curfman McInnes 
28759b94acceSBarry Smith    Input Parameter:
28769b94acceSBarry Smith .  snes - the SNES context
28779b94acceSBarry Smith 
28789b94acceSBarry Smith    Output Parameter:
28797bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
288070e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
288170e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
28829b94acceSBarry Smith 
288336851e7fSLois Curfman McInnes    Level: advanced
288436851e7fSLois Curfman McInnes 
2885a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
28869b94acceSBarry Smith 
28874b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
28889b94acceSBarry Smith @*/
28897087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
28909b94acceSBarry Smith {
28913a40ed3dSBarry Smith   PetscFunctionBegin;
28920700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
289385385478SLisandro Dalcin   if (r)    *r    = snes->vec_func;
2894e7788613SBarry Smith   if (func) *func = snes->ops->computefunction;
289570e92668SMatthew Knepley   if (ctx)  *ctx  = snes->funP;
28963a40ed3dSBarry Smith   PetscFunctionReturn(0);
28979b94acceSBarry Smith }
28989b94acceSBarry Smith 
28994a2ae208SSatish Balay #undef __FUNCT__
29004a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
29013c7409f5SSatish Balay /*@C
29023c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
2903d850072dSLois Curfman McInnes    SNES options in the database.
29043c7409f5SSatish Balay 
29053f9fe445SBarry Smith    Logically Collective on SNES
2906fee21e36SBarry Smith 
2907c7afd0dbSLois Curfman McInnes    Input Parameter:
2908c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2909c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
2910c7afd0dbSLois Curfman McInnes 
2911d850072dSLois Curfman McInnes    Notes:
2912a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
2913c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
2914d850072dSLois Curfman McInnes 
291536851e7fSLois Curfman McInnes    Level: advanced
291636851e7fSLois Curfman McInnes 
29173c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
2918a86d99e1SLois Curfman McInnes 
2919a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
29203c7409f5SSatish Balay @*/
29217087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
29223c7409f5SSatish Balay {
2923dfbe8321SBarry Smith   PetscErrorCode ierr;
29243c7409f5SSatish Balay 
29253a40ed3dSBarry Smith   PetscFunctionBegin;
29260700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2927639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
29281cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
292994b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
29303a40ed3dSBarry Smith   PetscFunctionReturn(0);
29313c7409f5SSatish Balay }
29323c7409f5SSatish Balay 
29334a2ae208SSatish Balay #undef __FUNCT__
29344a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
29353c7409f5SSatish Balay /*@C
2936f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
2937d850072dSLois Curfman McInnes    SNES options in the database.
29383c7409f5SSatish Balay 
29393f9fe445SBarry Smith    Logically Collective on SNES
2940fee21e36SBarry Smith 
2941c7afd0dbSLois Curfman McInnes    Input Parameters:
2942c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2943c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
2944c7afd0dbSLois Curfman McInnes 
2945d850072dSLois Curfman McInnes    Notes:
2946a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
2947c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
2948d850072dSLois Curfman McInnes 
294936851e7fSLois Curfman McInnes    Level: advanced
295036851e7fSLois Curfman McInnes 
29513c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
2952a86d99e1SLois Curfman McInnes 
2953a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
29543c7409f5SSatish Balay @*/
29557087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
29563c7409f5SSatish Balay {
2957dfbe8321SBarry Smith   PetscErrorCode ierr;
29583c7409f5SSatish Balay 
29593a40ed3dSBarry Smith   PetscFunctionBegin;
29600700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2961639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
29621cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
296394b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
29643a40ed3dSBarry Smith   PetscFunctionReturn(0);
29653c7409f5SSatish Balay }
29663c7409f5SSatish Balay 
29674a2ae208SSatish Balay #undef __FUNCT__
29684a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
29699ab63eb5SSatish Balay /*@C
29703c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
29713c7409f5SSatish Balay    SNES options in the database.
29723c7409f5SSatish Balay 
2973c7afd0dbSLois Curfman McInnes    Not Collective
2974c7afd0dbSLois Curfman McInnes 
29753c7409f5SSatish Balay    Input Parameter:
29763c7409f5SSatish Balay .  snes - the SNES context
29773c7409f5SSatish Balay 
29783c7409f5SSatish Balay    Output Parameter:
29793c7409f5SSatish Balay .  prefix - pointer to the prefix string used
29803c7409f5SSatish Balay 
29814ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
29829ab63eb5SSatish Balay    sufficient length to hold the prefix.
29839ab63eb5SSatish Balay 
298436851e7fSLois Curfman McInnes    Level: advanced
298536851e7fSLois Curfman McInnes 
29863c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
2987a86d99e1SLois Curfman McInnes 
2988a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
29893c7409f5SSatish Balay @*/
29907087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
29913c7409f5SSatish Balay {
2992dfbe8321SBarry Smith   PetscErrorCode ierr;
29933c7409f5SSatish Balay 
29943a40ed3dSBarry Smith   PetscFunctionBegin;
29950700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2996639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
29973a40ed3dSBarry Smith   PetscFunctionReturn(0);
29983c7409f5SSatish Balay }
29993c7409f5SSatish Balay 
3000b2002411SLois Curfman McInnes 
30014a2ae208SSatish Balay #undef __FUNCT__
30024a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
30033cea93caSBarry Smith /*@C
30043cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
30053cea93caSBarry Smith 
30067f6c08e0SMatthew Knepley   Level: advanced
30073cea93caSBarry Smith @*/
30087087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
3009b2002411SLois Curfman McInnes {
3010e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
3011dfbe8321SBarry Smith   PetscErrorCode ierr;
3012b2002411SLois Curfman McInnes 
3013b2002411SLois Curfman McInnes   PetscFunctionBegin;
3014b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3015c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3016b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
3017b2002411SLois Curfman McInnes }
3018da9b6338SBarry Smith 
3019da9b6338SBarry Smith #undef __FUNCT__
3020da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
30217087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
3022da9b6338SBarry Smith {
3023dfbe8321SBarry Smith   PetscErrorCode ierr;
302477431f27SBarry Smith   PetscInt       N,i,j;
3025da9b6338SBarry Smith   Vec            u,uh,fh;
3026da9b6338SBarry Smith   PetscScalar    value;
3027da9b6338SBarry Smith   PetscReal      norm;
3028da9b6338SBarry Smith 
3029da9b6338SBarry Smith   PetscFunctionBegin;
3030da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
3031da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
3032da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
3033da9b6338SBarry Smith 
3034da9b6338SBarry Smith   /* currently only works for sequential */
3035da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
3036da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
3037da9b6338SBarry Smith   for (i=0; i<N; i++) {
3038da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
303977431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
3040da9b6338SBarry Smith     for (j=-10; j<11; j++) {
3041ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
3042da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
30433ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
3044da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
304577431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
3046da9b6338SBarry Smith       value = -value;
3047da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
3048da9b6338SBarry Smith     }
3049da9b6338SBarry Smith   }
30506bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
30516bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
3052da9b6338SBarry Smith   PetscFunctionReturn(0);
3053da9b6338SBarry Smith }
305471f87433Sdalcinl 
305571f87433Sdalcinl #undef __FUNCT__
3056fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
305771f87433Sdalcinl /*@
3058fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
305971f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
306071f87433Sdalcinl    Newton method.
306171f87433Sdalcinl 
30623f9fe445SBarry Smith    Logically Collective on SNES
306371f87433Sdalcinl 
306471f87433Sdalcinl    Input Parameters:
306571f87433Sdalcinl +  snes - SNES context
306671f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
306771f87433Sdalcinl 
306864ba62caSBarry Smith     Options Database:
306964ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
307064ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
307164ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
307264ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
307364ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
307464ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
307564ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
307664ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
307764ba62caSBarry Smith 
307871f87433Sdalcinl    Notes:
307971f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
308071f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
308171f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
308271f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
308371f87433Sdalcinl    solver.
308471f87433Sdalcinl 
308571f87433Sdalcinl    Level: advanced
308671f87433Sdalcinl 
308771f87433Sdalcinl    Reference:
308871f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
308971f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
309071f87433Sdalcinl 
309171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
309271f87433Sdalcinl 
3093fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
309471f87433Sdalcinl @*/
30957087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
309671f87433Sdalcinl {
309771f87433Sdalcinl   PetscFunctionBegin;
30980700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3099acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
310071f87433Sdalcinl   snes->ksp_ewconv = flag;
310171f87433Sdalcinl   PetscFunctionReturn(0);
310271f87433Sdalcinl }
310371f87433Sdalcinl 
310471f87433Sdalcinl #undef __FUNCT__
3105fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
310671f87433Sdalcinl /*@
3107fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
310871f87433Sdalcinl    for computing relative tolerance for linear solvers within an
310971f87433Sdalcinl    inexact Newton method.
311071f87433Sdalcinl 
311171f87433Sdalcinl    Not Collective
311271f87433Sdalcinl 
311371f87433Sdalcinl    Input Parameter:
311471f87433Sdalcinl .  snes - SNES context
311571f87433Sdalcinl 
311671f87433Sdalcinl    Output Parameter:
311771f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
311871f87433Sdalcinl 
311971f87433Sdalcinl    Notes:
312071f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
312171f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
312271f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
312371f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
312471f87433Sdalcinl    solver.
312571f87433Sdalcinl 
312671f87433Sdalcinl    Level: advanced
312771f87433Sdalcinl 
312871f87433Sdalcinl    Reference:
312971f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
313071f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
313171f87433Sdalcinl 
313271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
313371f87433Sdalcinl 
3134fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
313571f87433Sdalcinl @*/
31367087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
313771f87433Sdalcinl {
313871f87433Sdalcinl   PetscFunctionBegin;
31390700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
314071f87433Sdalcinl   PetscValidPointer(flag,2);
314171f87433Sdalcinl   *flag = snes->ksp_ewconv;
314271f87433Sdalcinl   PetscFunctionReturn(0);
314371f87433Sdalcinl }
314471f87433Sdalcinl 
314571f87433Sdalcinl #undef __FUNCT__
3146fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
314771f87433Sdalcinl /*@
3148fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
314971f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
315071f87433Sdalcinl    Newton method.
315171f87433Sdalcinl 
31523f9fe445SBarry Smith    Logically Collective on SNES
315371f87433Sdalcinl 
315471f87433Sdalcinl    Input Parameters:
315571f87433Sdalcinl +    snes - SNES context
315671f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
315771f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
315871f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
315971f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
316071f87433Sdalcinl              (0 <= gamma2 <= 1)
316171f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
316271f87433Sdalcinl .    alpha2 - power for safeguard
316371f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
316471f87433Sdalcinl 
316571f87433Sdalcinl    Note:
316671f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
316771f87433Sdalcinl 
316871f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
316971f87433Sdalcinl 
317071f87433Sdalcinl    Level: advanced
317171f87433Sdalcinl 
317271f87433Sdalcinl    Reference:
317371f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
317471f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
317571f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
317671f87433Sdalcinl 
317771f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
317871f87433Sdalcinl 
3179fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
318071f87433Sdalcinl @*/
31817087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
318271f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
318371f87433Sdalcinl {
3184fa9f3622SBarry Smith   SNESKSPEW *kctx;
318571f87433Sdalcinl   PetscFunctionBegin;
31860700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3187fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3188e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
3189c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
3190c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
3191c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
3192c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
3193c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
3194c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
3195c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
319671f87433Sdalcinl 
319771f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
319871f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
319971f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
320071f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
320171f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
320271f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
320371f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
320471f87433Sdalcinl 
320571f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
3206e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
320771f87433Sdalcinl   }
320871f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
3209e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
321071f87433Sdalcinl   }
321171f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
3212e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
321371f87433Sdalcinl   }
321471f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
3215e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
321671f87433Sdalcinl   }
321771f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
3218e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
321971f87433Sdalcinl   }
322071f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
3221e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
322271f87433Sdalcinl   }
322371f87433Sdalcinl   PetscFunctionReturn(0);
322471f87433Sdalcinl }
322571f87433Sdalcinl 
322671f87433Sdalcinl #undef __FUNCT__
3227fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
322871f87433Sdalcinl /*@
3229fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
323071f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
323171f87433Sdalcinl    Newton method.
323271f87433Sdalcinl 
323371f87433Sdalcinl    Not Collective
323471f87433Sdalcinl 
323571f87433Sdalcinl    Input Parameters:
323671f87433Sdalcinl      snes - SNES context
323771f87433Sdalcinl 
323871f87433Sdalcinl    Output Parameters:
323971f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
324071f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
324171f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
324271f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
324371f87433Sdalcinl              (0 <= gamma2 <= 1)
324471f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
324571f87433Sdalcinl .    alpha2 - power for safeguard
324671f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
324771f87433Sdalcinl 
324871f87433Sdalcinl    Level: advanced
324971f87433Sdalcinl 
325071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
325171f87433Sdalcinl 
3252fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
325371f87433Sdalcinl @*/
32547087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
325571f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
325671f87433Sdalcinl {
3257fa9f3622SBarry Smith   SNESKSPEW *kctx;
325871f87433Sdalcinl   PetscFunctionBegin;
32590700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3260fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3261e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
326271f87433Sdalcinl   if(version)   *version   = kctx->version;
326371f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
326471f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
326571f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
326671f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
326771f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
326871f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
326971f87433Sdalcinl   PetscFunctionReturn(0);
327071f87433Sdalcinl }
327171f87433Sdalcinl 
327271f87433Sdalcinl #undef __FUNCT__
3273fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
3274fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
327571f87433Sdalcinl {
327671f87433Sdalcinl   PetscErrorCode ierr;
3277fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
327871f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
327971f87433Sdalcinl 
328071f87433Sdalcinl   PetscFunctionBegin;
3281e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
328271f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
328371f87433Sdalcinl     rtol = kctx->rtol_0;
328471f87433Sdalcinl   } else {
328571f87433Sdalcinl     if (kctx->version == 1) {
328671f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
328771f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
328871f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
328971f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
329071f87433Sdalcinl     } else if (kctx->version == 2) {
329171f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
329271f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
329371f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
329471f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
329571f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
329671f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
329771f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
329871f87433Sdalcinl       stol = PetscMax(rtol,stol);
329971f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
330071f87433Sdalcinl       /* safeguard: avoid oversolving */
330171f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
330271f87433Sdalcinl       stol = PetscMax(rtol,stol);
330371f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
3304e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
330571f87433Sdalcinl   }
330671f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
330771f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
330871f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
330971f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
331071f87433Sdalcinl   PetscFunctionReturn(0);
331171f87433Sdalcinl }
331271f87433Sdalcinl 
331371f87433Sdalcinl #undef __FUNCT__
3314fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
3315fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
331671f87433Sdalcinl {
331771f87433Sdalcinl   PetscErrorCode ierr;
3318fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
331971f87433Sdalcinl   PCSide         pcside;
332071f87433Sdalcinl   Vec            lres;
332171f87433Sdalcinl 
332271f87433Sdalcinl   PetscFunctionBegin;
3323e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
332471f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
332571f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
332671f87433Sdalcinl   if (kctx->version == 1) {
3327b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
332871f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
332971f87433Sdalcinl       /* KSP residual is true linear residual */
333071f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
333171f87433Sdalcinl     } else {
333271f87433Sdalcinl       /* KSP residual is preconditioned residual */
333371f87433Sdalcinl       /* compute true linear residual norm */
333471f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
333571f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
333671f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
333771f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
33386bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
333971f87433Sdalcinl     }
334071f87433Sdalcinl   }
334171f87433Sdalcinl   PetscFunctionReturn(0);
334271f87433Sdalcinl }
334371f87433Sdalcinl 
334471f87433Sdalcinl #undef __FUNCT__
334571f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
334671f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
334771f87433Sdalcinl {
334871f87433Sdalcinl   PetscErrorCode ierr;
334971f87433Sdalcinl 
335071f87433Sdalcinl   PetscFunctionBegin;
3351fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
335271f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
3353fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
335471f87433Sdalcinl   PetscFunctionReturn(0);
335571f87433Sdalcinl }
33566c699258SBarry Smith 
33576c699258SBarry Smith #undef __FUNCT__
33586c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
33596c699258SBarry Smith /*@
33606c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
33616c699258SBarry Smith 
33623f9fe445SBarry Smith    Logically Collective on SNES
33636c699258SBarry Smith 
33646c699258SBarry Smith    Input Parameters:
33656c699258SBarry Smith +  snes - the preconditioner context
33666c699258SBarry Smith -  dm - the dm
33676c699258SBarry Smith 
33686c699258SBarry Smith    Level: intermediate
33696c699258SBarry Smith 
33706c699258SBarry Smith 
33716c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
33726c699258SBarry Smith @*/
33737087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
33746c699258SBarry Smith {
33756c699258SBarry Smith   PetscErrorCode ierr;
3376345fed2cSBarry Smith   KSP            ksp;
33776c699258SBarry Smith 
33786c699258SBarry Smith   PetscFunctionBegin;
33790700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3380d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
33816bf464f9SBarry Smith   ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
33826c699258SBarry Smith   snes->dm = dm;
3383345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
3384345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
3385f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
33866c699258SBarry Smith   PetscFunctionReturn(0);
33876c699258SBarry Smith }
33886c699258SBarry Smith 
33896c699258SBarry Smith #undef __FUNCT__
33906c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
33916c699258SBarry Smith /*@
33926c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
33936c699258SBarry Smith 
33943f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
33956c699258SBarry Smith 
33966c699258SBarry Smith    Input Parameter:
33976c699258SBarry Smith . snes - the preconditioner context
33986c699258SBarry Smith 
33996c699258SBarry Smith    Output Parameter:
34006c699258SBarry Smith .  dm - the dm
34016c699258SBarry Smith 
34026c699258SBarry Smith    Level: intermediate
34036c699258SBarry Smith 
34046c699258SBarry Smith 
34056c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
34066c699258SBarry Smith @*/
34077087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
34086c699258SBarry Smith {
34096c699258SBarry Smith   PetscFunctionBegin;
34100700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
34116c699258SBarry Smith   *dm = snes->dm;
34126c699258SBarry Smith   PetscFunctionReturn(0);
34136c699258SBarry Smith }
34140807856dSBarry Smith 
341531823bd8SMatthew G Knepley #undef __FUNCT__
341631823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
341731823bd8SMatthew G Knepley /*@
341831823bd8SMatthew G Knepley   SNESSetPC - Sets the preconditioner to be used.
341931823bd8SMatthew G Knepley 
342031823bd8SMatthew G Knepley   Collective on SNES
342131823bd8SMatthew G Knepley 
342231823bd8SMatthew G Knepley   Input Parameters:
342331823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
342431823bd8SMatthew G Knepley - pc   - the preconditioner object
342531823bd8SMatthew G Knepley 
342631823bd8SMatthew G Knepley   Notes:
342731823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
342831823bd8SMatthew G Knepley   to configure it using the API).
342931823bd8SMatthew G Knepley 
343031823bd8SMatthew G Knepley   Level: developer
343131823bd8SMatthew G Knepley 
343231823bd8SMatthew G Knepley .keywords: SNES, set, precondition
343331823bd8SMatthew G Knepley .seealso: SNESGetPC()
343431823bd8SMatthew G Knepley @*/
343531823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
343631823bd8SMatthew G Knepley {
343731823bd8SMatthew G Knepley   PetscErrorCode ierr;
343831823bd8SMatthew G Knepley 
343931823bd8SMatthew G Knepley   PetscFunctionBegin;
344031823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
344131823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
344231823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
344331823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
3444bf11d3b6SBarry Smith   ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr);
344531823bd8SMatthew G Knepley   snes->pc = pc;
344631823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
344731823bd8SMatthew G Knepley   PetscFunctionReturn(0);
344831823bd8SMatthew G Knepley }
344931823bd8SMatthew G Knepley 
345031823bd8SMatthew G Knepley #undef __FUNCT__
345131823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
345231823bd8SMatthew G Knepley /*@
345331823bd8SMatthew G Knepley   SNESGetPC - Returns a pointer to the preconditioner context set with SNESSetPC().
345431823bd8SMatthew G Knepley 
345531823bd8SMatthew G Knepley   Not Collective
345631823bd8SMatthew G Knepley 
345731823bd8SMatthew G Knepley   Input Parameter:
345831823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
345931823bd8SMatthew G Knepley 
346031823bd8SMatthew G Knepley   Output Parameter:
346131823bd8SMatthew G Knepley . pc - preconditioner context
346231823bd8SMatthew G Knepley 
346331823bd8SMatthew G Knepley   Level: developer
346431823bd8SMatthew G Knepley 
346531823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
346631823bd8SMatthew G Knepley .seealso: SNESSetPC()
346731823bd8SMatthew G Knepley @*/
346831823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
346931823bd8SMatthew G Knepley {
347031823bd8SMatthew G Knepley   PetscErrorCode ierr;
347131823bd8SMatthew G Knepley 
347231823bd8SMatthew G Knepley   PetscFunctionBegin;
347331823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
347431823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
347531823bd8SMatthew G Knepley   if (!snes->pc) {
347631823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr);
347731823bd8SMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 0);CHKERRQ(ierr);
347831823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
347931823bd8SMatthew G Knepley   }
348031823bd8SMatthew G Knepley   *pc = snes->pc;
348131823bd8SMatthew G Knepley   PetscFunctionReturn(0);
348231823bd8SMatthew G Knepley }
348331823bd8SMatthew G Knepley 
348469b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3485c6db04a5SJed Brown #include <mex.h>
348669b4f73cSBarry Smith 
34878f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
34888f6e6473SBarry Smith 
34890807856dSBarry Smith #undef __FUNCT__
34900807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
34910807856dSBarry Smith /*
34920807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
34930807856dSBarry Smith                          SNESSetFunctionMatlab().
34940807856dSBarry Smith 
34950807856dSBarry Smith    Collective on SNES
34960807856dSBarry Smith 
34970807856dSBarry Smith    Input Parameters:
34980807856dSBarry Smith +  snes - the SNES context
34990807856dSBarry Smith -  x - input vector
35000807856dSBarry Smith 
35010807856dSBarry Smith    Output Parameter:
35020807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
35030807856dSBarry Smith 
35040807856dSBarry Smith    Notes:
35050807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
35060807856dSBarry Smith    implementations, so most users would not generally call this routine
35070807856dSBarry Smith    themselves.
35080807856dSBarry Smith 
35090807856dSBarry Smith    Level: developer
35100807856dSBarry Smith 
35110807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
35120807856dSBarry Smith 
35130807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
351461b2408cSBarry Smith */
35157087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
35160807856dSBarry Smith {
3517e650e774SBarry Smith   PetscErrorCode    ierr;
35188f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
35198f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
35208f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
352191621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
3522e650e774SBarry Smith 
35230807856dSBarry Smith   PetscFunctionBegin;
35240807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35250807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
35260807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
35270807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
35280807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
35290807856dSBarry Smith 
35300807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
3531e650e774SBarry Smith 
353291621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
3533e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
3534e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
353591621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
353691621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
353791621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
35388f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
35398f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
3540b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
3541e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
3542e650e774SBarry Smith   mxDestroyArray(prhs[0]);
3543e650e774SBarry Smith   mxDestroyArray(prhs[1]);
3544e650e774SBarry Smith   mxDestroyArray(prhs[2]);
35458f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
3546e650e774SBarry Smith   mxDestroyArray(plhs[0]);
35470807856dSBarry Smith   PetscFunctionReturn(0);
35480807856dSBarry Smith }
35490807856dSBarry Smith 
35500807856dSBarry Smith 
35510807856dSBarry Smith #undef __FUNCT__
35520807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
355361b2408cSBarry Smith /*
35540807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
35550807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
3556e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
35570807856dSBarry Smith 
35580807856dSBarry Smith    Logically Collective on SNES
35590807856dSBarry Smith 
35600807856dSBarry Smith    Input Parameters:
35610807856dSBarry Smith +  snes - the SNES context
35620807856dSBarry Smith .  r - vector to store function value
35630807856dSBarry Smith -  func - function evaluation routine
35640807856dSBarry Smith 
35650807856dSBarry Smith    Calling sequence of func:
356661b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
35670807856dSBarry Smith 
35680807856dSBarry Smith 
35690807856dSBarry Smith    Notes:
35700807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
35710807856dSBarry Smith $      f'(x) x = -f(x),
35720807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
35730807856dSBarry Smith 
35740807856dSBarry Smith    Level: beginner
35750807856dSBarry Smith 
35760807856dSBarry Smith .keywords: SNES, nonlinear, set, function
35770807856dSBarry Smith 
35780807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
357961b2408cSBarry Smith */
35807087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
35810807856dSBarry Smith {
35820807856dSBarry Smith   PetscErrorCode    ierr;
35838f6e6473SBarry Smith   SNESMatlabContext *sctx;
35840807856dSBarry Smith 
35850807856dSBarry Smith   PetscFunctionBegin;
35868f6e6473SBarry Smith   /* currently sctx is memory bleed */
35878f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
35888f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
35898f6e6473SBarry Smith   /*
35908f6e6473SBarry Smith      This should work, but it doesn't
35918f6e6473SBarry Smith   sctx->ctx = ctx;
35928f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
35938f6e6473SBarry Smith   */
35948f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
35958f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
35960807856dSBarry Smith   PetscFunctionReturn(0);
35970807856dSBarry Smith }
359869b4f73cSBarry Smith 
359961b2408cSBarry Smith #undef __FUNCT__
360061b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
360161b2408cSBarry Smith /*
360261b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
360361b2408cSBarry Smith                          SNESSetJacobianMatlab().
360461b2408cSBarry Smith 
360561b2408cSBarry Smith    Collective on SNES
360661b2408cSBarry Smith 
360761b2408cSBarry Smith    Input Parameters:
360861b2408cSBarry Smith +  snes - the SNES context
360961b2408cSBarry Smith .  x - input vector
361061b2408cSBarry Smith .  A, B - the matrices
361161b2408cSBarry Smith -  ctx - user context
361261b2408cSBarry Smith 
361361b2408cSBarry Smith    Output Parameter:
361461b2408cSBarry Smith .  flag - structure of the matrix
361561b2408cSBarry Smith 
361661b2408cSBarry Smith    Level: developer
361761b2408cSBarry Smith 
361861b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
361961b2408cSBarry Smith 
362061b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
362161b2408cSBarry Smith @*/
36227087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
362361b2408cSBarry Smith {
362461b2408cSBarry Smith   PetscErrorCode    ierr;
362561b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
362661b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
362761b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
362861b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
362961b2408cSBarry Smith 
363061b2408cSBarry Smith   PetscFunctionBegin;
363161b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
363261b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
363361b2408cSBarry Smith 
363461b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
363561b2408cSBarry Smith 
363661b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
363761b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
363861b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
363961b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
364061b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
364161b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
364261b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
364361b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
364461b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
364561b2408cSBarry Smith   prhs[5] =  sctx->ctx;
3646b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
364761b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
364861b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
364961b2408cSBarry Smith   mxDestroyArray(prhs[0]);
365061b2408cSBarry Smith   mxDestroyArray(prhs[1]);
365161b2408cSBarry Smith   mxDestroyArray(prhs[2]);
365261b2408cSBarry Smith   mxDestroyArray(prhs[3]);
365361b2408cSBarry Smith   mxDestroyArray(prhs[4]);
365461b2408cSBarry Smith   mxDestroyArray(plhs[0]);
365561b2408cSBarry Smith   mxDestroyArray(plhs[1]);
365661b2408cSBarry Smith   PetscFunctionReturn(0);
365761b2408cSBarry Smith }
365861b2408cSBarry Smith 
365961b2408cSBarry Smith 
366061b2408cSBarry Smith #undef __FUNCT__
366161b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
366261b2408cSBarry Smith /*
366361b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
366461b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
3665e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
366661b2408cSBarry Smith 
366761b2408cSBarry Smith    Logically Collective on SNES
366861b2408cSBarry Smith 
366961b2408cSBarry Smith    Input Parameters:
367061b2408cSBarry Smith +  snes - the SNES context
367161b2408cSBarry Smith .  A,B - Jacobian matrices
367261b2408cSBarry Smith .  func - function evaluation routine
367361b2408cSBarry Smith -  ctx - user context
367461b2408cSBarry Smith 
367561b2408cSBarry Smith    Calling sequence of func:
367661b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
367761b2408cSBarry Smith 
367861b2408cSBarry Smith 
367961b2408cSBarry Smith    Level: developer
368061b2408cSBarry Smith 
368161b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
368261b2408cSBarry Smith 
368361b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
368461b2408cSBarry Smith */
36857087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
368661b2408cSBarry Smith {
368761b2408cSBarry Smith   PetscErrorCode    ierr;
368861b2408cSBarry Smith   SNESMatlabContext *sctx;
368961b2408cSBarry Smith 
369061b2408cSBarry Smith   PetscFunctionBegin;
369161b2408cSBarry Smith   /* currently sctx is memory bleed */
369261b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
369361b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
369461b2408cSBarry Smith   /*
369561b2408cSBarry Smith      This should work, but it doesn't
369661b2408cSBarry Smith   sctx->ctx = ctx;
369761b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
369861b2408cSBarry Smith   */
369961b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
370061b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
370161b2408cSBarry Smith   PetscFunctionReturn(0);
370261b2408cSBarry Smith }
370369b4f73cSBarry Smith 
3704f9eb7ae2SShri Abhyankar #undef __FUNCT__
3705f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
3706f9eb7ae2SShri Abhyankar /*
3707f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
3708f9eb7ae2SShri Abhyankar 
3709f9eb7ae2SShri Abhyankar    Collective on SNES
3710f9eb7ae2SShri Abhyankar 
3711f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
3712f9eb7ae2SShri Abhyankar @*/
37137087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
3714f9eb7ae2SShri Abhyankar {
3715f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
371648f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
3717f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
3718f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
3719f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
3720f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
3721f9eb7ae2SShri Abhyankar 
3722f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
3723f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3724f9eb7ae2SShri Abhyankar 
3725f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
3726f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
3727f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
3728f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
3729f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
3730f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
3731f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
3732f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
3733f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
3734f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
3735f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
3736f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
3737f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
3738f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
3739f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
3740f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
3741f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
3742f9eb7ae2SShri Abhyankar }
3743f9eb7ae2SShri Abhyankar 
3744f9eb7ae2SShri Abhyankar 
3745f9eb7ae2SShri Abhyankar #undef __FUNCT__
3746f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
3747f9eb7ae2SShri Abhyankar /*
3748e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
3749f9eb7ae2SShri Abhyankar 
3750f9eb7ae2SShri Abhyankar    Level: developer
3751f9eb7ae2SShri Abhyankar 
3752f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
3753f9eb7ae2SShri Abhyankar 
3754f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
3755f9eb7ae2SShri Abhyankar */
37567087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
3757f9eb7ae2SShri Abhyankar {
3758f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
3759f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
3760f9eb7ae2SShri Abhyankar 
3761f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
3762f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
3763f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
3764f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
3765f9eb7ae2SShri Abhyankar   /*
3766f9eb7ae2SShri Abhyankar      This should work, but it doesn't
3767f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
3768f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
3769f9eb7ae2SShri Abhyankar   */
3770f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
3771f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
3772f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
3773f9eb7ae2SShri Abhyankar }
3774f9eb7ae2SShri Abhyankar 
377569b4f73cSBarry Smith #endif
3776