xref: /petsc/src/snes/interface/snes.c (revision cab2e9cced711b0c3b5f6081f427e1e5aa178814)
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__
12*cab2e9ccSBarry Smith #define __FUNCT__ "SNESDMComputeJacobian"
13*cab2e9ccSBarry Smith /*
14*cab2e9ccSBarry Smith     Translates from a SNES call to a DM call in computing a Jacobian
15*cab2e9ccSBarry Smith */
16*cab2e9ccSBarry Smith PetscErrorCode SNESDMComputeJacobian(SNES snes,Vec X,Mat *J,Mat *B,MatStructure *flag,void *ptr)
17*cab2e9ccSBarry Smith {
18*cab2e9ccSBarry Smith   PetscErrorCode ierr;
19*cab2e9ccSBarry Smith   DM             dm;
20*cab2e9ccSBarry Smith 
21*cab2e9ccSBarry Smith   PetscFunctionBegin;
22*cab2e9ccSBarry Smith   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
23*cab2e9ccSBarry Smith   ierr = DMComputeJacobian(dm,X,*J,*B,flag);CHKERRQ(ierr);
24*cab2e9ccSBarry Smith   PetscFunctionReturn(0);
25*cab2e9ccSBarry Smith }
26*cab2e9ccSBarry Smith 
27*cab2e9ccSBarry Smith #undef __FUNCT__
28e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged"
29e113a28aSBarry Smith /*@
30e113a28aSBarry Smith    SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged.
31e113a28aSBarry Smith 
323f9fe445SBarry Smith    Logically Collective on SNES
33e113a28aSBarry Smith 
34e113a28aSBarry Smith    Input Parameters:
35e113a28aSBarry Smith +  snes - iterative context obtained from SNESCreate()
36e113a28aSBarry Smith -  flg - PETSC_TRUE indicates you want the error generated
37e113a28aSBarry Smith 
38e113a28aSBarry Smith    Options database keys:
39e113a28aSBarry Smith .  -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false)
40e113a28aSBarry Smith 
41e113a28aSBarry Smith    Level: intermediate
42e113a28aSBarry Smith 
43e113a28aSBarry Smith    Notes:
44e113a28aSBarry Smith     Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve()
45e113a28aSBarry Smith     to determine if it has converged.
46e113a28aSBarry Smith 
47e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
48e113a28aSBarry Smith 
49e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
50e113a28aSBarry Smith @*/
517087cfbeSBarry Smith PetscErrorCode  SNESSetErrorIfNotConverged(SNES snes,PetscBool  flg)
52e113a28aSBarry Smith {
53e113a28aSBarry Smith   PetscFunctionBegin;
54e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
55acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flg,2);
56e113a28aSBarry Smith   snes->errorifnotconverged = flg;
57e113a28aSBarry Smith   PetscFunctionReturn(0);
58e113a28aSBarry Smith }
59e113a28aSBarry Smith 
60e113a28aSBarry Smith #undef __FUNCT__
61e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged"
62e113a28aSBarry Smith /*@
63e113a28aSBarry Smith    SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge?
64e113a28aSBarry Smith 
65e113a28aSBarry Smith    Not Collective
66e113a28aSBarry Smith 
67e113a28aSBarry Smith    Input Parameter:
68e113a28aSBarry Smith .  snes - iterative context obtained from SNESCreate()
69e113a28aSBarry Smith 
70e113a28aSBarry Smith    Output Parameter:
71e113a28aSBarry Smith .  flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE
72e113a28aSBarry Smith 
73e113a28aSBarry Smith    Level: intermediate
74e113a28aSBarry Smith 
75e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
76e113a28aSBarry Smith 
77e113a28aSBarry Smith .seealso:  SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
78e113a28aSBarry Smith @*/
797087cfbeSBarry Smith PetscErrorCode  SNESGetErrorIfNotConverged(SNES snes,PetscBool  *flag)
80e113a28aSBarry Smith {
81e113a28aSBarry Smith   PetscFunctionBegin;
82e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
83e113a28aSBarry Smith   PetscValidPointer(flag,2);
84e113a28aSBarry Smith   *flag = snes->errorifnotconverged;
85e113a28aSBarry Smith   PetscFunctionReturn(0);
86e113a28aSBarry Smith }
87e113a28aSBarry Smith 
88e113a28aSBarry Smith #undef __FUNCT__
894936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError"
90e725d27bSBarry Smith /*@
914936397dSBarry Smith    SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not
924936397dSBarry Smith      in the functions domain. For example, negative pressure.
934936397dSBarry Smith 
943f9fe445SBarry Smith    Logically Collective on SNES
954936397dSBarry Smith 
964936397dSBarry Smith    Input Parameters:
974936397dSBarry Smith .  SNES - the SNES context
984936397dSBarry Smith 
9928529972SSatish Balay    Level: advanced
1004936397dSBarry Smith 
1014936397dSBarry Smith .keywords: SNES, view
1024936397dSBarry Smith 
1034936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction()
1044936397dSBarry Smith @*/
1057087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionDomainError(SNES snes)
1064936397dSBarry Smith {
1074936397dSBarry Smith   PetscFunctionBegin;
1080700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1094936397dSBarry Smith   snes->domainerror = PETSC_TRUE;
1104936397dSBarry Smith   PetscFunctionReturn(0);
1114936397dSBarry Smith }
1124936397dSBarry Smith 
1134936397dSBarry Smith #undef __FUNCT__
1144a2ae208SSatish Balay #define __FUNCT__ "SNESView"
1157e2c5f70SBarry Smith /*@C
1169b94acceSBarry Smith    SNESView - Prints the SNES data structure.
1179b94acceSBarry Smith 
1184c49b128SBarry Smith    Collective on SNES
119fee21e36SBarry Smith 
120c7afd0dbSLois Curfman McInnes    Input Parameters:
121c7afd0dbSLois Curfman McInnes +  SNES - the SNES context
122c7afd0dbSLois Curfman McInnes -  viewer - visualization context
123c7afd0dbSLois Curfman McInnes 
1249b94acceSBarry Smith    Options Database Key:
125c8a8ba5cSLois Curfman McInnes .  -snes_view - Calls SNESView() at end of SNESSolve()
1269b94acceSBarry Smith 
1279b94acceSBarry Smith    Notes:
1289b94acceSBarry Smith    The available visualization contexts include
129b0a32e0cSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
130b0a32e0cSBarry Smith -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
131c8a8ba5cSLois Curfman McInnes          output where only the first processor opens
132c8a8ba5cSLois Curfman McInnes          the file.  All other processors send their
133c8a8ba5cSLois Curfman McInnes          data to the first processor to print.
1349b94acceSBarry Smith 
1353e081fefSLois Curfman McInnes    The user can open an alternative visualization context with
136b0a32e0cSBarry Smith    PetscViewerASCIIOpen() - output to a specified file.
1379b94acceSBarry Smith 
13836851e7fSLois Curfman McInnes    Level: beginner
13936851e7fSLois Curfman McInnes 
1409b94acceSBarry Smith .keywords: SNES, view
1419b94acceSBarry Smith 
142b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen()
1439b94acceSBarry Smith @*/
1447087cfbeSBarry Smith PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
1459b94acceSBarry Smith {
146fa9f3622SBarry Smith   SNESKSPEW           *kctx;
147dfbe8321SBarry Smith   PetscErrorCode      ierr;
14894b7f48cSBarry Smith   KSP                 ksp;
149ace3abfcSBarry Smith   PetscBool           iascii,isstring;
1509b94acceSBarry Smith 
1513a40ed3dSBarry Smith   PetscFunctionBegin;
1520700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1533050cee2SBarry Smith   if (!viewer) {
1547adad957SLisandro Dalcin     ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
1553050cee2SBarry Smith   }
1560700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
157c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,viewer,2);
15874679c65SBarry Smith 
1592692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1602692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
16132077d6dSBarry Smith   if (iascii) {
162317d6ea6SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr);
163e7788613SBarry Smith     if (snes->ops->view) {
164b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
165e7788613SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
166b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1670ef38995SBarry Smith     }
16877431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr);
169a83599f4SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%G, absolute=%G, solution=%G\n",
17070441072SBarry Smith                  snes->rtol,snes->abstol,snes->xtol);CHKERRQ(ierr);
17177431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr);
17277431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr);
1739b94acceSBarry Smith     if (snes->ksp_ewconv) {
174fa9f3622SBarry Smith       kctx = (SNESKSPEW *)snes->kspconvctx;
1759b94acceSBarry Smith       if (kctx) {
17677431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr);
177a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr);
178a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr);
1799b94acceSBarry Smith       }
1809b94acceSBarry Smith     }
181eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
182eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");CHKERRQ(ierr);
183eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
184eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr);
185eb1f6c34SBarry Smith     }
186eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
187eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");CHKERRQ(ierr);
188eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
189eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D Newton iterations\n",snes->lagjacobian);CHKERRQ(ierr);
190eb1f6c34SBarry Smith     }
1910f5bd95cSBarry Smith   } else if (isstring) {
192317d6ea6SBarry Smith     const char *type;
193454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
194b0a32e0cSBarry Smith     ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr);
19519bcc07fSBarry Smith   }
19694b7f48cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
197b0a32e0cSBarry Smith   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
19894b7f48cSBarry Smith   ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
199b0a32e0cSBarry Smith   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2003a40ed3dSBarry Smith   PetscFunctionReturn(0);
2019b94acceSBarry Smith }
2029b94acceSBarry Smith 
20376b2cf59SMatthew Knepley /*
20476b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
20576b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
20676b2cf59SMatthew Knepley */
20776b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
208a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
2096849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
21076b2cf59SMatthew Knepley 
211e74ef692SMatthew Knepley #undef __FUNCT__
212e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker"
213ac226902SBarry Smith /*@C
21476b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
21576b2cf59SMatthew Knepley 
21676b2cf59SMatthew Knepley   Not Collective
21776b2cf59SMatthew Knepley 
21876b2cf59SMatthew Knepley   Input Parameter:
21976b2cf59SMatthew Knepley . snescheck - function that checks for options
22076b2cf59SMatthew Knepley 
22176b2cf59SMatthew Knepley   Level: developer
22276b2cf59SMatthew Knepley 
22376b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
22476b2cf59SMatthew Knepley @*/
2257087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
22676b2cf59SMatthew Knepley {
22776b2cf59SMatthew Knepley   PetscFunctionBegin;
22876b2cf59SMatthew Knepley   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
229e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
23076b2cf59SMatthew Knepley   }
23176b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
23276b2cf59SMatthew Knepley   PetscFunctionReturn(0);
23376b2cf59SMatthew Knepley }
23476b2cf59SMatthew Knepley 
2357087cfbeSBarry Smith extern PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
236aa3661deSLisandro Dalcin 
237aa3661deSLisandro Dalcin #undef __FUNCT__
238aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private"
239ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool  hasOperator, PetscInt version)
240aa3661deSLisandro Dalcin {
241aa3661deSLisandro Dalcin   Mat            J;
242aa3661deSLisandro Dalcin   KSP            ksp;
243aa3661deSLisandro Dalcin   PC             pc;
244ace3abfcSBarry Smith   PetscBool      match;
245aa3661deSLisandro Dalcin   PetscErrorCode ierr;
246aa3661deSLisandro Dalcin 
247aa3661deSLisandro Dalcin   PetscFunctionBegin;
2480700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
249aa3661deSLisandro Dalcin 
25098613b67SLisandro Dalcin   if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
25198613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
25298613b67SLisandro Dalcin     ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr);
25398613b67SLisandro Dalcin   }
25498613b67SLisandro Dalcin 
255aa3661deSLisandro Dalcin   if (version == 1) {
256aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
25798613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
2589c6ac3b3SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
259aa3661deSLisandro Dalcin   } else if (version == 2) {
260e32f2f54SBarry Smith     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
261ce63c4c1SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL_LONG_DOUBLE)
262aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
263aa3661deSLisandro Dalcin #else
264e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
265aa3661deSLisandro Dalcin #endif
266aa3661deSLisandro Dalcin   } else {
267e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
268aa3661deSLisandro Dalcin   }
269aa3661deSLisandro Dalcin 
270aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
271d3462f78SMatthew Knepley   if (hasOperator) {
272aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
273aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
274aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
275aa3661deSLisandro Dalcin   } else {
276aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
277aa3661deSLisandro Dalcin        provided preconditioner matrix with the default matrix free version. */
278aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);CHKERRQ(ierr);
279aa3661deSLisandro Dalcin     /* Force no preconditioner */
280aa3661deSLisandro Dalcin     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
281aa3661deSLisandro Dalcin     ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
282aa3661deSLisandro Dalcin     ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
283aa3661deSLisandro Dalcin     if (!match) {
284aa3661deSLisandro Dalcin       ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
285aa3661deSLisandro Dalcin       ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
286aa3661deSLisandro Dalcin     }
287aa3661deSLisandro Dalcin   }
2886bf464f9SBarry Smith   ierr = MatDestroy(&J);CHKERRQ(ierr);
289aa3661deSLisandro Dalcin 
290aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
291aa3661deSLisandro Dalcin }
292aa3661deSLisandro Dalcin 
2934a2ae208SSatish Balay #undef __FUNCT__
2944a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions"
2959b94acceSBarry Smith /*@
29694b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
2979b94acceSBarry Smith 
298c7afd0dbSLois Curfman McInnes    Collective on SNES
299c7afd0dbSLois Curfman McInnes 
3009b94acceSBarry Smith    Input Parameter:
3019b94acceSBarry Smith .  snes - the SNES context
3029b94acceSBarry Smith 
30336851e7fSLois Curfman McInnes    Options Database Keys:
3046831982aSBarry Smith +  -snes_type <type> - ls, tr, umls, umtr, test
30582738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
30682738288SBarry Smith                 of the change in the solution between steps
30770441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
308b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
309b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
310b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
31150ffb88aSMatthew Knepley .  -snes_max_fail <max_fail> - maximum number of failures
312ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
313a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
314e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
315b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
3162492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
31782738288SBarry Smith                                solver; hence iterations will continue until max_it
3181fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
31982738288SBarry Smith                                of convergence test
320e8105e01SRichard Katz .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
321e8105e01SRichard Katz                                        filename given prints to stdout
322a6570f20SBarry Smith .  -snes_monitor_solution - plots solution at each iteration
323a6570f20SBarry Smith .  -snes_monitor_residual - plots residual (not its norm) at each iteration
324a6570f20SBarry Smith .  -snes_monitor_solution_update - plots update to solution at each iteration
325a6570f20SBarry Smith .  -snes_monitor_draw - plots residual norm at each iteration
326e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
3275968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
328fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
32982738288SBarry Smith 
33082738288SBarry Smith     Options Database for Eisenstat-Walker method:
331fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
3324b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
33336851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
33436851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
33536851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
33636851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
33736851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
33836851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
33982738288SBarry Smith 
34011ca99fdSLois Curfman McInnes    Notes:
34111ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
3420598bfebSBarry Smith    the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>.
34383e2fdc7SBarry Smith 
34436851e7fSLois Curfman McInnes    Level: beginner
34536851e7fSLois Curfman McInnes 
3469b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
3479b94acceSBarry Smith 
34869ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
3499b94acceSBarry Smith @*/
3507087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
3519b94acceSBarry Smith {
352ace3abfcSBarry Smith   PetscBool               flg,mf,mf_operator;
353efd51863SBarry Smith   PetscInt                i,indx,lag,mf_version,grids;
354aa3661deSLisandro Dalcin   MatStructure            matflag;
35585385478SLisandro Dalcin   const char              *deft = SNESLS;
35685385478SLisandro Dalcin   const char              *convtests[] = {"default","skip"};
35785385478SLisandro Dalcin   SNESKSPEW               *kctx = NULL;
358e8105e01SRichard Katz   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
35923d894e5SBarry Smith   PetscViewerASCIIMonitor monviewer;
36085385478SLisandro Dalcin   PetscErrorCode          ierr;
3619b94acceSBarry Smith 
3623a40ed3dSBarry Smith   PetscFunctionBegin;
3630700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
364ca161407SBarry Smith 
365186905e3SBarry Smith   if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
366cce0b1b2SLisandro Dalcin   ierr = PetscOptionsBegin(((PetscObject)snes)->comm,((PetscObject)snes)->prefix,"Nonlinear solver (SNES) options","SNES");CHKERRQ(ierr);
3677adad957SLisandro Dalcin     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
368b0a32e0cSBarry Smith     ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
369d64ed03dSBarry Smith     if (flg) {
370186905e3SBarry Smith       ierr = SNESSetType(snes,type);CHKERRQ(ierr);
3717adad957SLisandro Dalcin     } else if (!((PetscObject)snes)->type_name) {
372186905e3SBarry Smith       ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
373d64ed03dSBarry Smith     }
37490d69ab7SBarry Smith     /* not used here, but called so will go into help messaage */
375909c8a9fSBarry Smith     ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr);
37693c39befSBarry Smith 
37757034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->xtol,&snes->xtol,0);CHKERRQ(ierr);
37857034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr);
379186905e3SBarry Smith 
38057034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr);
381b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr);
382b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr);
38350ffb88aSMatthew Knepley     ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr);
384ddf469c8SBarry Smith     ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr);
385acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr);
38685385478SLisandro Dalcin 
387a8054027SBarry Smith     ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
388a8054027SBarry Smith     if (flg) {
389a8054027SBarry Smith       ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
390a8054027SBarry Smith     }
391e35cf81dSBarry Smith     ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
392e35cf81dSBarry Smith     if (flg) {
393e35cf81dSBarry Smith       ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
394e35cf81dSBarry Smith     }
395efd51863SBarry Smith     ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
396efd51863SBarry Smith     if (flg) {
397efd51863SBarry Smith       ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
398efd51863SBarry Smith     }
399a8054027SBarry Smith 
40085385478SLisandro Dalcin     ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
40185385478SLisandro Dalcin     if (flg) {
40285385478SLisandro Dalcin       switch (indx) {
4037f7931b9SBarry Smith       case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break;
4047f7931b9SBarry Smith       case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);    break;
40585385478SLisandro Dalcin       }
40685385478SLisandro Dalcin     }
40785385478SLisandro Dalcin 
408acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr);
409186905e3SBarry Smith 
41085385478SLisandro Dalcin     kctx = (SNESKSPEW *)snes->kspconvctx;
41185385478SLisandro Dalcin 
412acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr);
413186905e3SBarry Smith 
414fa9f3622SBarry Smith     ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr);
415fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr);
416fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr);
417fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr);
418fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr);
419fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr);
420fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr);
421186905e3SBarry Smith 
42290d69ab7SBarry Smith     flg  = PETSC_FALSE;
423acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
424a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
425eabae89aSBarry Smith 
426a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
427e8105e01SRichard Katz     if (flg) {
428050a712dSBarry Smith       ierr = PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,((PetscObject)snes)->tablevel,&monviewer);CHKERRQ(ierr);
429c2efdce3SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerASCIIMonitorDestroy);CHKERRQ(ierr);
430e8105e01SRichard Katz     }
431eabae89aSBarry Smith 
432b271bb04SBarry Smith     ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
433b271bb04SBarry Smith     if (flg) {
434b271bb04SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr);
435b271bb04SBarry Smith     }
436b271bb04SBarry Smith 
437a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
438eabae89aSBarry Smith     if (flg) {
439050a712dSBarry Smith       ierr = PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,((PetscObject)snes)->tablevel,&monviewer);CHKERRQ(ierr);
440f1bef1bcSMatthew Knepley       ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr);
441e8105e01SRichard Katz     }
442eabae89aSBarry Smith 
443a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
444eabae89aSBarry Smith     if (flg) {
445050a712dSBarry Smith       ierr = PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,((PetscObject)snes)->tablevel,&monviewer);CHKERRQ(ierr);
446c2efdce3SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerASCIIMonitorDestroy);CHKERRQ(ierr);
447eabae89aSBarry Smith     }
448eabae89aSBarry Smith 
44990d69ab7SBarry Smith     flg  = PETSC_FALSE;
450acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
451a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
45290d69ab7SBarry Smith     flg  = PETSC_FALSE;
453acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
454a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
45590d69ab7SBarry Smith     flg  = PETSC_FALSE;
456acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
457a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
45890d69ab7SBarry Smith     flg  = PETSC_FALSE;
459acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
460a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
46190d69ab7SBarry Smith     flg  = PETSC_FALSE;
462acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
463b271bb04SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
464e24b481bSBarry Smith 
46590d69ab7SBarry Smith     flg  = PETSC_FALSE;
466acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
4674b27c08aSLois Curfman McInnes     if (flg) {
468186905e3SBarry Smith       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);CHKERRQ(ierr);
469ae15b995SBarry Smith       ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
4709b94acceSBarry Smith     }
471639f9d9dSBarry Smith 
472aa3661deSLisandro Dalcin     mf = mf_operator = PETSC_FALSE;
473aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
474acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr);
475aa3661deSLisandro Dalcin     if (flg && mf_operator) mf = PETSC_TRUE;
476aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
477acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr);
478aa3661deSLisandro Dalcin     if (!flg && mf_operator) mf = PETSC_TRUE;
479aa3661deSLisandro Dalcin     mf_version = 1;
480aa3661deSLisandro Dalcin     ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr);
481aa3661deSLisandro Dalcin 
48276b2cf59SMatthew Knepley     for(i = 0; i < numberofsetfromoptions; i++) {
48376b2cf59SMatthew Knepley       ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
48476b2cf59SMatthew Knepley     }
48576b2cf59SMatthew Knepley 
486e7788613SBarry Smith     if (snes->ops->setfromoptions) {
487e7788613SBarry Smith       ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr);
488639f9d9dSBarry Smith     }
4895d973c19SBarry Smith 
4905d973c19SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
4915d973c19SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr);
492b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
4934bbc92c1SBarry Smith 
494aa3661deSLisandro Dalcin   if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); }
4951cee3971SBarry Smith 
4961cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
497aa3661deSLisandro Dalcin   ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
498aa3661deSLisandro Dalcin   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr);
49985385478SLisandro Dalcin   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
50093993e2dSLois Curfman McInnes 
5013a40ed3dSBarry Smith   PetscFunctionReturn(0);
5029b94acceSBarry Smith }
5039b94acceSBarry Smith 
504d25893d9SBarry Smith #undef __FUNCT__
505d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext"
506d25893d9SBarry Smith /*@
507d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
508d25893d9SBarry Smith    the nonlinear solvers.
509d25893d9SBarry Smith 
510d25893d9SBarry Smith    Logically Collective on SNES
511d25893d9SBarry Smith 
512d25893d9SBarry Smith    Input Parameters:
513d25893d9SBarry Smith +  snes - the SNES context
514d25893d9SBarry Smith .  compute - function to compute the context
515d25893d9SBarry Smith -  destroy - function to destroy the context
516d25893d9SBarry Smith 
517d25893d9SBarry Smith    Level: intermediate
518d25893d9SBarry Smith 
519d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
520d25893d9SBarry Smith 
521d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
522d25893d9SBarry Smith @*/
523d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
524d25893d9SBarry Smith {
525d25893d9SBarry Smith   PetscFunctionBegin;
526d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
527d25893d9SBarry Smith   snes->ops->usercompute = compute;
528d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
529d25893d9SBarry Smith   PetscFunctionReturn(0);
530d25893d9SBarry Smith }
531a847f771SSatish Balay 
5324a2ae208SSatish Balay #undef __FUNCT__
5334a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
534b07ff414SBarry Smith /*@
5359b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
5369b94acceSBarry Smith    the nonlinear solvers.
5379b94acceSBarry Smith 
5383f9fe445SBarry Smith    Logically Collective on SNES
539fee21e36SBarry Smith 
540c7afd0dbSLois Curfman McInnes    Input Parameters:
541c7afd0dbSLois Curfman McInnes +  snes - the SNES context
542c7afd0dbSLois Curfman McInnes -  usrP - optional user context
543c7afd0dbSLois Curfman McInnes 
54436851e7fSLois Curfman McInnes    Level: intermediate
54536851e7fSLois Curfman McInnes 
5469b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
5479b94acceSBarry Smith 
548d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext()
5499b94acceSBarry Smith @*/
5507087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
5519b94acceSBarry Smith {
5521b2093e4SBarry Smith   PetscErrorCode ierr;
553b07ff414SBarry Smith   KSP            ksp;
5541b2093e4SBarry Smith 
5553a40ed3dSBarry Smith   PetscFunctionBegin;
5560700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
557b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
558b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
5599b94acceSBarry Smith   snes->user = usrP;
5603a40ed3dSBarry Smith   PetscFunctionReturn(0);
5619b94acceSBarry Smith }
56274679c65SBarry Smith 
5634a2ae208SSatish Balay #undef __FUNCT__
5644a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
565b07ff414SBarry Smith /*@
5669b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
5679b94acceSBarry Smith    nonlinear solvers.
5689b94acceSBarry Smith 
569c7afd0dbSLois Curfman McInnes    Not Collective
570c7afd0dbSLois Curfman McInnes 
5719b94acceSBarry Smith    Input Parameter:
5729b94acceSBarry Smith .  snes - SNES context
5739b94acceSBarry Smith 
5749b94acceSBarry Smith    Output Parameter:
5759b94acceSBarry Smith .  usrP - user context
5769b94acceSBarry Smith 
57736851e7fSLois Curfman McInnes    Level: intermediate
57836851e7fSLois Curfman McInnes 
5799b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
5809b94acceSBarry Smith 
5819b94acceSBarry Smith .seealso: SNESSetApplicationContext()
5829b94acceSBarry Smith @*/
5837087cfbeSBarry Smith PetscErrorCode  SNESGetApplicationContext(SNES snes,void **usrP)
5849b94acceSBarry Smith {
5853a40ed3dSBarry Smith   PetscFunctionBegin;
5860700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5879b94acceSBarry Smith   *usrP = snes->user;
5883a40ed3dSBarry Smith   PetscFunctionReturn(0);
5899b94acceSBarry Smith }
59074679c65SBarry Smith 
5914a2ae208SSatish Balay #undef __FUNCT__
5924a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
5939b94acceSBarry Smith /*@
594c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
595c8228a4eSBarry Smith    at this time.
5969b94acceSBarry Smith 
597c7afd0dbSLois Curfman McInnes    Not Collective
598c7afd0dbSLois Curfman McInnes 
5999b94acceSBarry Smith    Input Parameter:
6009b94acceSBarry Smith .  snes - SNES context
6019b94acceSBarry Smith 
6029b94acceSBarry Smith    Output Parameter:
6039b94acceSBarry Smith .  iter - iteration number
6049b94acceSBarry Smith 
605c8228a4eSBarry Smith    Notes:
606c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
607c8228a4eSBarry Smith 
608c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
60908405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
61008405cd6SLois Curfman McInnes .vb
61108405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
61208405cd6SLois Curfman McInnes       if (!(it % 2)) {
61308405cd6SLois Curfman McInnes         [compute Jacobian here]
61408405cd6SLois Curfman McInnes       }
61508405cd6SLois Curfman McInnes .ve
616c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
61708405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
618c8228a4eSBarry Smith 
61936851e7fSLois Curfman McInnes    Level: intermediate
62036851e7fSLois Curfman McInnes 
6212b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
6222b668275SBarry Smith 
623b850b91aSLisandro Dalcin .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
6249b94acceSBarry Smith @*/
6257087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
6269b94acceSBarry Smith {
6273a40ed3dSBarry Smith   PetscFunctionBegin;
6280700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
6294482741eSBarry Smith   PetscValidIntPointer(iter,2);
6309b94acceSBarry Smith   *iter = snes->iter;
6313a40ed3dSBarry Smith   PetscFunctionReturn(0);
6329b94acceSBarry Smith }
63374679c65SBarry Smith 
6344a2ae208SSatish Balay #undef __FUNCT__
6354a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm"
6369b94acceSBarry Smith /*@
6379b94acceSBarry Smith    SNESGetFunctionNorm - Gets the norm of the current function that was set
6389b94acceSBarry Smith    with SNESSSetFunction().
6399b94acceSBarry Smith 
640c7afd0dbSLois Curfman McInnes    Collective on SNES
641c7afd0dbSLois Curfman McInnes 
6429b94acceSBarry Smith    Input Parameter:
6439b94acceSBarry Smith .  snes - SNES context
6449b94acceSBarry Smith 
6459b94acceSBarry Smith    Output Parameter:
6469b94acceSBarry Smith .  fnorm - 2-norm of function
6479b94acceSBarry Smith 
64836851e7fSLois Curfman McInnes    Level: intermediate
64936851e7fSLois Curfman McInnes 
6509b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm
651a86d99e1SLois Curfman McInnes 
652b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
6539b94acceSBarry Smith @*/
6547087cfbeSBarry Smith PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
6559b94acceSBarry Smith {
6563a40ed3dSBarry Smith   PetscFunctionBegin;
6570700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
6584482741eSBarry Smith   PetscValidScalarPointer(fnorm,2);
6599b94acceSBarry Smith   *fnorm = snes->norm;
6603a40ed3dSBarry Smith   PetscFunctionReturn(0);
6619b94acceSBarry Smith }
66274679c65SBarry Smith 
6634a2ae208SSatish Balay #undef __FUNCT__
664b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
6659b94acceSBarry Smith /*@
666b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
6679b94acceSBarry Smith    attempted by the nonlinear solver.
6689b94acceSBarry Smith 
669c7afd0dbSLois Curfman McInnes    Not Collective
670c7afd0dbSLois Curfman McInnes 
6719b94acceSBarry Smith    Input Parameter:
6729b94acceSBarry Smith .  snes - SNES context
6739b94acceSBarry Smith 
6749b94acceSBarry Smith    Output Parameter:
6759b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
6769b94acceSBarry Smith 
677c96a6f78SLois Curfman McInnes    Notes:
678c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
679c96a6f78SLois Curfman McInnes 
68036851e7fSLois Curfman McInnes    Level: intermediate
68136851e7fSLois Curfman McInnes 
6829b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
68358ebbce7SBarry Smith 
684e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
68558ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
6869b94acceSBarry Smith @*/
6877087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
6889b94acceSBarry Smith {
6893a40ed3dSBarry Smith   PetscFunctionBegin;
6900700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
6914482741eSBarry Smith   PetscValidIntPointer(nfails,2);
69250ffb88aSMatthew Knepley   *nfails = snes->numFailures;
69350ffb88aSMatthew Knepley   PetscFunctionReturn(0);
69450ffb88aSMatthew Knepley }
69550ffb88aSMatthew Knepley 
69650ffb88aSMatthew Knepley #undef __FUNCT__
697b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
69850ffb88aSMatthew Knepley /*@
699b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
70050ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
70150ffb88aSMatthew Knepley 
70250ffb88aSMatthew Knepley    Not Collective
70350ffb88aSMatthew Knepley 
70450ffb88aSMatthew Knepley    Input Parameters:
70550ffb88aSMatthew Knepley +  snes     - SNES context
70650ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
70750ffb88aSMatthew Knepley 
70850ffb88aSMatthew Knepley    Level: intermediate
70950ffb88aSMatthew Knepley 
71050ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
71158ebbce7SBarry Smith 
712e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
71358ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
71450ffb88aSMatthew Knepley @*/
7157087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
71650ffb88aSMatthew Knepley {
71750ffb88aSMatthew Knepley   PetscFunctionBegin;
7180700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
71950ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
72050ffb88aSMatthew Knepley   PetscFunctionReturn(0);
72150ffb88aSMatthew Knepley }
72250ffb88aSMatthew Knepley 
72350ffb88aSMatthew Knepley #undef __FUNCT__
724b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
72550ffb88aSMatthew Knepley /*@
726b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
72750ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
72850ffb88aSMatthew Knepley 
72950ffb88aSMatthew Knepley    Not Collective
73050ffb88aSMatthew Knepley 
73150ffb88aSMatthew Knepley    Input Parameter:
73250ffb88aSMatthew Knepley .  snes     - SNES context
73350ffb88aSMatthew Knepley 
73450ffb88aSMatthew Knepley    Output Parameter:
73550ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
73650ffb88aSMatthew Knepley 
73750ffb88aSMatthew Knepley    Level: intermediate
73850ffb88aSMatthew Knepley 
73950ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
74058ebbce7SBarry Smith 
741e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
74258ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
74358ebbce7SBarry Smith 
74450ffb88aSMatthew Knepley @*/
7457087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
74650ffb88aSMatthew Knepley {
74750ffb88aSMatthew Knepley   PetscFunctionBegin;
7480700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7494482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
75050ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
7513a40ed3dSBarry Smith   PetscFunctionReturn(0);
7529b94acceSBarry Smith }
753a847f771SSatish Balay 
7544a2ae208SSatish Balay #undef __FUNCT__
7552541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
7562541af92SBarry Smith /*@
7572541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
7582541af92SBarry Smith      done by SNES.
7592541af92SBarry Smith 
7602541af92SBarry Smith    Not Collective
7612541af92SBarry Smith 
7622541af92SBarry Smith    Input Parameter:
7632541af92SBarry Smith .  snes     - SNES context
7642541af92SBarry Smith 
7652541af92SBarry Smith    Output Parameter:
7662541af92SBarry Smith .  nfuncs - number of evaluations
7672541af92SBarry Smith 
7682541af92SBarry Smith    Level: intermediate
7692541af92SBarry Smith 
7702541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
77158ebbce7SBarry Smith 
772e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
7732541af92SBarry Smith @*/
7747087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
7752541af92SBarry Smith {
7762541af92SBarry Smith   PetscFunctionBegin;
7770700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7782541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
7792541af92SBarry Smith   *nfuncs = snes->nfuncs;
7802541af92SBarry Smith   PetscFunctionReturn(0);
7812541af92SBarry Smith }
7822541af92SBarry Smith 
7832541af92SBarry Smith #undef __FUNCT__
7843d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
7853d4c4710SBarry Smith /*@
7863d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
7873d4c4710SBarry Smith    linear solvers.
7883d4c4710SBarry Smith 
7893d4c4710SBarry Smith    Not Collective
7903d4c4710SBarry Smith 
7913d4c4710SBarry Smith    Input Parameter:
7923d4c4710SBarry Smith .  snes - SNES context
7933d4c4710SBarry Smith 
7943d4c4710SBarry Smith    Output Parameter:
7953d4c4710SBarry Smith .  nfails - number of failed solves
7963d4c4710SBarry Smith 
7973d4c4710SBarry Smith    Notes:
7983d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
7993d4c4710SBarry Smith 
8003d4c4710SBarry Smith    Level: intermediate
8013d4c4710SBarry Smith 
8023d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
80358ebbce7SBarry Smith 
804e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
8053d4c4710SBarry Smith @*/
8067087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
8073d4c4710SBarry Smith {
8083d4c4710SBarry Smith   PetscFunctionBegin;
8090700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8103d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
8113d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
8123d4c4710SBarry Smith   PetscFunctionReturn(0);
8133d4c4710SBarry Smith }
8143d4c4710SBarry Smith 
8153d4c4710SBarry Smith #undef __FUNCT__
8163d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
8173d4c4710SBarry Smith /*@
8183d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
8193d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
8203d4c4710SBarry Smith 
8213f9fe445SBarry Smith    Logically Collective on SNES
8223d4c4710SBarry Smith 
8233d4c4710SBarry Smith    Input Parameters:
8243d4c4710SBarry Smith +  snes     - SNES context
8253d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
8263d4c4710SBarry Smith 
8273d4c4710SBarry Smith    Level: intermediate
8283d4c4710SBarry Smith 
829a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
8303d4c4710SBarry Smith 
8313d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
8323d4c4710SBarry Smith 
83358ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
8343d4c4710SBarry Smith @*/
8357087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
8363d4c4710SBarry Smith {
8373d4c4710SBarry Smith   PetscFunctionBegin;
8380700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
839c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
8403d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
8413d4c4710SBarry Smith   PetscFunctionReturn(0);
8423d4c4710SBarry Smith }
8433d4c4710SBarry Smith 
8443d4c4710SBarry Smith #undef __FUNCT__
8453d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
8463d4c4710SBarry Smith /*@
8473d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
8483d4c4710SBarry Smith      are allowed before SNES terminates
8493d4c4710SBarry Smith 
8503d4c4710SBarry Smith    Not Collective
8513d4c4710SBarry Smith 
8523d4c4710SBarry Smith    Input Parameter:
8533d4c4710SBarry Smith .  snes     - SNES context
8543d4c4710SBarry Smith 
8553d4c4710SBarry Smith    Output Parameter:
8563d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
8573d4c4710SBarry Smith 
8583d4c4710SBarry Smith    Level: intermediate
8593d4c4710SBarry Smith 
8603d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
8613d4c4710SBarry Smith 
8623d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
8633d4c4710SBarry Smith 
864e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
8653d4c4710SBarry Smith @*/
8667087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
8673d4c4710SBarry Smith {
8683d4c4710SBarry Smith   PetscFunctionBegin;
8690700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8703d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
8713d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
8723d4c4710SBarry Smith   PetscFunctionReturn(0);
8733d4c4710SBarry Smith }
8743d4c4710SBarry Smith 
8753d4c4710SBarry Smith #undef __FUNCT__
876b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
877c96a6f78SLois Curfman McInnes /*@
878b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
879c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
880c96a6f78SLois Curfman McInnes 
881c7afd0dbSLois Curfman McInnes    Not Collective
882c7afd0dbSLois Curfman McInnes 
883c96a6f78SLois Curfman McInnes    Input Parameter:
884c96a6f78SLois Curfman McInnes .  snes - SNES context
885c96a6f78SLois Curfman McInnes 
886c96a6f78SLois Curfman McInnes    Output Parameter:
887c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
888c96a6f78SLois Curfman McInnes 
889c96a6f78SLois Curfman McInnes    Notes:
890c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
891c96a6f78SLois Curfman McInnes 
89236851e7fSLois Curfman McInnes    Level: intermediate
89336851e7fSLois Curfman McInnes 
894c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
8952b668275SBarry Smith 
8968c7482ecSBarry Smith .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
897c96a6f78SLois Curfman McInnes @*/
8987087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
899c96a6f78SLois Curfman McInnes {
9003a40ed3dSBarry Smith   PetscFunctionBegin;
9010700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9024482741eSBarry Smith   PetscValidIntPointer(lits,2);
903c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
9043a40ed3dSBarry Smith   PetscFunctionReturn(0);
905c96a6f78SLois Curfman McInnes }
906c96a6f78SLois Curfman McInnes 
9074a2ae208SSatish Balay #undef __FUNCT__
90894b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP"
90952baeb72SSatish Balay /*@
91094b7f48cSBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
9119b94acceSBarry Smith 
91294b7f48cSBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
913c7afd0dbSLois Curfman McInnes 
9149b94acceSBarry Smith    Input Parameter:
9159b94acceSBarry Smith .  snes - the SNES context
9169b94acceSBarry Smith 
9179b94acceSBarry Smith    Output Parameter:
91894b7f48cSBarry Smith .  ksp - the KSP context
9199b94acceSBarry Smith 
9209b94acceSBarry Smith    Notes:
92194b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
9229b94acceSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
9232999313aSBarry Smith    PC contexts as well.
9249b94acceSBarry Smith 
92536851e7fSLois Curfman McInnes    Level: beginner
92636851e7fSLois Curfman McInnes 
92794b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
9289b94acceSBarry Smith 
9292999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
9309b94acceSBarry Smith @*/
9317087cfbeSBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
9329b94acceSBarry Smith {
9331cee3971SBarry Smith   PetscErrorCode ierr;
9341cee3971SBarry Smith 
9353a40ed3dSBarry Smith   PetscFunctionBegin;
9360700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9374482741eSBarry Smith   PetscValidPointer(ksp,2);
9381cee3971SBarry Smith 
9391cee3971SBarry Smith   if (!snes->ksp) {
9401cee3971SBarry Smith     ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr);
9411cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
9421cee3971SBarry Smith     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
9431cee3971SBarry Smith   }
94494b7f48cSBarry Smith   *ksp = snes->ksp;
9453a40ed3dSBarry Smith   PetscFunctionReturn(0);
9469b94acceSBarry Smith }
94782bf6240SBarry Smith 
9484a2ae208SSatish Balay #undef __FUNCT__
9492999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
9502999313aSBarry Smith /*@
9512999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
9522999313aSBarry Smith 
9532999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
9542999313aSBarry Smith 
9552999313aSBarry Smith    Input Parameters:
9562999313aSBarry Smith +  snes - the SNES context
9572999313aSBarry Smith -  ksp - the KSP context
9582999313aSBarry Smith 
9592999313aSBarry Smith    Notes:
9602999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
9612999313aSBarry Smith    so this routine is rarely needed.
9622999313aSBarry Smith 
9632999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
9642999313aSBarry Smith    decreased by one.
9652999313aSBarry Smith 
9662999313aSBarry Smith    Level: developer
9672999313aSBarry Smith 
9682999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
9692999313aSBarry Smith 
9702999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
9712999313aSBarry Smith @*/
9727087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
9732999313aSBarry Smith {
9742999313aSBarry Smith   PetscErrorCode ierr;
9752999313aSBarry Smith 
9762999313aSBarry Smith   PetscFunctionBegin;
9770700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9780700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
9792999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
9807dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
981906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
9822999313aSBarry Smith   snes->ksp = ksp;
9832999313aSBarry Smith   PetscFunctionReturn(0);
9842999313aSBarry Smith }
9852999313aSBarry Smith 
9867adad957SLisandro Dalcin #if 0
9872999313aSBarry Smith #undef __FUNCT__
9884a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc"
9896849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
990e24b481bSBarry Smith {
991e24b481bSBarry Smith   PetscFunctionBegin;
992e24b481bSBarry Smith   PetscFunctionReturn(0);
993e24b481bSBarry Smith }
9947adad957SLisandro Dalcin #endif
995e24b481bSBarry Smith 
9969b94acceSBarry Smith /* -----------------------------------------------------------*/
9974a2ae208SSatish Balay #undef __FUNCT__
9984a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
99952baeb72SSatish Balay /*@
10009b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
10019b94acceSBarry Smith 
1002c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1003c7afd0dbSLois Curfman McInnes 
1004c7afd0dbSLois Curfman McInnes    Input Parameters:
1005906ed7ccSBarry Smith .  comm - MPI communicator
10069b94acceSBarry Smith 
10079b94acceSBarry Smith    Output Parameter:
10089b94acceSBarry Smith .  outsnes - the new SNES context
10099b94acceSBarry Smith 
1010c7afd0dbSLois Curfman McInnes    Options Database Keys:
1011c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1012c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1013c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1014c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1015c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1016c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1017c1f60f51SBarry Smith 
101836851e7fSLois Curfman McInnes    Level: beginner
101936851e7fSLois Curfman McInnes 
10209b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
10219b94acceSBarry Smith 
1022a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1023a8054027SBarry Smith 
10249b94acceSBarry Smith @*/
10257087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
10269b94acceSBarry Smith {
1027dfbe8321SBarry Smith   PetscErrorCode      ierr;
10289b94acceSBarry Smith   SNES                snes;
1029fa9f3622SBarry Smith   SNESKSPEW           *kctx;
103037fcc0dbSBarry Smith 
10313a40ed3dSBarry Smith   PetscFunctionBegin;
1032ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
10338ba1e511SMatthew Knepley   *outsnes = PETSC_NULL;
10348ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
10358ba1e511SMatthew Knepley   ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr);
10368ba1e511SMatthew Knepley #endif
10378ba1e511SMatthew Knepley 
10380700a824SBarry Smith   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
10397adad957SLisandro Dalcin 
104085385478SLisandro Dalcin   snes->ops->converged    = SNESDefaultConverged;
10419b94acceSBarry Smith   snes->max_its           = 50;
10429750a799SBarry Smith   snes->max_funcs	  = 10000;
10439b94acceSBarry Smith   snes->norm		  = 0.0;
1044b4874afaSBarry Smith   snes->rtol		  = 1.e-8;
1045b4874afaSBarry Smith   snes->ttol              = 0.0;
104670441072SBarry Smith   snes->abstol		  = 1.e-50;
10479b94acceSBarry Smith   snes->xtol		  = 1.e-8;
10484b27c08aSLois Curfman McInnes   snes->deltatol	  = 1.e-12;
10499b94acceSBarry Smith   snes->nfuncs            = 0;
105050ffb88aSMatthew Knepley   snes->numFailures       = 0;
105150ffb88aSMatthew Knepley   snes->maxFailures       = 1;
10527a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1053e35cf81dSBarry Smith   snes->lagjacobian       = 1;
1054a8054027SBarry Smith   snes->lagpreconditioner = 1;
1055639f9d9dSBarry Smith   snes->numbermonitors    = 0;
10569b94acceSBarry Smith   snes->data              = 0;
10574dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1058186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
10596f24a144SLois Curfman McInnes   snes->nwork             = 0;
106058c9b817SLisandro Dalcin   snes->work              = 0;
106158c9b817SLisandro Dalcin   snes->nvwork            = 0;
106258c9b817SLisandro Dalcin   snes->vwork             = 0;
1063758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1064758f92a0SBarry Smith   snes->conv_hist_max     = 0;
1065758f92a0SBarry Smith   snes->conv_hist         = PETSC_NULL;
1066758f92a0SBarry Smith   snes->conv_hist_its     = PETSC_NULL;
1067758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1068184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
10699b94acceSBarry Smith 
10703d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
10713d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
10723d4c4710SBarry Smith 
10739b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
107438f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr);
10759b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
10769b94acceSBarry Smith   kctx->version     = 2;
10779b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
10789b94acceSBarry Smith                              this was too large for some test cases */
107975567043SBarry Smith   kctx->rtol_last   = 0.0;
10809b94acceSBarry Smith   kctx->rtol_max    = .9;
10819b94acceSBarry Smith   kctx->gamma       = 1.0;
108271f87433Sdalcinl   kctx->alpha       = .5*(1.0 + sqrt(5.0));
108371f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
10849b94acceSBarry Smith   kctx->threshold   = .1;
108575567043SBarry Smith   kctx->lresid_last = 0.0;
108675567043SBarry Smith   kctx->norm_last   = 0.0;
10879b94acceSBarry Smith 
10889b94acceSBarry Smith   *outsnes = snes;
10893a40ed3dSBarry Smith   PetscFunctionReturn(0);
10909b94acceSBarry Smith }
10919b94acceSBarry Smith 
10924a2ae208SSatish Balay #undef __FUNCT__
10934a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
10949b94acceSBarry Smith /*@C
10959b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
10969b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
10979b94acceSBarry Smith    equations.
10989b94acceSBarry Smith 
10993f9fe445SBarry Smith    Logically Collective on SNES
1100fee21e36SBarry Smith 
1101c7afd0dbSLois Curfman McInnes    Input Parameters:
1102c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1103c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1104de044059SHong Zhang .  func - function evaluation routine
1105c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1106c7afd0dbSLois Curfman McInnes          function evaluation routine (may be PETSC_NULL)
11079b94acceSBarry Smith 
1108c7afd0dbSLois Curfman McInnes    Calling sequence of func:
11098d76a1e5SLois Curfman McInnes $    func (SNES snes,Vec x,Vec f,void *ctx);
1110c7afd0dbSLois Curfman McInnes 
1111313e4042SLois Curfman McInnes .  f - function vector
1112c7afd0dbSLois Curfman McInnes -  ctx - optional user-defined function context
11139b94acceSBarry Smith 
11149b94acceSBarry Smith    Notes:
11159b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
11169b94acceSBarry Smith $      f'(x) x = -f(x),
1117c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
11189b94acceSBarry Smith 
111936851e7fSLois Curfman McInnes    Level: beginner
112036851e7fSLois Curfman McInnes 
11219b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
11229b94acceSBarry Smith 
1123a86d99e1SLois Curfman McInnes .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
11249b94acceSBarry Smith @*/
11257087cfbeSBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
11269b94acceSBarry Smith {
112785385478SLisandro Dalcin   PetscErrorCode ierr;
11283a40ed3dSBarry Smith   PetscFunctionBegin;
11290700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1130d2a683ecSLisandro Dalcin   if (r) {
1131d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1132d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
113385385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
11346bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
113585385478SLisandro Dalcin     snes->vec_func = r;
1136d2a683ecSLisandro Dalcin   } else if (!snes->vec_func && snes->dm) {
1137d2a683ecSLisandro Dalcin     ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
1138d2a683ecSLisandro Dalcin   }
1139d2a683ecSLisandro Dalcin   if (func) snes->ops->computefunction = func;
1140d2a683ecSLisandro Dalcin   if (ctx)  snes->funP                 = ctx;
11413a40ed3dSBarry Smith   PetscFunctionReturn(0);
11429b94acceSBarry Smith }
11439b94acceSBarry Smith 
1144d25893d9SBarry Smith #undef __FUNCT__
1145d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess"
1146d25893d9SBarry Smith /*@C
1147d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1148d25893d9SBarry Smith 
1149d25893d9SBarry Smith    Logically Collective on SNES
1150d25893d9SBarry Smith 
1151d25893d9SBarry Smith    Input Parameters:
1152d25893d9SBarry Smith +  snes - the SNES context
1153d25893d9SBarry Smith .  func - function evaluation routine
1154d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
1155d25893d9SBarry Smith          function evaluation routine (may be PETSC_NULL)
1156d25893d9SBarry Smith 
1157d25893d9SBarry Smith    Calling sequence of func:
1158d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
1159d25893d9SBarry Smith 
1160d25893d9SBarry Smith .  f - function vector
1161d25893d9SBarry Smith -  ctx - optional user-defined function context
1162d25893d9SBarry Smith 
1163d25893d9SBarry Smith    Level: intermediate
1164d25893d9SBarry Smith 
1165d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
1166d25893d9SBarry Smith 
1167d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1168d25893d9SBarry Smith @*/
1169d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1170d25893d9SBarry Smith {
1171d25893d9SBarry Smith   PetscFunctionBegin;
1172d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1173d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
1174d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
1175d25893d9SBarry Smith   PetscFunctionReturn(0);
1176d25893d9SBarry Smith }
1177d25893d9SBarry Smith 
11783ab0aad5SBarry Smith /* --------------------------------------------------------------- */
11793ab0aad5SBarry Smith #undef __FUNCT__
11801096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
11811096aae1SMatthew Knepley /*@C
11821096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
11831096aae1SMatthew Knepley    it assumes a zero right hand side.
11841096aae1SMatthew Knepley 
11853f9fe445SBarry Smith    Logically Collective on SNES
11861096aae1SMatthew Knepley 
11871096aae1SMatthew Knepley    Input Parameter:
11881096aae1SMatthew Knepley .  snes - the SNES context
11891096aae1SMatthew Knepley 
11901096aae1SMatthew Knepley    Output Parameter:
1191bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
11921096aae1SMatthew Knepley 
11931096aae1SMatthew Knepley    Level: intermediate
11941096aae1SMatthew Knepley 
11951096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
11961096aae1SMatthew Knepley 
119785385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
11981096aae1SMatthew Knepley @*/
11997087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
12001096aae1SMatthew Knepley {
12011096aae1SMatthew Knepley   PetscFunctionBegin;
12020700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12031096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
120485385478SLisandro Dalcin   *rhs = snes->vec_rhs;
12051096aae1SMatthew Knepley   PetscFunctionReturn(0);
12061096aae1SMatthew Knepley }
12071096aae1SMatthew Knepley 
12081096aae1SMatthew Knepley #undef __FUNCT__
12094a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
12109b94acceSBarry Smith /*@
121136851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
12129b94acceSBarry Smith                          SNESSetFunction().
12139b94acceSBarry Smith 
1214c7afd0dbSLois Curfman McInnes    Collective on SNES
1215c7afd0dbSLois Curfman McInnes 
12169b94acceSBarry Smith    Input Parameters:
1217c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1218c7afd0dbSLois Curfman McInnes -  x - input vector
12199b94acceSBarry Smith 
12209b94acceSBarry Smith    Output Parameter:
12213638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
12229b94acceSBarry Smith 
12231bffabb2SLois Curfman McInnes    Notes:
122436851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
122536851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
122636851e7fSLois Curfman McInnes    themselves.
122736851e7fSLois Curfman McInnes 
122836851e7fSLois Curfman McInnes    Level: developer
122936851e7fSLois Curfman McInnes 
12309b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
12319b94acceSBarry Smith 
1232a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
12339b94acceSBarry Smith @*/
12347087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
12359b94acceSBarry Smith {
1236dfbe8321SBarry Smith   PetscErrorCode ierr;
12379b94acceSBarry Smith 
12383a40ed3dSBarry Smith   PetscFunctionBegin;
12390700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12400700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
12410700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
1242c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
1243c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
1244184914b5SBarry Smith 
1245d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
1246e7788613SBarry Smith   if (snes->ops->computefunction) {
1247d64ed03dSBarry Smith     PetscStackPush("SNES user function");
124839d508bbSBarry Smith     ierr = (*snes->ops->computefunction)(snes,x,y,snes->funP);CHKERRQ(ierr);
1249d64ed03dSBarry Smith     PetscStackPop;
125085385478SLisandro Dalcin   } else if (snes->vec_rhs) {
12511096aae1SMatthew Knepley     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
1252644e2e5bSBarry Smith   } 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);
1575*cab2e9ccSBarry Smith     ierr = SNESSetJacobian(snes,J,J,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr);
1576*cab2e9ccSBarry Smith     ierr = MatDestroy(&J);CHKERRQ(ierr);
1577efd51863SBarry Smith   } else if (snes->dm && !snes->jacobian_pre){
1578efd51863SBarry Smith     Mat J;
1579efd51863SBarry Smith     ierr = DMGetMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr);
1580efd51863SBarry Smith     ierr = SNESSetJacobian(snes,J,J,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
1581efd51863SBarry Smith     ierr = MatDestroy(&J);CHKERRQ(ierr);
1582ef8dffc7SBarry Smith   }
1583efd51863SBarry Smith 
1584b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
1585b710008aSBarry Smith 
1586d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
1587d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
1588d25893d9SBarry Smith   }
1589d25893d9SBarry Smith 
1590410397dcSLisandro Dalcin   if (snes->ops->setup) {
1591410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
1592410397dcSLisandro Dalcin   }
159358c9b817SLisandro Dalcin 
15947aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
15953a40ed3dSBarry Smith   PetscFunctionReturn(0);
15969b94acceSBarry Smith }
15979b94acceSBarry Smith 
15984a2ae208SSatish Balay #undef __FUNCT__
159937596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
160037596af1SLisandro Dalcin /*@
160137596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
160237596af1SLisandro Dalcin 
160337596af1SLisandro Dalcin    Collective on SNES
160437596af1SLisandro Dalcin 
160537596af1SLisandro Dalcin    Input Parameter:
160637596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
160737596af1SLisandro Dalcin 
1608d25893d9SBarry Smith    Level: intermediate
1609d25893d9SBarry Smith 
1610d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
161137596af1SLisandro Dalcin 
161237596af1SLisandro Dalcin .keywords: SNES, destroy
161337596af1SLisandro Dalcin 
161437596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
161537596af1SLisandro Dalcin @*/
161637596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
161737596af1SLisandro Dalcin {
161837596af1SLisandro Dalcin   PetscErrorCode ierr;
161937596af1SLisandro Dalcin 
162037596af1SLisandro Dalcin   PetscFunctionBegin;
162137596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1622d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
1623d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
1624d25893d9SBarry Smith     snes->user = PETSC_NULL;
1625d25893d9SBarry Smith   }
1626644e2e5bSBarry Smith   if (snes->ops->computejacobian == SNESDefaultComputeJacobianColor && snes->dm) {
1627644e2e5bSBarry Smith     ierr = MatFDColoringDestroy((MatFDColoring*)&snes->jacP);CHKERRQ(ierr);
1628644e2e5bSBarry Smith     snes->ops->computejacobian = PETSC_NULL;
1629644e2e5bSBarry Smith   }
1630d25893d9SBarry Smith 
163137596af1SLisandro Dalcin   if (snes->ops->reset) {
163237596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
163337596af1SLisandro Dalcin   }
163437596af1SLisandro Dalcin   if (snes->ksp) {ierr = KSPReset(snes->ksp);CHKERRQ(ierr);}
16356bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
16366bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
16376bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
16386bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
16396bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
16406bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
164137596af1SLisandro Dalcin   if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);}
164237596af1SLisandro Dalcin   if (snes->vwork) {ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);}
164337596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
164437596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
164537596af1SLisandro Dalcin   PetscFunctionReturn(0);
164637596af1SLisandro Dalcin }
164737596af1SLisandro Dalcin 
164837596af1SLisandro Dalcin #undef __FUNCT__
16494a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
165052baeb72SSatish Balay /*@
16519b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
16529b94acceSBarry Smith    with SNESCreate().
16539b94acceSBarry Smith 
1654c7afd0dbSLois Curfman McInnes    Collective on SNES
1655c7afd0dbSLois Curfman McInnes 
16569b94acceSBarry Smith    Input Parameter:
16579b94acceSBarry Smith .  snes - the SNES context
16589b94acceSBarry Smith 
165936851e7fSLois Curfman McInnes    Level: beginner
166036851e7fSLois Curfman McInnes 
16619b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
16629b94acceSBarry Smith 
166363a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
16649b94acceSBarry Smith @*/
16656bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
16669b94acceSBarry Smith {
16676849ba73SBarry Smith   PetscErrorCode ierr;
16683a40ed3dSBarry Smith 
16693a40ed3dSBarry Smith   PetscFunctionBegin;
16706bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
16716bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
16726bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
1673d4bb536fSBarry Smith 
16746bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
16756b8b9a38SLisandro Dalcin 
1676be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
16776bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
16786bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
16796d4c513bSLisandro Dalcin 
16806bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
16816bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
16826b8b9a38SLisandro Dalcin 
16836bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
16846bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
16856bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
16866b8b9a38SLisandro Dalcin   }
16876bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
16886bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
16896bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
169058c9b817SLisandro Dalcin   }
16916bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
1692a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
16933a40ed3dSBarry Smith   PetscFunctionReturn(0);
16949b94acceSBarry Smith }
16959b94acceSBarry Smith 
16969b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
16979b94acceSBarry Smith 
16984a2ae208SSatish Balay #undef __FUNCT__
1699a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
1700a8054027SBarry Smith /*@
1701a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
1702a8054027SBarry Smith 
17033f9fe445SBarry Smith    Logically Collective on SNES
1704a8054027SBarry Smith 
1705a8054027SBarry Smith    Input Parameters:
1706a8054027SBarry Smith +  snes - the SNES context
1707a8054027SBarry Smith -  lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
17083b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
1709a8054027SBarry Smith 
1710a8054027SBarry Smith    Options Database Keys:
1711a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
1712a8054027SBarry Smith 
1713a8054027SBarry Smith    Notes:
1714a8054027SBarry Smith    The default is 1
1715a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1716a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
1717a8054027SBarry Smith 
1718a8054027SBarry Smith    Level: intermediate
1719a8054027SBarry Smith 
1720a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1721a8054027SBarry Smith 
1722e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
1723a8054027SBarry Smith 
1724a8054027SBarry Smith @*/
17257087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
1726a8054027SBarry Smith {
1727a8054027SBarry Smith   PetscFunctionBegin;
17280700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1729e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
1730e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
1731c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
1732a8054027SBarry Smith   snes->lagpreconditioner = lag;
1733a8054027SBarry Smith   PetscFunctionReturn(0);
1734a8054027SBarry Smith }
1735a8054027SBarry Smith 
1736a8054027SBarry Smith #undef __FUNCT__
1737efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
1738efd51863SBarry Smith /*@
1739efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
1740efd51863SBarry Smith 
1741efd51863SBarry Smith    Logically Collective on SNES
1742efd51863SBarry Smith 
1743efd51863SBarry Smith    Input Parameters:
1744efd51863SBarry Smith +  snes - the SNES context
1745efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
1746efd51863SBarry Smith 
1747efd51863SBarry Smith    Options Database Keys:
1748efd51863SBarry Smith .    -snes_grid_sequence <steps>
1749efd51863SBarry Smith 
1750efd51863SBarry Smith    Level: intermediate
1751efd51863SBarry Smith 
1752efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1753efd51863SBarry Smith 
1754efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
1755efd51863SBarry Smith 
1756efd51863SBarry Smith @*/
1757efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
1758efd51863SBarry Smith {
1759efd51863SBarry Smith   PetscFunctionBegin;
1760efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1761efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
1762efd51863SBarry Smith   snes->gridsequence = steps;
1763efd51863SBarry Smith   PetscFunctionReturn(0);
1764efd51863SBarry Smith }
1765efd51863SBarry Smith 
1766efd51863SBarry Smith #undef __FUNCT__
1767a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
1768a8054027SBarry Smith /*@
1769a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
1770a8054027SBarry Smith 
17713f9fe445SBarry Smith    Not Collective
1772a8054027SBarry Smith 
1773a8054027SBarry Smith    Input Parameter:
1774a8054027SBarry Smith .  snes - the SNES context
1775a8054027SBarry Smith 
1776a8054027SBarry Smith    Output Parameter:
1777a8054027SBarry Smith .   lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
17783b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
1779a8054027SBarry Smith 
1780a8054027SBarry Smith    Options Database Keys:
1781a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
1782a8054027SBarry Smith 
1783a8054027SBarry Smith    Notes:
1784a8054027SBarry Smith    The default is 1
1785a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1786a8054027SBarry Smith 
1787a8054027SBarry Smith    Level: intermediate
1788a8054027SBarry Smith 
1789a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1790a8054027SBarry Smith 
1791a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
1792a8054027SBarry Smith 
1793a8054027SBarry Smith @*/
17947087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
1795a8054027SBarry Smith {
1796a8054027SBarry Smith   PetscFunctionBegin;
17970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1798a8054027SBarry Smith   *lag = snes->lagpreconditioner;
1799a8054027SBarry Smith   PetscFunctionReturn(0);
1800a8054027SBarry Smith }
1801a8054027SBarry Smith 
1802a8054027SBarry Smith #undef __FUNCT__
1803e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
1804e35cf81dSBarry Smith /*@
1805e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
1806e35cf81dSBarry Smith      often the preconditioner is rebuilt.
1807e35cf81dSBarry Smith 
18083f9fe445SBarry Smith    Logically Collective on SNES
1809e35cf81dSBarry Smith 
1810e35cf81dSBarry Smith    Input Parameters:
1811e35cf81dSBarry Smith +  snes - the SNES context
1812e35cf81dSBarry Smith -  lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
1813fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
1814e35cf81dSBarry Smith 
1815e35cf81dSBarry Smith    Options Database Keys:
1816e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
1817e35cf81dSBarry Smith 
1818e35cf81dSBarry Smith    Notes:
1819e35cf81dSBarry Smith    The default is 1
1820e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1821fe3ffe1eSBarry Smith    If  -1 is used before the very first nonlinear solve the CODE WILL FAIL! because no Jacobian is used, use -2 to indicate you want it recomputed
1822fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
1823e35cf81dSBarry Smith 
1824e35cf81dSBarry Smith    Level: intermediate
1825e35cf81dSBarry Smith 
1826e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1827e35cf81dSBarry Smith 
1828e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
1829e35cf81dSBarry Smith 
1830e35cf81dSBarry Smith @*/
18317087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
1832e35cf81dSBarry Smith {
1833e35cf81dSBarry Smith   PetscFunctionBegin;
18340700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1835e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
1836e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
1837c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
1838e35cf81dSBarry Smith   snes->lagjacobian = lag;
1839e35cf81dSBarry Smith   PetscFunctionReturn(0);
1840e35cf81dSBarry Smith }
1841e35cf81dSBarry Smith 
1842e35cf81dSBarry Smith #undef __FUNCT__
1843e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
1844e35cf81dSBarry Smith /*@
1845e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
1846e35cf81dSBarry Smith 
18473f9fe445SBarry Smith    Not Collective
1848e35cf81dSBarry Smith 
1849e35cf81dSBarry Smith    Input Parameter:
1850e35cf81dSBarry Smith .  snes - the SNES context
1851e35cf81dSBarry Smith 
1852e35cf81dSBarry Smith    Output Parameter:
1853e35cf81dSBarry Smith .   lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
1854e35cf81dSBarry Smith          the Jacobian is built etc.
1855e35cf81dSBarry Smith 
1856e35cf81dSBarry Smith    Options Database Keys:
1857e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
1858e35cf81dSBarry Smith 
1859e35cf81dSBarry Smith    Notes:
1860e35cf81dSBarry Smith    The default is 1
1861e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1862e35cf81dSBarry Smith 
1863e35cf81dSBarry Smith    Level: intermediate
1864e35cf81dSBarry Smith 
1865e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
1866e35cf81dSBarry Smith 
1867e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
1868e35cf81dSBarry Smith 
1869e35cf81dSBarry Smith @*/
18707087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
1871e35cf81dSBarry Smith {
1872e35cf81dSBarry Smith   PetscFunctionBegin;
18730700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1874e35cf81dSBarry Smith   *lag = snes->lagjacobian;
1875e35cf81dSBarry Smith   PetscFunctionReturn(0);
1876e35cf81dSBarry Smith }
1877e35cf81dSBarry Smith 
1878e35cf81dSBarry Smith #undef __FUNCT__
18794a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
18809b94acceSBarry Smith /*@
1881d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
18829b94acceSBarry Smith 
18833f9fe445SBarry Smith    Logically Collective on SNES
1884c7afd0dbSLois Curfman McInnes 
18859b94acceSBarry Smith    Input Parameters:
1886c7afd0dbSLois Curfman McInnes +  snes - the SNES context
188770441072SBarry Smith .  abstol - absolute convergence tolerance
188833174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
188933174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
189033174efeSLois Curfman McInnes            of the change in the solution between steps
189133174efeSLois Curfman McInnes .  maxit - maximum number of iterations
1892c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
1893fee21e36SBarry Smith 
189433174efeSLois Curfman McInnes    Options Database Keys:
189570441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
1896c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
1897c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
1898c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
1899c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
19009b94acceSBarry Smith 
1901d7a720efSLois Curfman McInnes    Notes:
19029b94acceSBarry Smith    The default maximum number of iterations is 50.
19039b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
19049b94acceSBarry Smith 
190536851e7fSLois Curfman McInnes    Level: intermediate
190636851e7fSLois Curfman McInnes 
190733174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
19089b94acceSBarry Smith 
19092492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
19109b94acceSBarry Smith @*/
19117087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
19129b94acceSBarry Smith {
19133a40ed3dSBarry Smith   PetscFunctionBegin;
19140700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1915c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
1916c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
1917c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
1918c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
1919c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
1920c5eb9154SBarry Smith 
192170441072SBarry Smith   if (abstol != PETSC_DEFAULT)  snes->abstol      = abstol;
1922d7a720efSLois Curfman McInnes   if (rtol != PETSC_DEFAULT)  snes->rtol      = rtol;
1923d7a720efSLois Curfman McInnes   if (stol != PETSC_DEFAULT)  snes->xtol      = stol;
1924d7a720efSLois Curfman McInnes   if (maxit != PETSC_DEFAULT) snes->max_its   = maxit;
1925d7a720efSLois Curfman McInnes   if (maxf != PETSC_DEFAULT)  snes->max_funcs = maxf;
19263a40ed3dSBarry Smith   PetscFunctionReturn(0);
19279b94acceSBarry Smith }
19289b94acceSBarry Smith 
19294a2ae208SSatish Balay #undef __FUNCT__
19304a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
19319b94acceSBarry Smith /*@
193233174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
193333174efeSLois Curfman McInnes 
1934c7afd0dbSLois Curfman McInnes    Not Collective
1935c7afd0dbSLois Curfman McInnes 
193633174efeSLois Curfman McInnes    Input Parameters:
1937c7afd0dbSLois Curfman McInnes +  snes - the SNES context
193885385478SLisandro Dalcin .  atol - absolute convergence tolerance
193933174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
194033174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
194133174efeSLois Curfman McInnes            of the change in the solution between steps
194233174efeSLois Curfman McInnes .  maxit - maximum number of iterations
1943c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
1944fee21e36SBarry Smith 
194533174efeSLois Curfman McInnes    Notes:
194633174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
194733174efeSLois Curfman McInnes 
194836851e7fSLois Curfman McInnes    Level: intermediate
194936851e7fSLois Curfman McInnes 
195033174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
195133174efeSLois Curfman McInnes 
195233174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
195333174efeSLois Curfman McInnes @*/
19547087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
195533174efeSLois Curfman McInnes {
19563a40ed3dSBarry Smith   PetscFunctionBegin;
19570700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
195885385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
195933174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
196033174efeSLois Curfman McInnes   if (stol)  *stol  = snes->xtol;
196133174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
196233174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
19633a40ed3dSBarry Smith   PetscFunctionReturn(0);
196433174efeSLois Curfman McInnes }
196533174efeSLois Curfman McInnes 
19664a2ae208SSatish Balay #undef __FUNCT__
19674a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
196833174efeSLois Curfman McInnes /*@
19699b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
19709b94acceSBarry Smith 
19713f9fe445SBarry Smith    Logically Collective on SNES
1972fee21e36SBarry Smith 
1973c7afd0dbSLois Curfman McInnes    Input Parameters:
1974c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1975c7afd0dbSLois Curfman McInnes -  tol - tolerance
1976c7afd0dbSLois Curfman McInnes 
19779b94acceSBarry Smith    Options Database Key:
1978c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
19799b94acceSBarry Smith 
198036851e7fSLois Curfman McInnes    Level: intermediate
198136851e7fSLois Curfman McInnes 
19829b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
19839b94acceSBarry Smith 
19842492ecdbSBarry Smith .seealso: SNESSetTolerances()
19859b94acceSBarry Smith @*/
19867087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
19879b94acceSBarry Smith {
19883a40ed3dSBarry Smith   PetscFunctionBegin;
19890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1990c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
19919b94acceSBarry Smith   snes->deltatol = tol;
19923a40ed3dSBarry Smith   PetscFunctionReturn(0);
19939b94acceSBarry Smith }
19949b94acceSBarry Smith 
1995df9fa365SBarry Smith /*
1996df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
1997df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
1998df9fa365SBarry Smith    macros instead of functions
1999df9fa365SBarry Smith */
20004a2ae208SSatish Balay #undef __FUNCT__
2001a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
20027087cfbeSBarry Smith PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2003ce1608b8SBarry Smith {
2004dfbe8321SBarry Smith   PetscErrorCode ierr;
2005ce1608b8SBarry Smith 
2006ce1608b8SBarry Smith   PetscFunctionBegin;
20070700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2008a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
2009ce1608b8SBarry Smith   PetscFunctionReturn(0);
2010ce1608b8SBarry Smith }
2011ce1608b8SBarry Smith 
20124a2ae208SSatish Balay #undef __FUNCT__
2013a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
20147087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2015df9fa365SBarry Smith {
2016dfbe8321SBarry Smith   PetscErrorCode ierr;
2017df9fa365SBarry Smith 
2018df9fa365SBarry Smith   PetscFunctionBegin;
2019a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2020df9fa365SBarry Smith   PetscFunctionReturn(0);
2021df9fa365SBarry Smith }
2022df9fa365SBarry Smith 
20234a2ae208SSatish Balay #undef __FUNCT__
2024a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
20256bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
2026df9fa365SBarry Smith {
2027dfbe8321SBarry Smith   PetscErrorCode ierr;
2028df9fa365SBarry Smith 
2029df9fa365SBarry Smith   PetscFunctionBegin;
2030a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2031df9fa365SBarry Smith   PetscFunctionReturn(0);
2032df9fa365SBarry Smith }
2033df9fa365SBarry Smith 
20347087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
2035b271bb04SBarry Smith #undef __FUNCT__
2036b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
20377087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2038b271bb04SBarry Smith {
2039b271bb04SBarry Smith   PetscDrawLG      lg;
2040b271bb04SBarry Smith   PetscErrorCode   ierr;
2041b271bb04SBarry Smith   PetscReal        x,y,per;
2042b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
2043b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
2044b271bb04SBarry Smith   PetscDraw        draw;
2045b271bb04SBarry Smith   PetscFunctionBegin;
2046b271bb04SBarry Smith   if (!monctx) {
2047b271bb04SBarry Smith     MPI_Comm    comm;
2048b271bb04SBarry Smith 
2049b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2050b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
2051b271bb04SBarry Smith   }
2052b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
2053b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2054b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2055b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
2056b271bb04SBarry Smith   x = (PetscReal) n;
2057b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
2058b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2059b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2060b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2061b271bb04SBarry Smith   }
2062b271bb04SBarry Smith 
2063b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
2064b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2065b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2066b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
2067b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
2068b271bb04SBarry Smith   x = (PetscReal) n;
2069b271bb04SBarry Smith   y = 100.0*per;
2070b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2071b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2072b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2073b271bb04SBarry Smith   }
2074b271bb04SBarry Smith 
2075b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
2076b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2077b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2078b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
2079b271bb04SBarry Smith   x = (PetscReal) n;
2080b271bb04SBarry Smith   y = (prev - rnorm)/prev;
2081b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2082b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2083b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2084b271bb04SBarry Smith   }
2085b271bb04SBarry Smith 
2086b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
2087b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2088b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2089b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
2090b271bb04SBarry Smith   x = (PetscReal) n;
2091b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
2092b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
2093b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2094b271bb04SBarry Smith   }
2095b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2096b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2097b271bb04SBarry Smith   }
2098b271bb04SBarry Smith   prev = rnorm;
2099b271bb04SBarry Smith   PetscFunctionReturn(0);
2100b271bb04SBarry Smith }
2101b271bb04SBarry Smith 
2102b271bb04SBarry Smith #undef __FUNCT__
2103b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
21047087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2105b271bb04SBarry Smith {
2106b271bb04SBarry Smith   PetscErrorCode ierr;
2107b271bb04SBarry Smith 
2108b271bb04SBarry Smith   PetscFunctionBegin;
2109b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2110b271bb04SBarry Smith   PetscFunctionReturn(0);
2111b271bb04SBarry Smith }
2112b271bb04SBarry Smith 
2113b271bb04SBarry Smith #undef __FUNCT__
2114b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
21156bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG *draw)
2116b271bb04SBarry Smith {
2117b271bb04SBarry Smith   PetscErrorCode ierr;
2118b271bb04SBarry Smith 
2119b271bb04SBarry Smith   PetscFunctionBegin;
2120b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2121b271bb04SBarry Smith   PetscFunctionReturn(0);
2122b271bb04SBarry Smith }
2123b271bb04SBarry Smith 
21247a03ce2fSLisandro Dalcin #undef __FUNCT__
21257a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
21267a03ce2fSLisandro Dalcin /*
21277a03ce2fSLisandro Dalcin      Runs the user provided monitor routines, if they exists.
21287a03ce2fSLisandro Dalcin */
21297a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
21307a03ce2fSLisandro Dalcin {
21317a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
21327a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
21337a03ce2fSLisandro Dalcin 
21347a03ce2fSLisandro Dalcin   PetscFunctionBegin;
21357a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
21367a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
21377a03ce2fSLisandro Dalcin   }
21387a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
21397a03ce2fSLisandro Dalcin }
21407a03ce2fSLisandro Dalcin 
21419b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
21429b94acceSBarry Smith 
21434a2ae208SSatish Balay #undef __FUNCT__
2144a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
21459b94acceSBarry Smith /*@C
2146a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
21479b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
21489b94acceSBarry Smith    progress.
21499b94acceSBarry Smith 
21503f9fe445SBarry Smith    Logically Collective on SNES
2151fee21e36SBarry Smith 
2152c7afd0dbSLois Curfman McInnes    Input Parameters:
2153c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2154c7afd0dbSLois Curfman McInnes .  func - monitoring routine
2155b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
2156e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
2157b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
2158b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
21599b94acceSBarry Smith 
2160c7afd0dbSLois Curfman McInnes    Calling sequence of func:
2161a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
2162c7afd0dbSLois Curfman McInnes 
2163c7afd0dbSLois Curfman McInnes +    snes - the SNES context
2164c7afd0dbSLois Curfman McInnes .    its - iteration number
2165c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
216640a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
21679b94acceSBarry Smith 
21689665c990SLois Curfman McInnes    Options Database Keys:
2169a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
2170a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
2171a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
2172cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
2173c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
2174a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
2175c7afd0dbSLois Curfman McInnes                             does not cancel those set via
2176c7afd0dbSLois Curfman McInnes                             the options database.
21779665c990SLois Curfman McInnes 
2178639f9d9dSBarry Smith    Notes:
21796bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
2180a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
21816bc08f3fSLois Curfman McInnes    order in which they were set.
2182639f9d9dSBarry Smith 
2183025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
2184025f1a04SBarry Smith 
218536851e7fSLois Curfman McInnes    Level: intermediate
218636851e7fSLois Curfman McInnes 
21879b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
21889b94acceSBarry Smith 
2189a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
21909b94acceSBarry Smith @*/
2191c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
21929b94acceSBarry Smith {
2193b90d0a6eSBarry Smith   PetscInt i;
2194b90d0a6eSBarry Smith 
21953a40ed3dSBarry Smith   PetscFunctionBegin;
21960700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
219717186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
2198b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
2199b90d0a6eSBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) PetscFunctionReturn(0);
2200b90d0a6eSBarry Smith 
2201b90d0a6eSBarry Smith     /* check if both default monitors that share common ASCII viewer */
2202b90d0a6eSBarry Smith     if (monitor == snes->monitor[i] && monitor == SNESMonitorDefault) {
2203b90d0a6eSBarry Smith       if (mctx && snes->monitorcontext[i]) {
2204b90d0a6eSBarry Smith         PetscErrorCode          ierr;
2205b90d0a6eSBarry Smith         PetscViewerASCIIMonitor viewer1 = (PetscViewerASCIIMonitor) mctx;
2206b90d0a6eSBarry Smith         PetscViewerASCIIMonitor viewer2 = (PetscViewerASCIIMonitor) snes->monitorcontext[i];
2207b90d0a6eSBarry Smith         if (viewer1->viewer == viewer2->viewer) {
2208c2efdce3SBarry Smith           ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
2209b90d0a6eSBarry Smith           PetscFunctionReturn(0);
2210b90d0a6eSBarry Smith         }
2211b90d0a6eSBarry Smith       }
2212b90d0a6eSBarry Smith     }
2213b90d0a6eSBarry Smith   }
2214b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
2215b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
2216639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
22173a40ed3dSBarry Smith   PetscFunctionReturn(0);
22189b94acceSBarry Smith }
22199b94acceSBarry Smith 
22204a2ae208SSatish Balay #undef __FUNCT__
2221a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
22225cd90555SBarry Smith /*@C
2223a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
22245cd90555SBarry Smith 
22253f9fe445SBarry Smith    Logically Collective on SNES
2226c7afd0dbSLois Curfman McInnes 
22275cd90555SBarry Smith    Input Parameters:
22285cd90555SBarry Smith .  snes - the SNES context
22295cd90555SBarry Smith 
22301a480d89SAdministrator    Options Database Key:
2231a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
2232a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
2233c7afd0dbSLois Curfman McInnes     set via the options database
22345cd90555SBarry Smith 
22355cd90555SBarry Smith    Notes:
22365cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
22375cd90555SBarry Smith 
223836851e7fSLois Curfman McInnes    Level: intermediate
223936851e7fSLois Curfman McInnes 
22405cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
22415cd90555SBarry Smith 
2242a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
22435cd90555SBarry Smith @*/
22447087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
22455cd90555SBarry Smith {
2246d952e501SBarry Smith   PetscErrorCode ierr;
2247d952e501SBarry Smith   PetscInt       i;
2248d952e501SBarry Smith 
22495cd90555SBarry Smith   PetscFunctionBegin;
22500700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2251d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
2252d952e501SBarry Smith     if (snes->monitordestroy[i]) {
22533c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
2254d952e501SBarry Smith     }
2255d952e501SBarry Smith   }
22565cd90555SBarry Smith   snes->numbermonitors = 0;
22575cd90555SBarry Smith   PetscFunctionReturn(0);
22585cd90555SBarry Smith }
22595cd90555SBarry Smith 
22604a2ae208SSatish Balay #undef __FUNCT__
22614a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
22629b94acceSBarry Smith /*@C
22639b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
22649b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
22659b94acceSBarry Smith 
22663f9fe445SBarry Smith    Logically Collective on SNES
2267fee21e36SBarry Smith 
2268c7afd0dbSLois Curfman McInnes    Input Parameters:
2269c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2270c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
22717f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
22727f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
22739b94acceSBarry Smith 
2274c7afd0dbSLois Curfman McInnes    Calling sequence of func:
227506ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
2276c7afd0dbSLois Curfman McInnes 
2277c7afd0dbSLois Curfman McInnes +    snes - the SNES context
227806ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
2279c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
2280184914b5SBarry Smith .    reason - reason for convergence/divergence
2281c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
22824b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
22834b27c08aSLois Curfman McInnes -    f - 2-norm of function
22849b94acceSBarry Smith 
228536851e7fSLois Curfman McInnes    Level: advanced
228636851e7fSLois Curfman McInnes 
22879b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
22889b94acceSBarry Smith 
228985385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
22909b94acceSBarry Smith @*/
22917087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
22929b94acceSBarry Smith {
22937f7931b9SBarry Smith   PetscErrorCode ierr;
22947f7931b9SBarry Smith 
22953a40ed3dSBarry Smith   PetscFunctionBegin;
22960700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
229785385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
22987f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
22997f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
23007f7931b9SBarry Smith   }
230185385478SLisandro Dalcin   snes->ops->converged        = func;
23027f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
230385385478SLisandro Dalcin   snes->cnvP                  = cctx;
23043a40ed3dSBarry Smith   PetscFunctionReturn(0);
23059b94acceSBarry Smith }
23069b94acceSBarry Smith 
23074a2ae208SSatish Balay #undef __FUNCT__
23084a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
230952baeb72SSatish Balay /*@
2310184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
2311184914b5SBarry Smith 
2312184914b5SBarry Smith    Not Collective
2313184914b5SBarry Smith 
2314184914b5SBarry Smith    Input Parameter:
2315184914b5SBarry Smith .  snes - the SNES context
2316184914b5SBarry Smith 
2317184914b5SBarry Smith    Output Parameter:
23184d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
2319184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
2320184914b5SBarry Smith 
2321184914b5SBarry Smith    Level: intermediate
2322184914b5SBarry Smith 
2323184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
2324184914b5SBarry Smith 
2325184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
2326184914b5SBarry Smith 
232785385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
2328184914b5SBarry Smith @*/
23297087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
2330184914b5SBarry Smith {
2331184914b5SBarry Smith   PetscFunctionBegin;
23320700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
23334482741eSBarry Smith   PetscValidPointer(reason,2);
2334184914b5SBarry Smith   *reason = snes->reason;
2335184914b5SBarry Smith   PetscFunctionReturn(0);
2336184914b5SBarry Smith }
2337184914b5SBarry Smith 
23384a2ae208SSatish Balay #undef __FUNCT__
23394a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
2340c9005455SLois Curfman McInnes /*@
2341c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
2342c9005455SLois Curfman McInnes 
23433f9fe445SBarry Smith    Logically Collective on SNES
2344fee21e36SBarry Smith 
2345c7afd0dbSLois Curfman McInnes    Input Parameters:
2346c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
23478c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
2348cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
2349758f92a0SBarry Smith .  na  - size of a and its
235064731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
2351758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
2352c7afd0dbSLois Curfman McInnes 
2353308dcc3eSBarry Smith    Notes:
2354308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
2355308dcc3eSBarry Smith    default array of length 10000 is allocated.
2356308dcc3eSBarry Smith 
2357c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
2358c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
2359c9005455SLois Curfman McInnes    during the section of code that is being timed.
2360c9005455SLois Curfman McInnes 
236136851e7fSLois Curfman McInnes    Level: intermediate
236236851e7fSLois Curfman McInnes 
2363c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
2364758f92a0SBarry Smith 
236508405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
2366758f92a0SBarry Smith 
2367c9005455SLois Curfman McInnes @*/
23687087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
2369c9005455SLois Curfman McInnes {
2370308dcc3eSBarry Smith   PetscErrorCode ierr;
2371308dcc3eSBarry Smith 
23723a40ed3dSBarry Smith   PetscFunctionBegin;
23730700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
23744482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
2375a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
2376308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
2377308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
2378308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
2379308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
2380308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
2381308dcc3eSBarry Smith   }
2382c9005455SLois Curfman McInnes   snes->conv_hist       = a;
2383758f92a0SBarry Smith   snes->conv_hist_its   = its;
2384758f92a0SBarry Smith   snes->conv_hist_max   = na;
2385a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
2386758f92a0SBarry Smith   snes->conv_hist_reset = reset;
2387758f92a0SBarry Smith   PetscFunctionReturn(0);
2388758f92a0SBarry Smith }
2389758f92a0SBarry Smith 
2390308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
2391c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
2392c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
2393308dcc3eSBarry Smith EXTERN_C_BEGIN
2394308dcc3eSBarry Smith #undef __FUNCT__
2395308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
2396308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
2397308dcc3eSBarry Smith {
2398308dcc3eSBarry Smith   mxArray        *mat;
2399308dcc3eSBarry Smith   PetscInt       i;
2400308dcc3eSBarry Smith   PetscReal      *ar;
2401308dcc3eSBarry Smith 
2402308dcc3eSBarry Smith   PetscFunctionBegin;
2403308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
2404308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
2405308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
2406308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
2407308dcc3eSBarry Smith   }
2408308dcc3eSBarry Smith   PetscFunctionReturn(mat);
2409308dcc3eSBarry Smith }
2410308dcc3eSBarry Smith EXTERN_C_END
2411308dcc3eSBarry Smith #endif
2412308dcc3eSBarry Smith 
2413308dcc3eSBarry Smith 
24144a2ae208SSatish Balay #undef __FUNCT__
24154a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
24160c4c9dddSBarry Smith /*@C
2417758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
2418758f92a0SBarry Smith 
24193f9fe445SBarry Smith    Not Collective
2420758f92a0SBarry Smith 
2421758f92a0SBarry Smith    Input Parameter:
2422758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
2423758f92a0SBarry Smith 
2424758f92a0SBarry Smith    Output Parameters:
2425758f92a0SBarry Smith .  a   - array to hold history
2426758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
2427758f92a0SBarry Smith          negative if not converged) for each solve.
2428758f92a0SBarry Smith -  na  - size of a and its
2429758f92a0SBarry Smith 
2430758f92a0SBarry Smith    Notes:
2431758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
2432758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
2433758f92a0SBarry Smith 
2434758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
2435758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
2436758f92a0SBarry Smith    during the section of code that is being timed.
2437758f92a0SBarry Smith 
2438758f92a0SBarry Smith    Level: intermediate
2439758f92a0SBarry Smith 
2440758f92a0SBarry Smith .keywords: SNES, get, convergence, history
2441758f92a0SBarry Smith 
2442758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
2443758f92a0SBarry Smith 
2444758f92a0SBarry Smith @*/
24457087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
2446758f92a0SBarry Smith {
2447758f92a0SBarry Smith   PetscFunctionBegin;
24480700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2449758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
2450758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
2451758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
24523a40ed3dSBarry Smith   PetscFunctionReturn(0);
2453c9005455SLois Curfman McInnes }
2454c9005455SLois Curfman McInnes 
2455e74ef692SMatthew Knepley #undef __FUNCT__
2456e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
2457ac226902SBarry Smith /*@C
245876b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
2459eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
24607e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
246176b2cf59SMatthew Knepley 
24623f9fe445SBarry Smith   Logically Collective on SNES
246376b2cf59SMatthew Knepley 
246476b2cf59SMatthew Knepley   Input Parameters:
246576b2cf59SMatthew Knepley . snes - The nonlinear solver context
246676b2cf59SMatthew Knepley . func - The function
246776b2cf59SMatthew Knepley 
246876b2cf59SMatthew Knepley   Calling sequence of func:
2469b5d30489SBarry Smith . func (SNES snes, PetscInt step);
247076b2cf59SMatthew Knepley 
247176b2cf59SMatthew Knepley . step - The current step of the iteration
247276b2cf59SMatthew Knepley 
2473fe97e370SBarry Smith   Level: advanced
2474fe97e370SBarry Smith 
2475fe97e370SBarry 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()
2476fe97e370SBarry Smith         This is not used by most users.
247776b2cf59SMatthew Knepley 
247876b2cf59SMatthew Knepley .keywords: SNES, update
2479b5d30489SBarry Smith 
248085385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
248176b2cf59SMatthew Knepley @*/
24827087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
248376b2cf59SMatthew Knepley {
248476b2cf59SMatthew Knepley   PetscFunctionBegin;
24850700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
2486e7788613SBarry Smith   snes->ops->update = func;
248776b2cf59SMatthew Knepley   PetscFunctionReturn(0);
248876b2cf59SMatthew Knepley }
248976b2cf59SMatthew Knepley 
2490e74ef692SMatthew Knepley #undef __FUNCT__
2491e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
249276b2cf59SMatthew Knepley /*@
249376b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
249476b2cf59SMatthew Knepley 
249576b2cf59SMatthew Knepley   Not collective
249676b2cf59SMatthew Knepley 
249776b2cf59SMatthew Knepley   Input Parameters:
249876b2cf59SMatthew Knepley . snes - The nonlinear solver context
249976b2cf59SMatthew Knepley . step - The current step of the iteration
250076b2cf59SMatthew Knepley 
2501205452f4SMatthew Knepley   Level: intermediate
2502205452f4SMatthew Knepley 
250376b2cf59SMatthew Knepley .keywords: SNES, update
2504a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
250576b2cf59SMatthew Knepley @*/
25067087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
250776b2cf59SMatthew Knepley {
250876b2cf59SMatthew Knepley   PetscFunctionBegin;
250976b2cf59SMatthew Knepley   PetscFunctionReturn(0);
251076b2cf59SMatthew Knepley }
251176b2cf59SMatthew Knepley 
25124a2ae208SSatish Balay #undef __FUNCT__
25134a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
25149b94acceSBarry Smith /*
25159b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
25169b94acceSBarry Smith    positive parameter delta.
25179b94acceSBarry Smith 
25189b94acceSBarry Smith     Input Parameters:
2519c7afd0dbSLois Curfman McInnes +   snes - the SNES context
25209b94acceSBarry Smith .   y - approximate solution of linear system
25219b94acceSBarry Smith .   fnorm - 2-norm of current function
2522c7afd0dbSLois Curfman McInnes -   delta - trust region size
25239b94acceSBarry Smith 
25249b94acceSBarry Smith     Output Parameters:
2525c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
25269b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
25279b94acceSBarry Smith     region, and exceeds zero otherwise.
2528c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
25299b94acceSBarry Smith 
25309b94acceSBarry Smith     Note:
25314b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
25329b94acceSBarry Smith     is set to be the maximum allowable step size.
25339b94acceSBarry Smith 
25349b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
25359b94acceSBarry Smith */
2536dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
25379b94acceSBarry Smith {
2538064f8208SBarry Smith   PetscReal      nrm;
2539ea709b57SSatish Balay   PetscScalar    cnorm;
2540dfbe8321SBarry Smith   PetscErrorCode ierr;
25413a40ed3dSBarry Smith 
25423a40ed3dSBarry Smith   PetscFunctionBegin;
25430700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
25440700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
2545c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
2546184914b5SBarry Smith 
2547064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
2548064f8208SBarry Smith   if (nrm > *delta) {
2549064f8208SBarry Smith      nrm = *delta/nrm;
2550064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
2551064f8208SBarry Smith      cnorm = nrm;
25522dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
25539b94acceSBarry Smith      *ynorm = *delta;
25549b94acceSBarry Smith   } else {
25559b94acceSBarry Smith      *gpnorm = 0.0;
2556064f8208SBarry Smith      *ynorm = nrm;
25579b94acceSBarry Smith   }
25583a40ed3dSBarry Smith   PetscFunctionReturn(0);
25599b94acceSBarry Smith }
25609b94acceSBarry Smith 
25614a2ae208SSatish Balay #undef __FUNCT__
25624a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
25636ce558aeSBarry Smith /*@C
2564f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
2565f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
25669b94acceSBarry Smith 
2567c7afd0dbSLois Curfman McInnes    Collective on SNES
2568c7afd0dbSLois Curfman McInnes 
2569b2002411SLois Curfman McInnes    Input Parameters:
2570c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2571f69a0ea3SMatthew Knepley .  b - the constant part of the equation, or PETSC_NULL to use zero.
257285385478SLisandro Dalcin -  x - the solution vector.
25739b94acceSBarry Smith 
2574b2002411SLois Curfman McInnes    Notes:
25758ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
25768ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
25778ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
25788ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
25798ddd3da0SLois Curfman McInnes 
258036851e7fSLois Curfman McInnes    Level: beginner
258136851e7fSLois Curfman McInnes 
25829b94acceSBarry Smith .keywords: SNES, nonlinear, solve
25839b94acceSBarry Smith 
258485385478SLisandro Dalcin .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian()
25859b94acceSBarry Smith @*/
25867087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
25879b94acceSBarry Smith {
2588dfbe8321SBarry Smith   PetscErrorCode ierr;
2589ace3abfcSBarry Smith   PetscBool      flg;
2590eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
2591eabae89aSBarry Smith   PetscViewer    viewer;
2592efd51863SBarry Smith   PetscInt       grid;
2593052efed2SBarry Smith 
25943a40ed3dSBarry Smith   PetscFunctionBegin;
25950700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
25960700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
2597f69a0ea3SMatthew Knepley   PetscCheckSameComm(snes,1,x,3);
25980700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
259985385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
260085385478SLisandro Dalcin 
2601efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
2602efd51863SBarry Smith 
260385385478SLisandro Dalcin     /* set solution vector */
2604efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
26056bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
260685385478SLisandro Dalcin     snes->vec_sol = x;
260785385478SLisandro Dalcin     /* set afine vector if provided */
260885385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
26096bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
261085385478SLisandro Dalcin     snes->vec_rhs = b;
261185385478SLisandro Dalcin 
261270e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
26133f149594SLisandro Dalcin 
2614d25893d9SBarry Smith     if (!grid && snes->ops->computeinitialguess) {
2615d25893d9SBarry Smith       ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
2616d25893d9SBarry Smith     }
2617d25893d9SBarry Smith 
2618abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
261950ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
2620d5e45103SBarry Smith 
26213f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
26224936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
262385385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
26244936397dSBarry Smith     if (snes->domainerror){
26254936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
26264936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
26274936397dSBarry Smith     }
262817186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
26293f149594SLisandro Dalcin 
26307adad957SLisandro Dalcin     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
2631eabae89aSBarry Smith     if (flg && !PetscPreLoadingOn) {
26327adad957SLisandro Dalcin       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
2633eabae89aSBarry Smith       ierr = SNESView(snes,viewer);CHKERRQ(ierr);
26346bf464f9SBarry Smith       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
2635eabae89aSBarry Smith     }
2636eabae89aSBarry Smith 
263790d69ab7SBarry Smith     flg  = PETSC_FALSE;
2638acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
2639da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
26405968eb51SBarry Smith     if (snes->printreason) {
26415968eb51SBarry Smith       if (snes->reason > 0) {
26427adad957SLisandro Dalcin         ierr = PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr);
26435968eb51SBarry Smith       } else {
26447adad957SLisandro Dalcin         ierr = PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr);
26455968eb51SBarry Smith       }
26465968eb51SBarry Smith     }
26475968eb51SBarry Smith 
2648e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
2649efd51863SBarry Smith     if (grid <  snes->gridsequence) {
2650efd51863SBarry Smith       DM  fine;
2651efd51863SBarry Smith       Vec xnew;
2652efd51863SBarry Smith       Mat interp;
2653efd51863SBarry Smith 
2654efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
2655efd51863SBarry Smith       ierr = DMGetInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
2656efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
2657efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
2658efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
2659efd51863SBarry Smith       x    = xnew;
2660efd51863SBarry Smith 
2661efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
2662efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
2663efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
2664efd51863SBarry Smith     }
2665efd51863SBarry Smith   }
26663a40ed3dSBarry Smith   PetscFunctionReturn(0);
26679b94acceSBarry Smith }
26689b94acceSBarry Smith 
26699b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
26709b94acceSBarry Smith 
26714a2ae208SSatish Balay #undef __FUNCT__
26724a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
267382bf6240SBarry Smith /*@C
26744b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
26759b94acceSBarry Smith 
2676fee21e36SBarry Smith    Collective on SNES
2677fee21e36SBarry Smith 
2678c7afd0dbSLois Curfman McInnes    Input Parameters:
2679c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2680454a90a3SBarry Smith -  type - a known method
2681c7afd0dbSLois Curfman McInnes 
2682c7afd0dbSLois Curfman McInnes    Options Database Key:
2683454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
2684c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
2685ae12b187SLois Curfman McInnes 
26869b94acceSBarry Smith    Notes:
2687e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
26884b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
2689c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
26904b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
2691c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
26929b94acceSBarry Smith 
2693ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
2694ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
2695ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
2696ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
2697ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
2698ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
2699ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
2700ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
2701ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
2702b0a32e0cSBarry Smith   appropriate method.
270336851e7fSLois Curfman McInnes 
270436851e7fSLois Curfman McInnes   Level: intermediate
2705a703fe33SLois Curfman McInnes 
2706454a90a3SBarry Smith .keywords: SNES, set, type
2707435da068SBarry Smith 
2708435da068SBarry Smith .seealso: SNESType, SNESCreate()
2709435da068SBarry Smith 
27109b94acceSBarry Smith @*/
27117087cfbeSBarry Smith PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
27129b94acceSBarry Smith {
2713dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
2714ace3abfcSBarry Smith   PetscBool      match;
27153a40ed3dSBarry Smith 
27163a40ed3dSBarry Smith   PetscFunctionBegin;
27170700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
27184482741eSBarry Smith   PetscValidCharPointer(type,2);
271982bf6240SBarry Smith 
27206831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
27210f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
272292ff6ae8SBarry Smith 
27234b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
2724e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
272575396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
272675396ef9SLisandro Dalcin   if (snes->ops->destroy) { ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); }
272775396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
272875396ef9SLisandro Dalcin   snes->ops->setup          = 0;
272975396ef9SLisandro Dalcin   snes->ops->solve          = 0;
273075396ef9SLisandro Dalcin   snes->ops->view           = 0;
273175396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
273275396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
273375396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
273475396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
2735454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
273603bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
27379fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
27389fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
27399fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
27409fb22e1aSBarry Smith   }
27419fb22e1aSBarry Smith #endif
27423a40ed3dSBarry Smith   PetscFunctionReturn(0);
27439b94acceSBarry Smith }
27449b94acceSBarry Smith 
2745a847f771SSatish Balay 
27469b94acceSBarry Smith /* --------------------------------------------------------------------- */
27474a2ae208SSatish Balay #undef __FUNCT__
27484a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
274952baeb72SSatish Balay /*@
27509b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
2751f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
27529b94acceSBarry Smith 
2753fee21e36SBarry Smith    Not Collective
2754fee21e36SBarry Smith 
275536851e7fSLois Curfman McInnes    Level: advanced
275636851e7fSLois Curfman McInnes 
27579b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
27589b94acceSBarry Smith 
27599b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
27609b94acceSBarry Smith @*/
27617087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
27629b94acceSBarry Smith {
2763dfbe8321SBarry Smith   PetscErrorCode ierr;
276482bf6240SBarry Smith 
27653a40ed3dSBarry Smith   PetscFunctionBegin;
27661441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
27674c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
27683a40ed3dSBarry Smith   PetscFunctionReturn(0);
27699b94acceSBarry Smith }
27709b94acceSBarry Smith 
27714a2ae208SSatish Balay #undef __FUNCT__
27724a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
27739b94acceSBarry Smith /*@C
27749a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
27759b94acceSBarry Smith 
2776c7afd0dbSLois Curfman McInnes    Not Collective
2777c7afd0dbSLois Curfman McInnes 
27789b94acceSBarry Smith    Input Parameter:
27794b0e389bSBarry Smith .  snes - nonlinear solver context
27809b94acceSBarry Smith 
27819b94acceSBarry Smith    Output Parameter:
27823a7fca6bSBarry Smith .  type - SNES method (a character string)
27839b94acceSBarry Smith 
278436851e7fSLois Curfman McInnes    Level: intermediate
278536851e7fSLois Curfman McInnes 
2786454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
27879b94acceSBarry Smith @*/
27887087cfbeSBarry Smith PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
27899b94acceSBarry Smith {
27903a40ed3dSBarry Smith   PetscFunctionBegin;
27910700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
27924482741eSBarry Smith   PetscValidPointer(type,2);
27937adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
27943a40ed3dSBarry Smith   PetscFunctionReturn(0);
27959b94acceSBarry Smith }
27969b94acceSBarry Smith 
27974a2ae208SSatish Balay #undef __FUNCT__
27984a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
279952baeb72SSatish Balay /*@
28009b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
28019b94acceSBarry Smith    stored.
28029b94acceSBarry Smith 
2803c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
2804c7afd0dbSLois Curfman McInnes 
28059b94acceSBarry Smith    Input Parameter:
28069b94acceSBarry Smith .  snes - the SNES context
28079b94acceSBarry Smith 
28089b94acceSBarry Smith    Output Parameter:
28099b94acceSBarry Smith .  x - the solution
28109b94acceSBarry Smith 
281170e92668SMatthew Knepley    Level: intermediate
281236851e7fSLois Curfman McInnes 
28139b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
28149b94acceSBarry Smith 
281585385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
28169b94acceSBarry Smith @*/
28177087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
28189b94acceSBarry Smith {
28193a40ed3dSBarry Smith   PetscFunctionBegin;
28200700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
28214482741eSBarry Smith   PetscValidPointer(x,2);
282285385478SLisandro Dalcin   *x = snes->vec_sol;
282370e92668SMatthew Knepley   PetscFunctionReturn(0);
282470e92668SMatthew Knepley }
282570e92668SMatthew Knepley 
282670e92668SMatthew Knepley #undef __FUNCT__
28274a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
282852baeb72SSatish Balay /*@
28299b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
28309b94acceSBarry Smith    stored.
28319b94acceSBarry Smith 
2832c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
2833c7afd0dbSLois Curfman McInnes 
28349b94acceSBarry Smith    Input Parameter:
28359b94acceSBarry Smith .  snes - the SNES context
28369b94acceSBarry Smith 
28379b94acceSBarry Smith    Output Parameter:
28389b94acceSBarry Smith .  x - the solution update
28399b94acceSBarry Smith 
284036851e7fSLois Curfman McInnes    Level: advanced
284136851e7fSLois Curfman McInnes 
28429b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
28439b94acceSBarry Smith 
284485385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
28459b94acceSBarry Smith @*/
28467087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
28479b94acceSBarry Smith {
28483a40ed3dSBarry Smith   PetscFunctionBegin;
28490700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
28504482741eSBarry Smith   PetscValidPointer(x,2);
285185385478SLisandro Dalcin   *x = snes->vec_sol_update;
28523a40ed3dSBarry Smith   PetscFunctionReturn(0);
28539b94acceSBarry Smith }
28549b94acceSBarry Smith 
28554a2ae208SSatish Balay #undef __FUNCT__
28564a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
28579b94acceSBarry Smith /*@C
28583638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
28599b94acceSBarry Smith 
2860c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
2861c7afd0dbSLois Curfman McInnes 
28629b94acceSBarry Smith    Input Parameter:
28639b94acceSBarry Smith .  snes - the SNES context
28649b94acceSBarry Smith 
28659b94acceSBarry Smith    Output Parameter:
28667bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
286770e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
286870e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
28699b94acceSBarry Smith 
287036851e7fSLois Curfman McInnes    Level: advanced
287136851e7fSLois Curfman McInnes 
2872a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
28739b94acceSBarry Smith 
28744b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
28759b94acceSBarry Smith @*/
28767087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
28779b94acceSBarry Smith {
28783a40ed3dSBarry Smith   PetscFunctionBegin;
28790700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
288085385478SLisandro Dalcin   if (r)    *r    = snes->vec_func;
2881e7788613SBarry Smith   if (func) *func = snes->ops->computefunction;
288270e92668SMatthew Knepley   if (ctx)  *ctx  = snes->funP;
28833a40ed3dSBarry Smith   PetscFunctionReturn(0);
28849b94acceSBarry Smith }
28859b94acceSBarry Smith 
28864a2ae208SSatish Balay #undef __FUNCT__
28874a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
28883c7409f5SSatish Balay /*@C
28893c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
2890d850072dSLois Curfman McInnes    SNES options in the database.
28913c7409f5SSatish Balay 
28923f9fe445SBarry Smith    Logically Collective on SNES
2893fee21e36SBarry Smith 
2894c7afd0dbSLois Curfman McInnes    Input Parameter:
2895c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2896c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
2897c7afd0dbSLois Curfman McInnes 
2898d850072dSLois Curfman McInnes    Notes:
2899a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
2900c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
2901d850072dSLois Curfman McInnes 
290236851e7fSLois Curfman McInnes    Level: advanced
290336851e7fSLois Curfman McInnes 
29043c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
2905a86d99e1SLois Curfman McInnes 
2906a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
29073c7409f5SSatish Balay @*/
29087087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
29093c7409f5SSatish Balay {
2910dfbe8321SBarry Smith   PetscErrorCode ierr;
29113c7409f5SSatish Balay 
29123a40ed3dSBarry Smith   PetscFunctionBegin;
29130700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2914639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
29151cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
291694b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
29173a40ed3dSBarry Smith   PetscFunctionReturn(0);
29183c7409f5SSatish Balay }
29193c7409f5SSatish Balay 
29204a2ae208SSatish Balay #undef __FUNCT__
29214a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
29223c7409f5SSatish Balay /*@C
2923f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
2924d850072dSLois Curfman McInnes    SNES options in the database.
29253c7409f5SSatish Balay 
29263f9fe445SBarry Smith    Logically Collective on SNES
2927fee21e36SBarry Smith 
2928c7afd0dbSLois Curfman McInnes    Input Parameters:
2929c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2930c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
2931c7afd0dbSLois Curfman McInnes 
2932d850072dSLois Curfman McInnes    Notes:
2933a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
2934c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
2935d850072dSLois Curfman McInnes 
293636851e7fSLois Curfman McInnes    Level: advanced
293736851e7fSLois Curfman McInnes 
29383c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
2939a86d99e1SLois Curfman McInnes 
2940a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
29413c7409f5SSatish Balay @*/
29427087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
29433c7409f5SSatish Balay {
2944dfbe8321SBarry Smith   PetscErrorCode ierr;
29453c7409f5SSatish Balay 
29463a40ed3dSBarry Smith   PetscFunctionBegin;
29470700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2948639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
29491cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
295094b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
29513a40ed3dSBarry Smith   PetscFunctionReturn(0);
29523c7409f5SSatish Balay }
29533c7409f5SSatish Balay 
29544a2ae208SSatish Balay #undef __FUNCT__
29554a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
29569ab63eb5SSatish Balay /*@C
29573c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
29583c7409f5SSatish Balay    SNES options in the database.
29593c7409f5SSatish Balay 
2960c7afd0dbSLois Curfman McInnes    Not Collective
2961c7afd0dbSLois Curfman McInnes 
29623c7409f5SSatish Balay    Input Parameter:
29633c7409f5SSatish Balay .  snes - the SNES context
29643c7409f5SSatish Balay 
29653c7409f5SSatish Balay    Output Parameter:
29663c7409f5SSatish Balay .  prefix - pointer to the prefix string used
29673c7409f5SSatish Balay 
29684ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
29699ab63eb5SSatish Balay    sufficient length to hold the prefix.
29709ab63eb5SSatish Balay 
297136851e7fSLois Curfman McInnes    Level: advanced
297236851e7fSLois Curfman McInnes 
29733c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
2974a86d99e1SLois Curfman McInnes 
2975a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
29763c7409f5SSatish Balay @*/
29777087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
29783c7409f5SSatish Balay {
2979dfbe8321SBarry Smith   PetscErrorCode ierr;
29803c7409f5SSatish Balay 
29813a40ed3dSBarry Smith   PetscFunctionBegin;
29820700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2983639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
29843a40ed3dSBarry Smith   PetscFunctionReturn(0);
29853c7409f5SSatish Balay }
29863c7409f5SSatish Balay 
2987b2002411SLois Curfman McInnes 
29884a2ae208SSatish Balay #undef __FUNCT__
29894a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
29903cea93caSBarry Smith /*@C
29913cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
29923cea93caSBarry Smith 
29937f6c08e0SMatthew Knepley   Level: advanced
29943cea93caSBarry Smith @*/
29957087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
2996b2002411SLois Curfman McInnes {
2997e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
2998dfbe8321SBarry Smith   PetscErrorCode ierr;
2999b2002411SLois Curfman McInnes 
3000b2002411SLois Curfman McInnes   PetscFunctionBegin;
3001b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3002c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3003b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
3004b2002411SLois Curfman McInnes }
3005da9b6338SBarry Smith 
3006da9b6338SBarry Smith #undef __FUNCT__
3007da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
30087087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
3009da9b6338SBarry Smith {
3010dfbe8321SBarry Smith   PetscErrorCode ierr;
301177431f27SBarry Smith   PetscInt       N,i,j;
3012da9b6338SBarry Smith   Vec            u,uh,fh;
3013da9b6338SBarry Smith   PetscScalar    value;
3014da9b6338SBarry Smith   PetscReal      norm;
3015da9b6338SBarry Smith 
3016da9b6338SBarry Smith   PetscFunctionBegin;
3017da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
3018da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
3019da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
3020da9b6338SBarry Smith 
3021da9b6338SBarry Smith   /* currently only works for sequential */
3022da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
3023da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
3024da9b6338SBarry Smith   for (i=0; i<N; i++) {
3025da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
302677431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
3027da9b6338SBarry Smith     for (j=-10; j<11; j++) {
3028ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
3029da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
30303ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
3031da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
303277431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
3033da9b6338SBarry Smith       value = -value;
3034da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
3035da9b6338SBarry Smith     }
3036da9b6338SBarry Smith   }
30376bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
30386bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
3039da9b6338SBarry Smith   PetscFunctionReturn(0);
3040da9b6338SBarry Smith }
304171f87433Sdalcinl 
304271f87433Sdalcinl #undef __FUNCT__
3043fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
304471f87433Sdalcinl /*@
3045fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
304671f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
304771f87433Sdalcinl    Newton method.
304871f87433Sdalcinl 
30493f9fe445SBarry Smith    Logically Collective on SNES
305071f87433Sdalcinl 
305171f87433Sdalcinl    Input Parameters:
305271f87433Sdalcinl +  snes - SNES context
305371f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
305471f87433Sdalcinl 
305564ba62caSBarry Smith     Options Database:
305664ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
305764ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
305864ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
305964ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
306064ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
306164ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
306264ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
306364ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
306464ba62caSBarry Smith 
306571f87433Sdalcinl    Notes:
306671f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
306771f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
306871f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
306971f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
307071f87433Sdalcinl    solver.
307171f87433Sdalcinl 
307271f87433Sdalcinl    Level: advanced
307371f87433Sdalcinl 
307471f87433Sdalcinl    Reference:
307571f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
307671f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
307771f87433Sdalcinl 
307871f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
307971f87433Sdalcinl 
3080fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
308171f87433Sdalcinl @*/
30827087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
308371f87433Sdalcinl {
308471f87433Sdalcinl   PetscFunctionBegin;
30850700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3086acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
308771f87433Sdalcinl   snes->ksp_ewconv = flag;
308871f87433Sdalcinl   PetscFunctionReturn(0);
308971f87433Sdalcinl }
309071f87433Sdalcinl 
309171f87433Sdalcinl #undef __FUNCT__
3092fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
309371f87433Sdalcinl /*@
3094fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
309571f87433Sdalcinl    for computing relative tolerance for linear solvers within an
309671f87433Sdalcinl    inexact Newton method.
309771f87433Sdalcinl 
309871f87433Sdalcinl    Not Collective
309971f87433Sdalcinl 
310071f87433Sdalcinl    Input Parameter:
310171f87433Sdalcinl .  snes - SNES context
310271f87433Sdalcinl 
310371f87433Sdalcinl    Output Parameter:
310471f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
310571f87433Sdalcinl 
310671f87433Sdalcinl    Notes:
310771f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
310871f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
310971f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
311071f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
311171f87433Sdalcinl    solver.
311271f87433Sdalcinl 
311371f87433Sdalcinl    Level: advanced
311471f87433Sdalcinl 
311571f87433Sdalcinl    Reference:
311671f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
311771f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
311871f87433Sdalcinl 
311971f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
312071f87433Sdalcinl 
3121fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
312271f87433Sdalcinl @*/
31237087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
312471f87433Sdalcinl {
312571f87433Sdalcinl   PetscFunctionBegin;
31260700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
312771f87433Sdalcinl   PetscValidPointer(flag,2);
312871f87433Sdalcinl   *flag = snes->ksp_ewconv;
312971f87433Sdalcinl   PetscFunctionReturn(0);
313071f87433Sdalcinl }
313171f87433Sdalcinl 
313271f87433Sdalcinl #undef __FUNCT__
3133fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
313471f87433Sdalcinl /*@
3135fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
313671f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
313771f87433Sdalcinl    Newton method.
313871f87433Sdalcinl 
31393f9fe445SBarry Smith    Logically Collective on SNES
314071f87433Sdalcinl 
314171f87433Sdalcinl    Input Parameters:
314271f87433Sdalcinl +    snes - SNES context
314371f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
314471f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
314571f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
314671f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
314771f87433Sdalcinl              (0 <= gamma2 <= 1)
314871f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
314971f87433Sdalcinl .    alpha2 - power for safeguard
315071f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
315171f87433Sdalcinl 
315271f87433Sdalcinl    Note:
315371f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
315471f87433Sdalcinl 
315571f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
315671f87433Sdalcinl 
315771f87433Sdalcinl    Level: advanced
315871f87433Sdalcinl 
315971f87433Sdalcinl    Reference:
316071f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
316171f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
316271f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
316371f87433Sdalcinl 
316471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
316571f87433Sdalcinl 
3166fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
316771f87433Sdalcinl @*/
31687087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
316971f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
317071f87433Sdalcinl {
3171fa9f3622SBarry Smith   SNESKSPEW *kctx;
317271f87433Sdalcinl   PetscFunctionBegin;
31730700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3174fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3175e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
3176c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
3177c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
3178c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
3179c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
3180c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
3181c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
3182c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
318371f87433Sdalcinl 
318471f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
318571f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
318671f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
318771f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
318871f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
318971f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
319071f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
319171f87433Sdalcinl 
319271f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
3193e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
319471f87433Sdalcinl   }
319571f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
3196e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
319771f87433Sdalcinl   }
319871f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
3199e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
320071f87433Sdalcinl   }
320171f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
3202e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
320371f87433Sdalcinl   }
320471f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
3205e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
320671f87433Sdalcinl   }
320771f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
3208e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
320971f87433Sdalcinl   }
321071f87433Sdalcinl   PetscFunctionReturn(0);
321171f87433Sdalcinl }
321271f87433Sdalcinl 
321371f87433Sdalcinl #undef __FUNCT__
3214fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
321571f87433Sdalcinl /*@
3216fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
321771f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
321871f87433Sdalcinl    Newton method.
321971f87433Sdalcinl 
322071f87433Sdalcinl    Not Collective
322171f87433Sdalcinl 
322271f87433Sdalcinl    Input Parameters:
322371f87433Sdalcinl      snes - SNES context
322471f87433Sdalcinl 
322571f87433Sdalcinl    Output Parameters:
322671f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
322771f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
322871f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
322971f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
323071f87433Sdalcinl              (0 <= gamma2 <= 1)
323171f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
323271f87433Sdalcinl .    alpha2 - power for safeguard
323371f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
323471f87433Sdalcinl 
323571f87433Sdalcinl    Level: advanced
323671f87433Sdalcinl 
323771f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
323871f87433Sdalcinl 
3239fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
324071f87433Sdalcinl @*/
32417087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
324271f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
324371f87433Sdalcinl {
3244fa9f3622SBarry Smith   SNESKSPEW *kctx;
324571f87433Sdalcinl   PetscFunctionBegin;
32460700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3247fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3248e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
324971f87433Sdalcinl   if(version)   *version   = kctx->version;
325071f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
325171f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
325271f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
325371f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
325471f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
325571f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
325671f87433Sdalcinl   PetscFunctionReturn(0);
325771f87433Sdalcinl }
325871f87433Sdalcinl 
325971f87433Sdalcinl #undef __FUNCT__
3260fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
3261fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
326271f87433Sdalcinl {
326371f87433Sdalcinl   PetscErrorCode ierr;
3264fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
326571f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
326671f87433Sdalcinl 
326771f87433Sdalcinl   PetscFunctionBegin;
3268e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
326971f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
327071f87433Sdalcinl     rtol = kctx->rtol_0;
327171f87433Sdalcinl   } else {
327271f87433Sdalcinl     if (kctx->version == 1) {
327371f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
327471f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
327571f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
327671f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
327771f87433Sdalcinl     } else if (kctx->version == 2) {
327871f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
327971f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
328071f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
328171f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
328271f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
328371f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
328471f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
328571f87433Sdalcinl       stol = PetscMax(rtol,stol);
328671f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
328771f87433Sdalcinl       /* safeguard: avoid oversolving */
328871f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
328971f87433Sdalcinl       stol = PetscMax(rtol,stol);
329071f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
3291e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
329271f87433Sdalcinl   }
329371f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
329471f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
329571f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
329671f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
329771f87433Sdalcinl   PetscFunctionReturn(0);
329871f87433Sdalcinl }
329971f87433Sdalcinl 
330071f87433Sdalcinl #undef __FUNCT__
3301fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
3302fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
330371f87433Sdalcinl {
330471f87433Sdalcinl   PetscErrorCode ierr;
3305fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
330671f87433Sdalcinl   PCSide         pcside;
330771f87433Sdalcinl   Vec            lres;
330871f87433Sdalcinl 
330971f87433Sdalcinl   PetscFunctionBegin;
3310e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
331171f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
331271f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
331371f87433Sdalcinl   if (kctx->version == 1) {
3314b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
331571f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
331671f87433Sdalcinl       /* KSP residual is true linear residual */
331771f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
331871f87433Sdalcinl     } else {
331971f87433Sdalcinl       /* KSP residual is preconditioned residual */
332071f87433Sdalcinl       /* compute true linear residual norm */
332171f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
332271f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
332371f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
332471f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
33256bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
332671f87433Sdalcinl     }
332771f87433Sdalcinl   }
332871f87433Sdalcinl   PetscFunctionReturn(0);
332971f87433Sdalcinl }
333071f87433Sdalcinl 
333171f87433Sdalcinl #undef __FUNCT__
333271f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
333371f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
333471f87433Sdalcinl {
333571f87433Sdalcinl   PetscErrorCode ierr;
333671f87433Sdalcinl 
333771f87433Sdalcinl   PetscFunctionBegin;
3338fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
333971f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
3340fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
334171f87433Sdalcinl   PetscFunctionReturn(0);
334271f87433Sdalcinl }
33436c699258SBarry Smith 
33446c699258SBarry Smith #undef __FUNCT__
33456c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
33466c699258SBarry Smith /*@
33476c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
33486c699258SBarry Smith 
33493f9fe445SBarry Smith    Logically Collective on SNES
33506c699258SBarry Smith 
33516c699258SBarry Smith    Input Parameters:
33526c699258SBarry Smith +  snes - the preconditioner context
33536c699258SBarry Smith -  dm - the dm
33546c699258SBarry Smith 
33556c699258SBarry Smith    Level: intermediate
33566c699258SBarry Smith 
33576c699258SBarry Smith 
33586c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
33596c699258SBarry Smith @*/
33607087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
33616c699258SBarry Smith {
33626c699258SBarry Smith   PetscErrorCode ierr;
3363345fed2cSBarry Smith   KSP            ksp;
33646c699258SBarry Smith 
33656c699258SBarry Smith   PetscFunctionBegin;
33660700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3367d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
33686bf464f9SBarry Smith   ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
33696c699258SBarry Smith   snes->dm = dm;
3370345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
3371345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
3372f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
33736c699258SBarry Smith   PetscFunctionReturn(0);
33746c699258SBarry Smith }
33756c699258SBarry Smith 
33766c699258SBarry Smith #undef __FUNCT__
33776c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
33786c699258SBarry Smith /*@
33796c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
33806c699258SBarry Smith 
33813f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
33826c699258SBarry Smith 
33836c699258SBarry Smith    Input Parameter:
33846c699258SBarry Smith . snes - the preconditioner context
33856c699258SBarry Smith 
33866c699258SBarry Smith    Output Parameter:
33876c699258SBarry Smith .  dm - the dm
33886c699258SBarry Smith 
33896c699258SBarry Smith    Level: intermediate
33906c699258SBarry Smith 
33916c699258SBarry Smith 
33926c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
33936c699258SBarry Smith @*/
33947087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
33956c699258SBarry Smith {
33966c699258SBarry Smith   PetscFunctionBegin;
33970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
33986c699258SBarry Smith   *dm = snes->dm;
33996c699258SBarry Smith   PetscFunctionReturn(0);
34006c699258SBarry Smith }
34010807856dSBarry Smith 
340269b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3403c6db04a5SJed Brown #include <mex.h>
340469b4f73cSBarry Smith 
34058f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
34068f6e6473SBarry Smith 
34070807856dSBarry Smith #undef __FUNCT__
34080807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
34090807856dSBarry Smith /*
34100807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
34110807856dSBarry Smith                          SNESSetFunctionMatlab().
34120807856dSBarry Smith 
34130807856dSBarry Smith    Collective on SNES
34140807856dSBarry Smith 
34150807856dSBarry Smith    Input Parameters:
34160807856dSBarry Smith +  snes - the SNES context
34170807856dSBarry Smith -  x - input vector
34180807856dSBarry Smith 
34190807856dSBarry Smith    Output Parameter:
34200807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
34210807856dSBarry Smith 
34220807856dSBarry Smith    Notes:
34230807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
34240807856dSBarry Smith    implementations, so most users would not generally call this routine
34250807856dSBarry Smith    themselves.
34260807856dSBarry Smith 
34270807856dSBarry Smith    Level: developer
34280807856dSBarry Smith 
34290807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
34300807856dSBarry Smith 
34310807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
343261b2408cSBarry Smith */
34337087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
34340807856dSBarry Smith {
3435e650e774SBarry Smith   PetscErrorCode    ierr;
34368f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
34378f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
34388f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
343991621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
3440e650e774SBarry Smith 
34410807856dSBarry Smith   PetscFunctionBegin;
34420807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
34430807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
34440807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
34450807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
34460807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
34470807856dSBarry Smith 
34480807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
3449e650e774SBarry Smith 
345091621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
3451e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
3452e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
345391621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
345491621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
345591621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
34568f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
34578f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
3458b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
3459e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
3460e650e774SBarry Smith   mxDestroyArray(prhs[0]);
3461e650e774SBarry Smith   mxDestroyArray(prhs[1]);
3462e650e774SBarry Smith   mxDestroyArray(prhs[2]);
34638f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
3464e650e774SBarry Smith   mxDestroyArray(plhs[0]);
34650807856dSBarry Smith   PetscFunctionReturn(0);
34660807856dSBarry Smith }
34670807856dSBarry Smith 
34680807856dSBarry Smith 
34690807856dSBarry Smith #undef __FUNCT__
34700807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
347161b2408cSBarry Smith /*
34720807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
34730807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
3474e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
34750807856dSBarry Smith 
34760807856dSBarry Smith    Logically Collective on SNES
34770807856dSBarry Smith 
34780807856dSBarry Smith    Input Parameters:
34790807856dSBarry Smith +  snes - the SNES context
34800807856dSBarry Smith .  r - vector to store function value
34810807856dSBarry Smith -  func - function evaluation routine
34820807856dSBarry Smith 
34830807856dSBarry Smith    Calling sequence of func:
348461b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
34850807856dSBarry Smith 
34860807856dSBarry Smith 
34870807856dSBarry Smith    Notes:
34880807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
34890807856dSBarry Smith $      f'(x) x = -f(x),
34900807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
34910807856dSBarry Smith 
34920807856dSBarry Smith    Level: beginner
34930807856dSBarry Smith 
34940807856dSBarry Smith .keywords: SNES, nonlinear, set, function
34950807856dSBarry Smith 
34960807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
349761b2408cSBarry Smith */
34987087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
34990807856dSBarry Smith {
35000807856dSBarry Smith   PetscErrorCode    ierr;
35018f6e6473SBarry Smith   SNESMatlabContext *sctx;
35020807856dSBarry Smith 
35030807856dSBarry Smith   PetscFunctionBegin;
35048f6e6473SBarry Smith   /* currently sctx is memory bleed */
35058f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
35068f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
35078f6e6473SBarry Smith   /*
35088f6e6473SBarry Smith      This should work, but it doesn't
35098f6e6473SBarry Smith   sctx->ctx = ctx;
35108f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
35118f6e6473SBarry Smith   */
35128f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
35138f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
35140807856dSBarry Smith   PetscFunctionReturn(0);
35150807856dSBarry Smith }
351669b4f73cSBarry Smith 
351761b2408cSBarry Smith #undef __FUNCT__
351861b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
351961b2408cSBarry Smith /*
352061b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
352161b2408cSBarry Smith                          SNESSetJacobianMatlab().
352261b2408cSBarry Smith 
352361b2408cSBarry Smith    Collective on SNES
352461b2408cSBarry Smith 
352561b2408cSBarry Smith    Input Parameters:
352661b2408cSBarry Smith +  snes - the SNES context
352761b2408cSBarry Smith .  x - input vector
352861b2408cSBarry Smith .  A, B - the matrices
352961b2408cSBarry Smith -  ctx - user context
353061b2408cSBarry Smith 
353161b2408cSBarry Smith    Output Parameter:
353261b2408cSBarry Smith .  flag - structure of the matrix
353361b2408cSBarry Smith 
353461b2408cSBarry Smith    Level: developer
353561b2408cSBarry Smith 
353661b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
353761b2408cSBarry Smith 
353861b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
353961b2408cSBarry Smith @*/
35407087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
354161b2408cSBarry Smith {
354261b2408cSBarry Smith   PetscErrorCode    ierr;
354361b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
354461b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
354561b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
354661b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
354761b2408cSBarry Smith 
354861b2408cSBarry Smith   PetscFunctionBegin;
354961b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
355061b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
355161b2408cSBarry Smith 
355261b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
355361b2408cSBarry Smith 
355461b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
355561b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
355661b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
355761b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
355861b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
355961b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
356061b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
356161b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
356261b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
356361b2408cSBarry Smith   prhs[5] =  sctx->ctx;
3564b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
356561b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
356661b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
356761b2408cSBarry Smith   mxDestroyArray(prhs[0]);
356861b2408cSBarry Smith   mxDestroyArray(prhs[1]);
356961b2408cSBarry Smith   mxDestroyArray(prhs[2]);
357061b2408cSBarry Smith   mxDestroyArray(prhs[3]);
357161b2408cSBarry Smith   mxDestroyArray(prhs[4]);
357261b2408cSBarry Smith   mxDestroyArray(plhs[0]);
357361b2408cSBarry Smith   mxDestroyArray(plhs[1]);
357461b2408cSBarry Smith   PetscFunctionReturn(0);
357561b2408cSBarry Smith }
357661b2408cSBarry Smith 
357761b2408cSBarry Smith 
357861b2408cSBarry Smith #undef __FUNCT__
357961b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
358061b2408cSBarry Smith /*
358161b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
358261b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
3583e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
358461b2408cSBarry Smith 
358561b2408cSBarry Smith    Logically Collective on SNES
358661b2408cSBarry Smith 
358761b2408cSBarry Smith    Input Parameters:
358861b2408cSBarry Smith +  snes - the SNES context
358961b2408cSBarry Smith .  A,B - Jacobian matrices
359061b2408cSBarry Smith .  func - function evaluation routine
359161b2408cSBarry Smith -  ctx - user context
359261b2408cSBarry Smith 
359361b2408cSBarry Smith    Calling sequence of func:
359461b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
359561b2408cSBarry Smith 
359661b2408cSBarry Smith 
359761b2408cSBarry Smith    Level: developer
359861b2408cSBarry Smith 
359961b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
360061b2408cSBarry Smith 
360161b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
360261b2408cSBarry Smith */
36037087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
360461b2408cSBarry Smith {
360561b2408cSBarry Smith   PetscErrorCode    ierr;
360661b2408cSBarry Smith   SNESMatlabContext *sctx;
360761b2408cSBarry Smith 
360861b2408cSBarry Smith   PetscFunctionBegin;
360961b2408cSBarry Smith   /* currently sctx is memory bleed */
361061b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
361161b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
361261b2408cSBarry Smith   /*
361361b2408cSBarry Smith      This should work, but it doesn't
361461b2408cSBarry Smith   sctx->ctx = ctx;
361561b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
361661b2408cSBarry Smith   */
361761b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
361861b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
361961b2408cSBarry Smith   PetscFunctionReturn(0);
362061b2408cSBarry Smith }
362169b4f73cSBarry Smith 
3622f9eb7ae2SShri Abhyankar #undef __FUNCT__
3623f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
3624f9eb7ae2SShri Abhyankar /*
3625f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
3626f9eb7ae2SShri Abhyankar 
3627f9eb7ae2SShri Abhyankar    Collective on SNES
3628f9eb7ae2SShri Abhyankar 
3629f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
3630f9eb7ae2SShri Abhyankar @*/
36317087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
3632f9eb7ae2SShri Abhyankar {
3633f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
363448f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
3635f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
3636f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
3637f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
3638f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
3639f9eb7ae2SShri Abhyankar 
3640f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
3641f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3642f9eb7ae2SShri Abhyankar 
3643f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
3644f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
3645f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
3646f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
3647f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
3648f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
3649f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
3650f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
3651f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
3652f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
3653f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
3654f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
3655f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
3656f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
3657f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
3658f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
3659f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
3660f9eb7ae2SShri Abhyankar }
3661f9eb7ae2SShri Abhyankar 
3662f9eb7ae2SShri Abhyankar 
3663f9eb7ae2SShri Abhyankar #undef __FUNCT__
3664f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
3665f9eb7ae2SShri Abhyankar /*
3666e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
3667f9eb7ae2SShri Abhyankar 
3668f9eb7ae2SShri Abhyankar    Level: developer
3669f9eb7ae2SShri Abhyankar 
3670f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
3671f9eb7ae2SShri Abhyankar 
3672f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
3673f9eb7ae2SShri Abhyankar */
36747087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
3675f9eb7ae2SShri Abhyankar {
3676f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
3677f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
3678f9eb7ae2SShri Abhyankar 
3679f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
3680f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
3681f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
3682f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
3683f9eb7ae2SShri Abhyankar   /*
3684f9eb7ae2SShri Abhyankar      This should work, but it doesn't
3685f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
3686f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
3687f9eb7ae2SShri Abhyankar   */
3688f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
3689f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
3690f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
3691f9eb7ae2SShri Abhyankar }
3692f9eb7ae2SShri Abhyankar 
369369b4f73cSBarry Smith #endif
3694