xref: /petsc/src/snes/interface/snes.c (revision caa4e7f26594b8daaf440f4757330959cfc6cef4)
19b94acceSBarry Smith 
2c6db04a5SJed Brown #include <private/snesimpl.h>      /*I "petscsnes.h"  I*/
36cab3a1bSJed Brown #include <petscdmshell.h>          /*I "petscdmshell.h" I*/
49b94acceSBarry Smith 
5ace3abfcSBarry Smith PetscBool  SNESRegisterAllCalled = PETSC_FALSE;
68ba1e511SMatthew Knepley PetscFList SNESList              = PETSC_NULL;
78ba1e511SMatthew Knepley 
88ba1e511SMatthew Knepley /* Logging support */
97087cfbeSBarry Smith PetscClassId  SNES_CLASSID;
10f1c6b773SPeter Brune PetscLogEvent  SNES_Solve, SNES_FunctionEval, SNES_JacobianEval, SNES_GSEval;
11a09944afSBarry Smith 
12a09944afSBarry Smith #undef __FUNCT__
13cab2e9ccSBarry Smith #define __FUNCT__ "SNESDMComputeJacobian"
14cab2e9ccSBarry Smith /*
15cab2e9ccSBarry Smith     Translates from a SNES call to a DM call in computing a Jacobian
16*caa4e7f2SJed Brown 
17*caa4e7f2SJed Brown     This is a legacy calling sequence, should transition to dispatching through the SNESDM.
18cab2e9ccSBarry Smith */
19cab2e9ccSBarry Smith PetscErrorCode SNESDMComputeJacobian(SNES snes,Vec X,Mat *J,Mat *B,MatStructure *flag,void *ptr)
20cab2e9ccSBarry Smith {
21cab2e9ccSBarry Smith   PetscErrorCode ierr;
22cab2e9ccSBarry Smith   DM             dm;
23cab2e9ccSBarry Smith 
24cab2e9ccSBarry Smith   PetscFunctionBegin;
25cab2e9ccSBarry Smith   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
26cab2e9ccSBarry Smith   ierr = DMComputeJacobian(dm,X,*J,*B,flag);CHKERRQ(ierr);
27cab2e9ccSBarry Smith   PetscFunctionReturn(0);
28cab2e9ccSBarry Smith }
29cab2e9ccSBarry Smith 
30cab2e9ccSBarry Smith #undef __FUNCT__
31e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged"
32e113a28aSBarry Smith /*@
33e113a28aSBarry Smith    SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged.
34e113a28aSBarry Smith 
353f9fe445SBarry Smith    Logically Collective on SNES
36e113a28aSBarry Smith 
37e113a28aSBarry Smith    Input Parameters:
38e113a28aSBarry Smith +  snes - iterative context obtained from SNESCreate()
39e113a28aSBarry Smith -  flg - PETSC_TRUE indicates you want the error generated
40e113a28aSBarry Smith 
41e113a28aSBarry Smith    Options database keys:
42e113a28aSBarry Smith .  -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false)
43e113a28aSBarry Smith 
44e113a28aSBarry Smith    Level: intermediate
45e113a28aSBarry Smith 
46e113a28aSBarry Smith    Notes:
47e113a28aSBarry Smith     Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve()
48e113a28aSBarry Smith     to determine if it has converged.
49e113a28aSBarry Smith 
50e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
51e113a28aSBarry Smith 
52e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
53e113a28aSBarry Smith @*/
547087cfbeSBarry Smith PetscErrorCode  SNESSetErrorIfNotConverged(SNES snes,PetscBool  flg)
55e113a28aSBarry Smith {
56e113a28aSBarry Smith   PetscFunctionBegin;
57e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
58acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flg,2);
59e113a28aSBarry Smith   snes->errorifnotconverged = flg;
60dd568438SSatish Balay 
61e113a28aSBarry Smith   PetscFunctionReturn(0);
62e113a28aSBarry Smith }
63e113a28aSBarry Smith 
64e113a28aSBarry Smith #undef __FUNCT__
65e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged"
66e113a28aSBarry Smith /*@
67e113a28aSBarry Smith    SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge?
68e113a28aSBarry Smith 
69e113a28aSBarry Smith    Not Collective
70e113a28aSBarry Smith 
71e113a28aSBarry Smith    Input Parameter:
72e113a28aSBarry Smith .  snes - iterative context obtained from SNESCreate()
73e113a28aSBarry Smith 
74e113a28aSBarry Smith    Output Parameter:
75e113a28aSBarry Smith .  flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE
76e113a28aSBarry Smith 
77e113a28aSBarry Smith    Level: intermediate
78e113a28aSBarry Smith 
79e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
80e113a28aSBarry Smith 
81e113a28aSBarry Smith .seealso:  SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
82e113a28aSBarry Smith @*/
837087cfbeSBarry Smith PetscErrorCode  SNESGetErrorIfNotConverged(SNES snes,PetscBool  *flag)
84e113a28aSBarry Smith {
85e113a28aSBarry Smith   PetscFunctionBegin;
86e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
87e113a28aSBarry Smith   PetscValidPointer(flag,2);
88e113a28aSBarry Smith   *flag = snes->errorifnotconverged;
89e113a28aSBarry Smith   PetscFunctionReturn(0);
90e113a28aSBarry Smith }
91e113a28aSBarry Smith 
92e113a28aSBarry Smith #undef __FUNCT__
934936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError"
94e725d27bSBarry Smith /*@
954936397dSBarry Smith    SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not
964936397dSBarry Smith      in the functions domain. For example, negative pressure.
974936397dSBarry Smith 
983f9fe445SBarry Smith    Logically Collective on SNES
994936397dSBarry Smith 
1004936397dSBarry Smith    Input Parameters:
1016a388c36SPeter Brune .  snes - the SNES context
1024936397dSBarry Smith 
10328529972SSatish Balay    Level: advanced
1044936397dSBarry Smith 
1054936397dSBarry Smith .keywords: SNES, view
1064936397dSBarry Smith 
1074936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction()
1084936397dSBarry Smith @*/
1097087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionDomainError(SNES snes)
1104936397dSBarry Smith {
1114936397dSBarry Smith   PetscFunctionBegin;
1120700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1134936397dSBarry Smith   snes->domainerror = PETSC_TRUE;
1144936397dSBarry Smith   PetscFunctionReturn(0);
1154936397dSBarry Smith }
1164936397dSBarry Smith 
1176a388c36SPeter Brune 
1186a388c36SPeter Brune #undef __FUNCT__
1196a388c36SPeter Brune #define __FUNCT__ "SNESGetFunctionDomainError"
1206a388c36SPeter Brune /*@
121c77b2880SPeter Brune    SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction;
1226a388c36SPeter Brune 
1236a388c36SPeter Brune    Logically Collective on SNES
1246a388c36SPeter Brune 
1256a388c36SPeter Brune    Input Parameters:
1266a388c36SPeter Brune .  snes - the SNES context
1276a388c36SPeter Brune 
1286a388c36SPeter Brune    Output Parameters:
1296a388c36SPeter Brune .  domainerror Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise.
1306a388c36SPeter Brune 
1316a388c36SPeter Brune    Level: advanced
1326a388c36SPeter Brune 
1336a388c36SPeter Brune .keywords: SNES, view
1346a388c36SPeter Brune 
1356a388c36SPeter Brune .seealso: SNESSetFunctionDomainError, SNESComputeFunction()
1366a388c36SPeter Brune @*/
1376a388c36SPeter Brune PetscErrorCode  SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror)
1386a388c36SPeter Brune {
1396a388c36SPeter Brune   PetscFunctionBegin;
1406a388c36SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1416a388c36SPeter Brune   PetscValidPointer(domainerror, 2);
1426a388c36SPeter Brune   *domainerror = snes->domainerror;
1436a388c36SPeter Brune   PetscFunctionReturn(0);
1446a388c36SPeter Brune }
1456a388c36SPeter Brune 
1466a388c36SPeter Brune 
1474936397dSBarry Smith #undef __FUNCT__
1484a2ae208SSatish Balay #define __FUNCT__ "SNESView"
1497e2c5f70SBarry Smith /*@C
1509b94acceSBarry Smith    SNESView - Prints the SNES data structure.
1519b94acceSBarry Smith 
1524c49b128SBarry Smith    Collective on SNES
153fee21e36SBarry Smith 
154c7afd0dbSLois Curfman McInnes    Input Parameters:
155c7afd0dbSLois Curfman McInnes +  SNES - the SNES context
156c7afd0dbSLois Curfman McInnes -  viewer - visualization context
157c7afd0dbSLois Curfman McInnes 
1589b94acceSBarry Smith    Options Database Key:
159c8a8ba5cSLois Curfman McInnes .  -snes_view - Calls SNESView() at end of SNESSolve()
1609b94acceSBarry Smith 
1619b94acceSBarry Smith    Notes:
1629b94acceSBarry Smith    The available visualization contexts include
163b0a32e0cSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
164b0a32e0cSBarry Smith -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
165c8a8ba5cSLois Curfman McInnes          output where only the first processor opens
166c8a8ba5cSLois Curfman McInnes          the file.  All other processors send their
167c8a8ba5cSLois Curfman McInnes          data to the first processor to print.
1689b94acceSBarry Smith 
1693e081fefSLois Curfman McInnes    The user can open an alternative visualization context with
170b0a32e0cSBarry Smith    PetscViewerASCIIOpen() - output to a specified file.
1719b94acceSBarry Smith 
17236851e7fSLois Curfman McInnes    Level: beginner
17336851e7fSLois Curfman McInnes 
1749b94acceSBarry Smith .keywords: SNES, view
1759b94acceSBarry Smith 
176b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen()
1779b94acceSBarry Smith @*/
1787087cfbeSBarry Smith PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
1799b94acceSBarry Smith {
180fa9f3622SBarry Smith   SNESKSPEW           *kctx;
181dfbe8321SBarry Smith   PetscErrorCode      ierr;
18294b7f48cSBarry Smith   KSP                 ksp;
183ace3abfcSBarry Smith   PetscBool           iascii,isstring;
1849b94acceSBarry Smith 
1853a40ed3dSBarry Smith   PetscFunctionBegin;
1860700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1873050cee2SBarry Smith   if (!viewer) {
1887adad957SLisandro Dalcin     ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
1893050cee2SBarry Smith   }
1900700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
191c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,viewer,2);
19274679c65SBarry Smith 
1932692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1942692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
19532077d6dSBarry Smith   if (iascii) {
196317d6ea6SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr);
197e7788613SBarry Smith     if (snes->ops->view) {
198b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
199e7788613SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
200b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2010ef38995SBarry Smith     }
20277431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr);
203a83599f4SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%G, absolute=%G, solution=%G\n",
20470441072SBarry Smith                  snes->rtol,snes->abstol,snes->xtol);CHKERRQ(ierr);
20577431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr);
20677431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr);
2079b94acceSBarry Smith     if (snes->ksp_ewconv) {
208fa9f3622SBarry Smith       kctx = (SNESKSPEW *)snes->kspconvctx;
2099b94acceSBarry Smith       if (kctx) {
21077431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr);
211a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr);
212a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr);
2139b94acceSBarry Smith       }
2149b94acceSBarry Smith     }
215eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
216eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");CHKERRQ(ierr);
217eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
218eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr);
219eb1f6c34SBarry Smith     }
220eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
221eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");CHKERRQ(ierr);
222eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
22342f4f86dSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr);
224eb1f6c34SBarry Smith     }
2250f5bd95cSBarry Smith   } else if (isstring) {
226317d6ea6SBarry Smith     const char *type;
227454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
228b0a32e0cSBarry Smith     ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr);
22919bcc07fSBarry Smith   }
23042f4f86dSBarry Smith   if (snes->pc && snes->usespc) {
2314a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2324a0c5b0cSMatthew G Knepley     ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr);
2334a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2344a0c5b0cSMatthew G Knepley   }
2352c155ee1SBarry Smith   if (snes->usesksp) {
2362c155ee1SBarry Smith     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
237b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
23894b7f48cSBarry Smith     ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
239b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2402c155ee1SBarry Smith   }
2419e764e56SPeter Brune   ierr = PetscViewerASCIIPrintf(viewer, "  line search variant: %s\n",((PetscObject)snes->linesearch)->type_name);CHKERRQ(ierr);
2423a40ed3dSBarry Smith   PetscFunctionReturn(0);
2439b94acceSBarry Smith }
2449b94acceSBarry Smith 
24576b2cf59SMatthew Knepley /*
24676b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
24776b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
24876b2cf59SMatthew Knepley */
24976b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
250a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
2516849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
25276b2cf59SMatthew Knepley 
253e74ef692SMatthew Knepley #undef __FUNCT__
254e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker"
255ac226902SBarry Smith /*@C
25676b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
25776b2cf59SMatthew Knepley 
25876b2cf59SMatthew Knepley   Not Collective
25976b2cf59SMatthew Knepley 
26076b2cf59SMatthew Knepley   Input Parameter:
26176b2cf59SMatthew Knepley . snescheck - function that checks for options
26276b2cf59SMatthew Knepley 
26376b2cf59SMatthew Knepley   Level: developer
26476b2cf59SMatthew Knepley 
26576b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
26676b2cf59SMatthew Knepley @*/
2677087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
26876b2cf59SMatthew Knepley {
26976b2cf59SMatthew Knepley   PetscFunctionBegin;
27076b2cf59SMatthew Knepley   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
271e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
27276b2cf59SMatthew Knepley   }
27376b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
27476b2cf59SMatthew Knepley   PetscFunctionReturn(0);
27576b2cf59SMatthew Knepley }
27676b2cf59SMatthew Knepley 
2777087cfbeSBarry Smith extern PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
278aa3661deSLisandro Dalcin 
279aa3661deSLisandro Dalcin #undef __FUNCT__
280aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private"
281ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool  hasOperator, PetscInt version)
282aa3661deSLisandro Dalcin {
283aa3661deSLisandro Dalcin   Mat            J;
284aa3661deSLisandro Dalcin   KSP            ksp;
285aa3661deSLisandro Dalcin   PC             pc;
286ace3abfcSBarry Smith   PetscBool      match;
287aa3661deSLisandro Dalcin   PetscErrorCode ierr;
288aa3661deSLisandro Dalcin 
289aa3661deSLisandro Dalcin   PetscFunctionBegin;
2900700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
291aa3661deSLisandro Dalcin 
29298613b67SLisandro Dalcin   if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
29398613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
29498613b67SLisandro Dalcin     ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr);
29598613b67SLisandro Dalcin   }
29698613b67SLisandro Dalcin 
297aa3661deSLisandro Dalcin   if (version == 1) {
298aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
29998613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
3009c6ac3b3SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
301aa3661deSLisandro Dalcin   } else if (version == 2) {
302e32f2f54SBarry Smith     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
30382a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
304aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
305aa3661deSLisandro Dalcin #else
306e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
307aa3661deSLisandro Dalcin #endif
308a8248277SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
309aa3661deSLisandro Dalcin 
310aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
311d3462f78SMatthew Knepley   if (hasOperator) {
312aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
313aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
314aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
315aa3661deSLisandro Dalcin   } else {
316aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
317aa3661deSLisandro Dalcin        provided preconditioner matrix with the default matrix free version. */
3186cab3a1bSJed Brown     void *functx;
3196cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
3206cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
321aa3661deSLisandro Dalcin     /* Force no preconditioner */
322aa3661deSLisandro Dalcin     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
323aa3661deSLisandro Dalcin     ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
324aa3661deSLisandro Dalcin     ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
325aa3661deSLisandro Dalcin     if (!match) {
326aa3661deSLisandro Dalcin       ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
327aa3661deSLisandro Dalcin       ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
328aa3661deSLisandro Dalcin     }
329aa3661deSLisandro Dalcin   }
3306bf464f9SBarry Smith   ierr = MatDestroy(&J);CHKERRQ(ierr);
331aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
332aa3661deSLisandro Dalcin }
333aa3661deSLisandro Dalcin 
3344a2ae208SSatish Balay #undef __FUNCT__
335*caa4e7f2SJed Brown #define __FUNCT__ "KSPComputeOperators_SNES"
336*caa4e7f2SJed Brown static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,MatStructure *mstruct,void *ctx)
337*caa4e7f2SJed Brown {
338*caa4e7f2SJed Brown   SNES snes = (SNES)ctx;
339*caa4e7f2SJed Brown   PetscErrorCode ierr;
340*caa4e7f2SJed Brown   Mat Asave = A,Bsave = B;
341*caa4e7f2SJed Brown 
342*caa4e7f2SJed Brown   PetscFunctionBegin;
343*caa4e7f2SJed Brown   ierr = SNESComputeJacobian(snes,snes->vec_sol,&A,&B,mstruct);CHKERRQ(ierr);
344*caa4e7f2SJed Brown   if (A != Asave || B != Bsave) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_SUP,"No support for changing matrices at this time");
345*caa4e7f2SJed Brown   PetscFunctionReturn(0);
346*caa4e7f2SJed Brown }
347*caa4e7f2SJed Brown 
348*caa4e7f2SJed Brown #undef __FUNCT__
3496cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices"
3506cab3a1bSJed Brown /*@
3516cab3a1bSJed Brown    SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX()
3526cab3a1bSJed Brown 
3536cab3a1bSJed Brown    Collective
3546cab3a1bSJed Brown 
3556cab3a1bSJed Brown    Input Arguments:
3566cab3a1bSJed Brown .  snes - snes to configure
3576cab3a1bSJed Brown 
3586cab3a1bSJed Brown    Level: developer
3596cab3a1bSJed Brown 
3606cab3a1bSJed Brown .seealso: SNESSetUp()
3616cab3a1bSJed Brown @*/
3626cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes)
3636cab3a1bSJed Brown {
3646cab3a1bSJed Brown   PetscErrorCode ierr;
3656cab3a1bSJed Brown   DM             dm;
3666cab3a1bSJed Brown   SNESDM         sdm;
3676cab3a1bSJed Brown 
3686cab3a1bSJed Brown   PetscFunctionBegin;
3696cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3706cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
371*caa4e7f2SJed Brown   if (!sdm->computejacobian) {
3726cab3a1bSJed Brown     Mat J,B;
3736cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
3746cab3a1bSJed Brown     if (snes->mf_operator) {
3756cab3a1bSJed Brown       ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
3766cab3a1bSJed Brown       ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
3776cab3a1bSJed Brown       ierr = MatSetFromOptions(J);CHKERRQ(ierr);
3786cab3a1bSJed Brown     } else {
3796cab3a1bSJed Brown       J = B;
3806cab3a1bSJed Brown       ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
3816cab3a1bSJed Brown     }
3826cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr);
3836cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
3846cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
3856cab3a1bSJed Brown   } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) {
3866cab3a1bSJed Brown     Mat J;
3876cab3a1bSJed Brown     void *functx;
3886cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
3896cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
3906cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
3916cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
3926cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
3936cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
394*caa4e7f2SJed Brown   } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
3956cab3a1bSJed Brown     Mat J,B;
3966cab3a1bSJed Brown     void *functx;
3976cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
3986cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
3996cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4006cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4016cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
4026cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,functx);CHKERRQ(ierr);
4036cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
4046cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
405*caa4e7f2SJed Brown   } else if (!snes->jacobian_pre) {
4066cab3a1bSJed Brown     Mat J,B;
4076cab3a1bSJed Brown     J = snes->jacobian;
4086cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4096cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
4106cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
4116cab3a1bSJed Brown   }
412*caa4e7f2SJed Brown   {
413*caa4e7f2SJed Brown     PetscBool flg = PETSC_FALSE;
414*caa4e7f2SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_kspcompute",&flg,PETSC_NULL);CHKERRQ(ierr);
415*caa4e7f2SJed Brown     if (flg) {                  /* Plan to transition to this model */
416*caa4e7f2SJed Brown       KSP ksp;
417*caa4e7f2SJed Brown       ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
418*caa4e7f2SJed Brown       ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr);
419*caa4e7f2SJed Brown     }
420*caa4e7f2SJed Brown   }
4216cab3a1bSJed Brown   PetscFunctionReturn(0);
4226cab3a1bSJed Brown }
4236cab3a1bSJed Brown 
4246cab3a1bSJed Brown #undef __FUNCT__
4254a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions"
4269b94acceSBarry Smith /*@
42794b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
4289b94acceSBarry Smith 
429c7afd0dbSLois Curfman McInnes    Collective on SNES
430c7afd0dbSLois Curfman McInnes 
4319b94acceSBarry Smith    Input Parameter:
4329b94acceSBarry Smith .  snes - the SNES context
4339b94acceSBarry Smith 
43436851e7fSLois Curfman McInnes    Options Database Keys:
435ea630c6eSPeter Brune +  -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas
43682738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
43782738288SBarry Smith                 of the change in the solution between steps
43870441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
439b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
440b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
441b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
4424839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
443ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
444a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
445e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
446b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
4472492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
44882738288SBarry Smith                                solver; hence iterations will continue until max_it
4491fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
45082738288SBarry Smith                                of convergence test
451e8105e01SRichard Katz .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
452e8105e01SRichard Katz                                        filename given prints to stdout
453a6570f20SBarry Smith .  -snes_monitor_solution - plots solution at each iteration
454a6570f20SBarry Smith .  -snes_monitor_residual - plots residual (not its norm) at each iteration
455a6570f20SBarry Smith .  -snes_monitor_solution_update - plots update to solution at each iteration
456a6570f20SBarry Smith .  -snes_monitor_draw - plots residual norm at each iteration
457e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
4585968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
459fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
46082738288SBarry Smith 
46182738288SBarry Smith     Options Database for Eisenstat-Walker method:
462fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
4634b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
46436851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
46536851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
46636851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
46736851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
46836851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
46936851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
47082738288SBarry Smith 
47111ca99fdSLois Curfman McInnes    Notes:
47211ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
4730598bfebSBarry Smith    the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>.
47483e2fdc7SBarry Smith 
47536851e7fSLois Curfman McInnes    Level: beginner
47636851e7fSLois Curfman McInnes 
4779b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
4789b94acceSBarry Smith 
47969ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
4809b94acceSBarry Smith @*/
4817087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
4829b94acceSBarry Smith {
483872b6db9SPeter Brune   PetscBool               flg,mf,mf_operator,pcset;
484efd51863SBarry Smith   PetscInt                i,indx,lag,mf_version,grids;
485aa3661deSLisandro Dalcin   MatStructure            matflag;
48685385478SLisandro Dalcin   const char              *deft = SNESLS;
48785385478SLisandro Dalcin   const char              *convtests[] = {"default","skip"};
48885385478SLisandro Dalcin   SNESKSPEW               *kctx = NULL;
489e8105e01SRichard Katz   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
49051e86f29SPeter Brune   const char              *optionsprefix;
491649052a6SBarry Smith   PetscViewer             monviewer;
49285385478SLisandro Dalcin   PetscErrorCode          ierr;
4939b94acceSBarry Smith 
4943a40ed3dSBarry Smith   PetscFunctionBegin;
4950700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
496ca161407SBarry Smith 
497186905e3SBarry Smith   if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
4983194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
4997adad957SLisandro Dalcin     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
500b0a32e0cSBarry Smith     ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
501d64ed03dSBarry Smith     if (flg) {
502186905e3SBarry Smith       ierr = SNESSetType(snes,type);CHKERRQ(ierr);
5037adad957SLisandro Dalcin     } else if (!((PetscObject)snes)->type_name) {
504186905e3SBarry Smith       ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
505d64ed03dSBarry Smith     }
50690d69ab7SBarry Smith     /* not used here, but called so will go into help messaage */
507909c8a9fSBarry Smith     ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr);
50893c39befSBarry Smith 
50957034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->xtol,&snes->xtol,0);CHKERRQ(ierr);
51057034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr);
511186905e3SBarry Smith 
51257034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr);
513b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr);
514b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr);
51550ffb88aSMatthew Knepley     ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr);
516ddf469c8SBarry Smith     ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr);
517acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr);
51885385478SLisandro Dalcin 
519a8054027SBarry Smith     ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
520a8054027SBarry Smith     if (flg) {
521a8054027SBarry Smith       ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
522a8054027SBarry Smith     }
523e35cf81dSBarry Smith     ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
524e35cf81dSBarry Smith     if (flg) {
525e35cf81dSBarry Smith       ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
526e35cf81dSBarry Smith     }
527efd51863SBarry Smith     ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
528efd51863SBarry Smith     if (flg) {
529efd51863SBarry Smith       ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
530efd51863SBarry Smith     }
531a8054027SBarry Smith 
53285385478SLisandro Dalcin     ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
53385385478SLisandro Dalcin     if (flg) {
53485385478SLisandro Dalcin       switch (indx) {
5357f7931b9SBarry Smith       case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break;
5367f7931b9SBarry Smith       case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);    break;
53785385478SLisandro Dalcin       }
53885385478SLisandro Dalcin     }
53985385478SLisandro Dalcin 
540acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr);
541186905e3SBarry Smith 
54285385478SLisandro Dalcin     kctx = (SNESKSPEW *)snes->kspconvctx;
54385385478SLisandro Dalcin 
544acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr);
545186905e3SBarry Smith 
546fa9f3622SBarry Smith     ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr);
547fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr);
548fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr);
549fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr);
550fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr);
551fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr);
552fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr);
553186905e3SBarry Smith 
55490d69ab7SBarry Smith     flg  = PETSC_FALSE;
555acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
556a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
557eabae89aSBarry Smith 
558a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
559e8105e01SRichard Katz     if (flg) {
560649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
561649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
562e8105e01SRichard Katz     }
563eabae89aSBarry Smith 
564b271bb04SBarry Smith     ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
565b271bb04SBarry Smith     if (flg) {
566b271bb04SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr);
567b271bb04SBarry Smith     }
568b271bb04SBarry Smith 
569a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
570eabae89aSBarry Smith     if (flg) {
571649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
572f1bef1bcSMatthew Knepley       ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr);
573e8105e01SRichard Katz     }
574eabae89aSBarry Smith 
575a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
576eabae89aSBarry Smith     if (flg) {
577649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
578649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
579eabae89aSBarry Smith     }
580eabae89aSBarry Smith 
5815180491cSLisandro Dalcin     ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
5825180491cSLisandro Dalcin     if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);}
5835180491cSLisandro Dalcin 
58490d69ab7SBarry Smith     flg  = PETSC_FALSE;
585acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
586a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
58790d69ab7SBarry Smith     flg  = PETSC_FALSE;
588acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
589a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
59090d69ab7SBarry Smith     flg  = PETSC_FALSE;
591acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
592a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
59390d69ab7SBarry Smith     flg  = PETSC_FALSE;
594acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
595a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
59690d69ab7SBarry Smith     flg  = PETSC_FALSE;
597acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
598b271bb04SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
599e24b481bSBarry Smith 
60090d69ab7SBarry Smith     flg  = PETSC_FALSE;
601acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
6024b27c08aSLois Curfman McInnes     if (flg) {
6036cab3a1bSJed Brown       void *functx;
6046cab3a1bSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
6056cab3a1bSJed Brown       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr);
606ae15b995SBarry Smith       ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
6079b94acceSBarry Smith     }
608639f9d9dSBarry Smith 
609aa3661deSLisandro Dalcin     mf = mf_operator = PETSC_FALSE;
610aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
611acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr);
612a8248277SBarry Smith     if (flg && mf_operator) {
613a8248277SBarry Smith       snes->mf_operator = PETSC_TRUE;
614a8248277SBarry Smith       mf = PETSC_TRUE;
615a8248277SBarry Smith     }
616aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
617acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr);
618aa3661deSLisandro Dalcin     if (!flg && mf_operator) mf = PETSC_TRUE;
619aa3661deSLisandro Dalcin     mf_version = 1;
620aa3661deSLisandro Dalcin     ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr);
621aa3661deSLisandro Dalcin 
622d28543b3SPeter Brune 
62389b92e6fSPeter Brune     /* GS Options */
62489b92e6fSPeter Brune     ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr);
62589b92e6fSPeter Brune 
62676b2cf59SMatthew Knepley     for(i = 0; i < numberofsetfromoptions; i++) {
62776b2cf59SMatthew Knepley       ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
62876b2cf59SMatthew Knepley     }
62976b2cf59SMatthew Knepley 
630e7788613SBarry Smith     if (snes->ops->setfromoptions) {
631e7788613SBarry Smith       ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr);
632639f9d9dSBarry Smith     }
6335d973c19SBarry Smith 
6345d973c19SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
6355d973c19SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr);
636b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
6374bbc92c1SBarry Smith 
638aa3661deSLisandro Dalcin   if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); }
6391cee3971SBarry Smith 
6401cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
641aa3661deSLisandro Dalcin   ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
642aa3661deSLisandro Dalcin   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr);
64385385478SLisandro Dalcin   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
64493993e2dSLois Curfman McInnes 
6459e764e56SPeter Brune   if (!snes->linesearch) {
646f1c6b773SPeter Brune     ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
6479e764e56SPeter Brune   }
648f1c6b773SPeter Brune   ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr);
6499e764e56SPeter Brune 
65051e86f29SPeter Brune   /* if someone has set the SNES PC type, create it. */
65151e86f29SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
65251e86f29SPeter Brune   ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr);
65351e86f29SPeter Brune   if (pcset && (!snes->pc)) {
65451e86f29SPeter Brune     ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr);
65551e86f29SPeter Brune   }
6564a0c5b0cSMatthew G Knepley   if (snes->pc) {
657fde0ff24SPeter Brune     ierr = SNESSetOptionsPrefix(snes->pc, optionsprefix);CHKERRQ(ierr);
658fde0ff24SPeter Brune     ierr = SNESAppendOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr);
6594a0c5b0cSMatthew G Knepley     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
6604a0c5b0cSMatthew G Knepley     ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr);
6614a0c5b0cSMatthew G Knepley   }
6623a40ed3dSBarry Smith   PetscFunctionReturn(0);
6639b94acceSBarry Smith }
6649b94acceSBarry Smith 
665d25893d9SBarry Smith #undef __FUNCT__
666d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext"
667d25893d9SBarry Smith /*@
668d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
669d25893d9SBarry Smith    the nonlinear solvers.
670d25893d9SBarry Smith 
671d25893d9SBarry Smith    Logically Collective on SNES
672d25893d9SBarry Smith 
673d25893d9SBarry Smith    Input Parameters:
674d25893d9SBarry Smith +  snes - the SNES context
675d25893d9SBarry Smith .  compute - function to compute the context
676d25893d9SBarry Smith -  destroy - function to destroy the context
677d25893d9SBarry Smith 
678d25893d9SBarry Smith    Level: intermediate
679d25893d9SBarry Smith 
680d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
681d25893d9SBarry Smith 
682d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
683d25893d9SBarry Smith @*/
684d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
685d25893d9SBarry Smith {
686d25893d9SBarry Smith   PetscFunctionBegin;
687d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
688d25893d9SBarry Smith   snes->ops->usercompute = compute;
689d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
690d25893d9SBarry Smith   PetscFunctionReturn(0);
691d25893d9SBarry Smith }
692a847f771SSatish Balay 
6934a2ae208SSatish Balay #undef __FUNCT__
6944a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
695b07ff414SBarry Smith /*@
6969b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
6979b94acceSBarry Smith    the nonlinear solvers.
6989b94acceSBarry Smith 
6993f9fe445SBarry Smith    Logically Collective on SNES
700fee21e36SBarry Smith 
701c7afd0dbSLois Curfman McInnes    Input Parameters:
702c7afd0dbSLois Curfman McInnes +  snes - the SNES context
703c7afd0dbSLois Curfman McInnes -  usrP - optional user context
704c7afd0dbSLois Curfman McInnes 
70536851e7fSLois Curfman McInnes    Level: intermediate
70636851e7fSLois Curfman McInnes 
7079b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
7089b94acceSBarry Smith 
709d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext()
7109b94acceSBarry Smith @*/
7117087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
7129b94acceSBarry Smith {
7131b2093e4SBarry Smith   PetscErrorCode ierr;
714b07ff414SBarry Smith   KSP            ksp;
7151b2093e4SBarry Smith 
7163a40ed3dSBarry Smith   PetscFunctionBegin;
7170700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
718b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
719b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
7209b94acceSBarry Smith   snes->user = usrP;
7213a40ed3dSBarry Smith   PetscFunctionReturn(0);
7229b94acceSBarry Smith }
72374679c65SBarry Smith 
7244a2ae208SSatish Balay #undef __FUNCT__
7254a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
726b07ff414SBarry Smith /*@
7279b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
7289b94acceSBarry Smith    nonlinear solvers.
7299b94acceSBarry Smith 
730c7afd0dbSLois Curfman McInnes    Not Collective
731c7afd0dbSLois Curfman McInnes 
7329b94acceSBarry Smith    Input Parameter:
7339b94acceSBarry Smith .  snes - SNES context
7349b94acceSBarry Smith 
7359b94acceSBarry Smith    Output Parameter:
7369b94acceSBarry Smith .  usrP - user context
7379b94acceSBarry Smith 
73836851e7fSLois Curfman McInnes    Level: intermediate
73936851e7fSLois Curfman McInnes 
7409b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
7419b94acceSBarry Smith 
7429b94acceSBarry Smith .seealso: SNESSetApplicationContext()
7439b94acceSBarry Smith @*/
744e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
7459b94acceSBarry Smith {
7463a40ed3dSBarry Smith   PetscFunctionBegin;
7470700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
748e71120c6SJed Brown   *(void**)usrP = snes->user;
7493a40ed3dSBarry Smith   PetscFunctionReturn(0);
7509b94acceSBarry Smith }
75174679c65SBarry Smith 
7524a2ae208SSatish Balay #undef __FUNCT__
7534a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
7549b94acceSBarry Smith /*@
755c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
756c8228a4eSBarry Smith    at this time.
7579b94acceSBarry Smith 
758c7afd0dbSLois Curfman McInnes    Not Collective
759c7afd0dbSLois Curfman McInnes 
7609b94acceSBarry Smith    Input Parameter:
7619b94acceSBarry Smith .  snes - SNES context
7629b94acceSBarry Smith 
7639b94acceSBarry Smith    Output Parameter:
7649b94acceSBarry Smith .  iter - iteration number
7659b94acceSBarry Smith 
766c8228a4eSBarry Smith    Notes:
767c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
768c8228a4eSBarry Smith 
769c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
77008405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
77108405cd6SLois Curfman McInnes .vb
77208405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
77308405cd6SLois Curfman McInnes       if (!(it % 2)) {
77408405cd6SLois Curfman McInnes         [compute Jacobian here]
77508405cd6SLois Curfman McInnes       }
77608405cd6SLois Curfman McInnes .ve
777c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
77808405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
779c8228a4eSBarry Smith 
78036851e7fSLois Curfman McInnes    Level: intermediate
78136851e7fSLois Curfman McInnes 
7822b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
7832b668275SBarry Smith 
784b850b91aSLisandro Dalcin .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
7859b94acceSBarry Smith @*/
7867087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
7879b94acceSBarry Smith {
7883a40ed3dSBarry Smith   PetscFunctionBegin;
7890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7904482741eSBarry Smith   PetscValidIntPointer(iter,2);
7919b94acceSBarry Smith   *iter = snes->iter;
7923a40ed3dSBarry Smith   PetscFunctionReturn(0);
7939b94acceSBarry Smith }
79474679c65SBarry Smith 
7954a2ae208SSatish Balay #undef __FUNCT__
796360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber"
797360c497dSPeter Brune /*@
798360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
799360c497dSPeter Brune 
800360c497dSPeter Brune    Not Collective
801360c497dSPeter Brune 
802360c497dSPeter Brune    Input Parameter:
803360c497dSPeter Brune .  snes - SNES context
804360c497dSPeter Brune .  iter - iteration number
805360c497dSPeter Brune 
806360c497dSPeter Brune    Level: developer
807360c497dSPeter Brune 
808360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number,
809360c497dSPeter Brune 
810360c497dSPeter Brune .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
811360c497dSPeter Brune @*/
812360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
813360c497dSPeter Brune {
814360c497dSPeter Brune   PetscErrorCode ierr;
815360c497dSPeter Brune 
816360c497dSPeter Brune   PetscFunctionBegin;
817360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
818360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
819360c497dSPeter Brune   snes->iter = iter;
820360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
821360c497dSPeter Brune   PetscFunctionReturn(0);
822360c497dSPeter Brune }
823360c497dSPeter Brune 
824360c497dSPeter Brune #undef __FUNCT__
8254a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm"
8269b94acceSBarry Smith /*@
8279b94acceSBarry Smith    SNESGetFunctionNorm - Gets the norm of the current function that was set
8289b94acceSBarry Smith    with SNESSSetFunction().
8299b94acceSBarry Smith 
830c7afd0dbSLois Curfman McInnes    Collective on SNES
831c7afd0dbSLois Curfman McInnes 
8329b94acceSBarry Smith    Input Parameter:
8339b94acceSBarry Smith .  snes - SNES context
8349b94acceSBarry Smith 
8359b94acceSBarry Smith    Output Parameter:
8369b94acceSBarry Smith .  fnorm - 2-norm of function
8379b94acceSBarry Smith 
83836851e7fSLois Curfman McInnes    Level: intermediate
83936851e7fSLois Curfman McInnes 
8409b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm
841a86d99e1SLois Curfman McInnes 
842b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
8439b94acceSBarry Smith @*/
8447087cfbeSBarry Smith PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
8459b94acceSBarry Smith {
8463a40ed3dSBarry Smith   PetscFunctionBegin;
8470700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8484482741eSBarry Smith   PetscValidScalarPointer(fnorm,2);
8499b94acceSBarry Smith   *fnorm = snes->norm;
8503a40ed3dSBarry Smith   PetscFunctionReturn(0);
8519b94acceSBarry Smith }
85274679c65SBarry Smith 
853360c497dSPeter Brune 
854360c497dSPeter Brune #undef __FUNCT__
855360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm"
856360c497dSPeter Brune /*@
857360c497dSPeter Brune    SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm().
858360c497dSPeter Brune 
859360c497dSPeter Brune    Collective on SNES
860360c497dSPeter Brune 
861360c497dSPeter Brune    Input Parameter:
862360c497dSPeter Brune .  snes - SNES context
863360c497dSPeter Brune .  fnorm - 2-norm of function
864360c497dSPeter Brune 
865360c497dSPeter Brune    Level: developer
866360c497dSPeter Brune 
867360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm
868360c497dSPeter Brune 
869360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm().
870360c497dSPeter Brune @*/
871360c497dSPeter Brune PetscErrorCode  SNESSetFunctionNorm(SNES snes,PetscReal fnorm)
872360c497dSPeter Brune {
873360c497dSPeter Brune 
874360c497dSPeter Brune   PetscErrorCode ierr;
875360c497dSPeter Brune 
876360c497dSPeter Brune   PetscFunctionBegin;
877360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
878360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
879360c497dSPeter Brune   snes->norm = fnorm;
880360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
881360c497dSPeter Brune   PetscFunctionReturn(0);
882360c497dSPeter Brune }
883360c497dSPeter Brune 
8844a2ae208SSatish Balay #undef __FUNCT__
885b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
8869b94acceSBarry Smith /*@
887b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
8889b94acceSBarry Smith    attempted by the nonlinear solver.
8899b94acceSBarry Smith 
890c7afd0dbSLois Curfman McInnes    Not Collective
891c7afd0dbSLois Curfman McInnes 
8929b94acceSBarry Smith    Input Parameter:
8939b94acceSBarry Smith .  snes - SNES context
8949b94acceSBarry Smith 
8959b94acceSBarry Smith    Output Parameter:
8969b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
8979b94acceSBarry Smith 
898c96a6f78SLois Curfman McInnes    Notes:
899c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
900c96a6f78SLois Curfman McInnes 
90136851e7fSLois Curfman McInnes    Level: intermediate
90236851e7fSLois Curfman McInnes 
9039b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
90458ebbce7SBarry Smith 
905e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
90658ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
9079b94acceSBarry Smith @*/
9087087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
9099b94acceSBarry Smith {
9103a40ed3dSBarry Smith   PetscFunctionBegin;
9110700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9124482741eSBarry Smith   PetscValidIntPointer(nfails,2);
91350ffb88aSMatthew Knepley   *nfails = snes->numFailures;
91450ffb88aSMatthew Knepley   PetscFunctionReturn(0);
91550ffb88aSMatthew Knepley }
91650ffb88aSMatthew Knepley 
91750ffb88aSMatthew Knepley #undef __FUNCT__
918b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
91950ffb88aSMatthew Knepley /*@
920b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
92150ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
92250ffb88aSMatthew Knepley 
92350ffb88aSMatthew Knepley    Not Collective
92450ffb88aSMatthew Knepley 
92550ffb88aSMatthew Knepley    Input Parameters:
92650ffb88aSMatthew Knepley +  snes     - SNES context
92750ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
92850ffb88aSMatthew Knepley 
92950ffb88aSMatthew Knepley    Level: intermediate
93050ffb88aSMatthew Knepley 
93150ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
93258ebbce7SBarry Smith 
933e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
93458ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
93550ffb88aSMatthew Knepley @*/
9367087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
93750ffb88aSMatthew Knepley {
93850ffb88aSMatthew Knepley   PetscFunctionBegin;
9390700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
94050ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
94150ffb88aSMatthew Knepley   PetscFunctionReturn(0);
94250ffb88aSMatthew Knepley }
94350ffb88aSMatthew Knepley 
94450ffb88aSMatthew Knepley #undef __FUNCT__
945b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
94650ffb88aSMatthew Knepley /*@
947b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
94850ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
94950ffb88aSMatthew Knepley 
95050ffb88aSMatthew Knepley    Not Collective
95150ffb88aSMatthew Knepley 
95250ffb88aSMatthew Knepley    Input Parameter:
95350ffb88aSMatthew Knepley .  snes     - SNES context
95450ffb88aSMatthew Knepley 
95550ffb88aSMatthew Knepley    Output Parameter:
95650ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
95750ffb88aSMatthew Knepley 
95850ffb88aSMatthew Knepley    Level: intermediate
95950ffb88aSMatthew Knepley 
96050ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
96158ebbce7SBarry Smith 
962e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
96358ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
96458ebbce7SBarry Smith 
96550ffb88aSMatthew Knepley @*/
9667087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
96750ffb88aSMatthew Knepley {
96850ffb88aSMatthew Knepley   PetscFunctionBegin;
9690700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9704482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
97150ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
9723a40ed3dSBarry Smith   PetscFunctionReturn(0);
9739b94acceSBarry Smith }
974a847f771SSatish Balay 
9754a2ae208SSatish Balay #undef __FUNCT__
9762541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
9772541af92SBarry Smith /*@
9782541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
9792541af92SBarry Smith      done by SNES.
9802541af92SBarry Smith 
9812541af92SBarry Smith    Not Collective
9822541af92SBarry Smith 
9832541af92SBarry Smith    Input Parameter:
9842541af92SBarry Smith .  snes     - SNES context
9852541af92SBarry Smith 
9862541af92SBarry Smith    Output Parameter:
9872541af92SBarry Smith .  nfuncs - number of evaluations
9882541af92SBarry Smith 
9892541af92SBarry Smith    Level: intermediate
9902541af92SBarry Smith 
9912541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
99258ebbce7SBarry Smith 
993e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
9942541af92SBarry Smith @*/
9957087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
9962541af92SBarry Smith {
9972541af92SBarry Smith   PetscFunctionBegin;
9980700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9992541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
10002541af92SBarry Smith   *nfuncs = snes->nfuncs;
10012541af92SBarry Smith   PetscFunctionReturn(0);
10022541af92SBarry Smith }
10032541af92SBarry Smith 
10042541af92SBarry Smith #undef __FUNCT__
10053d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
10063d4c4710SBarry Smith /*@
10073d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
10083d4c4710SBarry Smith    linear solvers.
10093d4c4710SBarry Smith 
10103d4c4710SBarry Smith    Not Collective
10113d4c4710SBarry Smith 
10123d4c4710SBarry Smith    Input Parameter:
10133d4c4710SBarry Smith .  snes - SNES context
10143d4c4710SBarry Smith 
10153d4c4710SBarry Smith    Output Parameter:
10163d4c4710SBarry Smith .  nfails - number of failed solves
10173d4c4710SBarry Smith 
10183d4c4710SBarry Smith    Notes:
10193d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
10203d4c4710SBarry Smith 
10213d4c4710SBarry Smith    Level: intermediate
10223d4c4710SBarry Smith 
10233d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
102458ebbce7SBarry Smith 
1025e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
10263d4c4710SBarry Smith @*/
10277087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
10283d4c4710SBarry Smith {
10293d4c4710SBarry Smith   PetscFunctionBegin;
10300700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10313d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
10323d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
10333d4c4710SBarry Smith   PetscFunctionReturn(0);
10343d4c4710SBarry Smith }
10353d4c4710SBarry Smith 
10363d4c4710SBarry Smith #undef __FUNCT__
10373d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
10383d4c4710SBarry Smith /*@
10393d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
10403d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
10413d4c4710SBarry Smith 
10423f9fe445SBarry Smith    Logically Collective on SNES
10433d4c4710SBarry Smith 
10443d4c4710SBarry Smith    Input Parameters:
10453d4c4710SBarry Smith +  snes     - SNES context
10463d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
10473d4c4710SBarry Smith 
10483d4c4710SBarry Smith    Level: intermediate
10493d4c4710SBarry Smith 
1050a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
10513d4c4710SBarry Smith 
10523d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
10533d4c4710SBarry Smith 
105458ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
10553d4c4710SBarry Smith @*/
10567087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
10573d4c4710SBarry Smith {
10583d4c4710SBarry Smith   PetscFunctionBegin;
10590700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1060c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
10613d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
10623d4c4710SBarry Smith   PetscFunctionReturn(0);
10633d4c4710SBarry Smith }
10643d4c4710SBarry Smith 
10653d4c4710SBarry Smith #undef __FUNCT__
10663d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
10673d4c4710SBarry Smith /*@
10683d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
10693d4c4710SBarry Smith      are allowed before SNES terminates
10703d4c4710SBarry Smith 
10713d4c4710SBarry Smith    Not Collective
10723d4c4710SBarry Smith 
10733d4c4710SBarry Smith    Input Parameter:
10743d4c4710SBarry Smith .  snes     - SNES context
10753d4c4710SBarry Smith 
10763d4c4710SBarry Smith    Output Parameter:
10773d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
10783d4c4710SBarry Smith 
10793d4c4710SBarry Smith    Level: intermediate
10803d4c4710SBarry Smith 
10813d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
10823d4c4710SBarry Smith 
10833d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
10843d4c4710SBarry Smith 
1085e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
10863d4c4710SBarry Smith @*/
10877087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
10883d4c4710SBarry Smith {
10893d4c4710SBarry Smith   PetscFunctionBegin;
10900700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10913d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
10923d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
10933d4c4710SBarry Smith   PetscFunctionReturn(0);
10943d4c4710SBarry Smith }
10953d4c4710SBarry Smith 
10963d4c4710SBarry Smith #undef __FUNCT__
1097b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
1098c96a6f78SLois Curfman McInnes /*@
1099b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1100c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1101c96a6f78SLois Curfman McInnes 
1102c7afd0dbSLois Curfman McInnes    Not Collective
1103c7afd0dbSLois Curfman McInnes 
1104c96a6f78SLois Curfman McInnes    Input Parameter:
1105c96a6f78SLois Curfman McInnes .  snes - SNES context
1106c96a6f78SLois Curfman McInnes 
1107c96a6f78SLois Curfman McInnes    Output Parameter:
1108c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1109c96a6f78SLois Curfman McInnes 
1110c96a6f78SLois Curfman McInnes    Notes:
1111c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1112c96a6f78SLois Curfman McInnes 
111336851e7fSLois Curfman McInnes    Level: intermediate
111436851e7fSLois Curfman McInnes 
1115c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
11162b668275SBarry Smith 
11178c7482ecSBarry Smith .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
1118c96a6f78SLois Curfman McInnes @*/
11197087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
1120c96a6f78SLois Curfman McInnes {
11213a40ed3dSBarry Smith   PetscFunctionBegin;
11220700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11234482741eSBarry Smith   PetscValidIntPointer(lits,2);
1124c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
11253a40ed3dSBarry Smith   PetscFunctionReturn(0);
1126c96a6f78SLois Curfman McInnes }
1127c96a6f78SLois Curfman McInnes 
11284a2ae208SSatish Balay #undef __FUNCT__
112994b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP"
113052baeb72SSatish Balay /*@
113194b7f48cSBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
11329b94acceSBarry Smith 
113394b7f48cSBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
1134c7afd0dbSLois Curfman McInnes 
11359b94acceSBarry Smith    Input Parameter:
11369b94acceSBarry Smith .  snes - the SNES context
11379b94acceSBarry Smith 
11389b94acceSBarry Smith    Output Parameter:
113994b7f48cSBarry Smith .  ksp - the KSP context
11409b94acceSBarry Smith 
11419b94acceSBarry Smith    Notes:
114294b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
11439b94acceSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
11442999313aSBarry Smith    PC contexts as well.
11459b94acceSBarry Smith 
114636851e7fSLois Curfman McInnes    Level: beginner
114736851e7fSLois Curfman McInnes 
114894b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
11499b94acceSBarry Smith 
11502999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
11519b94acceSBarry Smith @*/
11527087cfbeSBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
11539b94acceSBarry Smith {
11541cee3971SBarry Smith   PetscErrorCode ierr;
11551cee3971SBarry Smith 
11563a40ed3dSBarry Smith   PetscFunctionBegin;
11570700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11584482741eSBarry Smith   PetscValidPointer(ksp,2);
11591cee3971SBarry Smith 
11601cee3971SBarry Smith   if (!snes->ksp) {
11611cee3971SBarry Smith     ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr);
11621cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
11631cee3971SBarry Smith     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
11641cee3971SBarry Smith   }
116594b7f48cSBarry Smith   *ksp = snes->ksp;
11663a40ed3dSBarry Smith   PetscFunctionReturn(0);
11679b94acceSBarry Smith }
116882bf6240SBarry Smith 
11694a2ae208SSatish Balay #undef __FUNCT__
11702999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
11712999313aSBarry Smith /*@
11722999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
11732999313aSBarry Smith 
11742999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
11752999313aSBarry Smith 
11762999313aSBarry Smith    Input Parameters:
11772999313aSBarry Smith +  snes - the SNES context
11782999313aSBarry Smith -  ksp - the KSP context
11792999313aSBarry Smith 
11802999313aSBarry Smith    Notes:
11812999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
11822999313aSBarry Smith    so this routine is rarely needed.
11832999313aSBarry Smith 
11842999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
11852999313aSBarry Smith    decreased by one.
11862999313aSBarry Smith 
11872999313aSBarry Smith    Level: developer
11882999313aSBarry Smith 
11892999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
11902999313aSBarry Smith 
11912999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
11922999313aSBarry Smith @*/
11937087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
11942999313aSBarry Smith {
11952999313aSBarry Smith   PetscErrorCode ierr;
11962999313aSBarry Smith 
11972999313aSBarry Smith   PetscFunctionBegin;
11980700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11990700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
12002999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
12017dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1202906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
12032999313aSBarry Smith   snes->ksp = ksp;
12042999313aSBarry Smith   PetscFunctionReturn(0);
12052999313aSBarry Smith }
12062999313aSBarry Smith 
12077adad957SLisandro Dalcin #if 0
12082999313aSBarry Smith #undef __FUNCT__
12094a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc"
12106849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
1211e24b481bSBarry Smith {
1212e24b481bSBarry Smith   PetscFunctionBegin;
1213e24b481bSBarry Smith   PetscFunctionReturn(0);
1214e24b481bSBarry Smith }
12157adad957SLisandro Dalcin #endif
1216e24b481bSBarry Smith 
12179b94acceSBarry Smith /* -----------------------------------------------------------*/
12184a2ae208SSatish Balay #undef __FUNCT__
12194a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
122052baeb72SSatish Balay /*@
12219b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
12229b94acceSBarry Smith 
1223c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1224c7afd0dbSLois Curfman McInnes 
1225c7afd0dbSLois Curfman McInnes    Input Parameters:
1226906ed7ccSBarry Smith .  comm - MPI communicator
12279b94acceSBarry Smith 
12289b94acceSBarry Smith    Output Parameter:
12299b94acceSBarry Smith .  outsnes - the new SNES context
12309b94acceSBarry Smith 
1231c7afd0dbSLois Curfman McInnes    Options Database Keys:
1232c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1233c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1234c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1235c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1236c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1237c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1238c1f60f51SBarry Smith 
123936851e7fSLois Curfman McInnes    Level: beginner
124036851e7fSLois Curfman McInnes 
12419b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
12429b94acceSBarry Smith 
1243a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1244a8054027SBarry Smith 
12459b94acceSBarry Smith @*/
12467087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
12479b94acceSBarry Smith {
1248dfbe8321SBarry Smith   PetscErrorCode      ierr;
12499b94acceSBarry Smith   SNES                snes;
1250fa9f3622SBarry Smith   SNESKSPEW           *kctx;
125137fcc0dbSBarry Smith 
12523a40ed3dSBarry Smith   PetscFunctionBegin;
1253ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
12548ba1e511SMatthew Knepley   *outsnes = PETSC_NULL;
12558ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
12568ba1e511SMatthew Knepley   ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr);
12578ba1e511SMatthew Knepley #endif
12588ba1e511SMatthew Knepley 
12593194b578SJed Brown   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
12607adad957SLisandro Dalcin 
126185385478SLisandro Dalcin   snes->ops->converged    = SNESDefaultConverged;
12622c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
12639b94acceSBarry Smith   snes->max_its           = 50;
12649750a799SBarry Smith   snes->max_funcs	  = 10000;
12659b94acceSBarry Smith   snes->norm		  = 0.0;
1266b4874afaSBarry Smith   snes->rtol		  = 1.e-8;
1267b4874afaSBarry Smith   snes->ttol              = 0.0;
126870441072SBarry Smith   snes->abstol		  = 1.e-50;
12699b94acceSBarry Smith   snes->xtol		  = 1.e-8;
12704b27c08aSLois Curfman McInnes   snes->deltatol	  = 1.e-12;
12719b94acceSBarry Smith   snes->nfuncs            = 0;
127250ffb88aSMatthew Knepley   snes->numFailures       = 0;
127350ffb88aSMatthew Knepley   snes->maxFailures       = 1;
12747a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1275e35cf81dSBarry Smith   snes->lagjacobian       = 1;
1276a8054027SBarry Smith   snes->lagpreconditioner = 1;
1277639f9d9dSBarry Smith   snes->numbermonitors    = 0;
12789b94acceSBarry Smith   snes->data              = 0;
12794dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1280186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
12816f24a144SLois Curfman McInnes   snes->nwork             = 0;
128258c9b817SLisandro Dalcin   snes->work              = 0;
128358c9b817SLisandro Dalcin   snes->nvwork            = 0;
128458c9b817SLisandro Dalcin   snes->vwork             = 0;
1285758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1286758f92a0SBarry Smith   snes->conv_hist_max     = 0;
1287758f92a0SBarry Smith   snes->conv_hist         = PETSC_NULL;
1288758f92a0SBarry Smith   snes->conv_hist_its     = PETSC_NULL;
1289758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1290184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
129189b92e6fSPeter Brune   snes->gssweeps          = 1;
12929b94acceSBarry Smith 
12933d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
12943d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
12953d4c4710SBarry Smith 
12969b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
129738f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr);
12989b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
12999b94acceSBarry Smith   kctx->version     = 2;
13009b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
13019b94acceSBarry Smith                              this was too large for some test cases */
130275567043SBarry Smith   kctx->rtol_last   = 0.0;
13039b94acceSBarry Smith   kctx->rtol_max    = .9;
13049b94acceSBarry Smith   kctx->gamma       = 1.0;
130562d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
130671f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
13079b94acceSBarry Smith   kctx->threshold   = .1;
130875567043SBarry Smith   kctx->lresid_last = 0.0;
130975567043SBarry Smith   kctx->norm_last   = 0.0;
13109b94acceSBarry Smith 
13119b94acceSBarry Smith   *outsnes = snes;
13123a40ed3dSBarry Smith   PetscFunctionReturn(0);
13139b94acceSBarry Smith }
13149b94acceSBarry Smith 
13154a2ae208SSatish Balay #undef __FUNCT__
13164a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
13179b94acceSBarry Smith /*@C
13189b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
13199b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
13209b94acceSBarry Smith    equations.
13219b94acceSBarry Smith 
13223f9fe445SBarry Smith    Logically Collective on SNES
1323fee21e36SBarry Smith 
1324c7afd0dbSLois Curfman McInnes    Input Parameters:
1325c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1326c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1327de044059SHong Zhang .  func - function evaluation routine
1328c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1329c7afd0dbSLois Curfman McInnes          function evaluation routine (may be PETSC_NULL)
13309b94acceSBarry Smith 
1331c7afd0dbSLois Curfman McInnes    Calling sequence of func:
13328d76a1e5SLois Curfman McInnes $    func (SNES snes,Vec x,Vec f,void *ctx);
1333c7afd0dbSLois Curfman McInnes 
1334c586c404SJed Brown +  snes - the SNES context
1335c586c404SJed Brown .  x - state at which to evaluate residual
1336c586c404SJed Brown .  f - vector to put residual
1337c7afd0dbSLois Curfman McInnes -  ctx - optional user-defined function context
13389b94acceSBarry Smith 
13399b94acceSBarry Smith    Notes:
13409b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
13419b94acceSBarry Smith $      f'(x) x = -f(x),
1342c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
13439b94acceSBarry Smith 
134436851e7fSLois Curfman McInnes    Level: beginner
134536851e7fSLois Curfman McInnes 
13469b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
13479b94acceSBarry Smith 
13488b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard()
13499b94acceSBarry Smith @*/
13507087cfbeSBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
13519b94acceSBarry Smith {
135285385478SLisandro Dalcin   PetscErrorCode ierr;
13536cab3a1bSJed Brown   DM             dm;
13546cab3a1bSJed Brown 
13553a40ed3dSBarry Smith   PetscFunctionBegin;
13560700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1357d2a683ecSLisandro Dalcin   if (r) {
1358d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1359d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
136085385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
13616bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
136285385478SLisandro Dalcin     snes->vec_func = r;
1363d2a683ecSLisandro Dalcin   }
13646cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
13656cab3a1bSJed Brown   ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr);
13663a40ed3dSBarry Smith   PetscFunctionReturn(0);
13679b94acceSBarry Smith }
13689b94acceSBarry Smith 
1369646217ecSPeter Brune 
1370646217ecSPeter Brune #undef __FUNCT__
1371646217ecSPeter Brune #define __FUNCT__ "SNESSetGS"
1372c79ef259SPeter Brune /*@C
1373c79ef259SPeter Brune    SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for
1374c79ef259SPeter Brune    use with composed nonlinear solvers.
1375c79ef259SPeter Brune 
1376c79ef259SPeter Brune    Input Parameters:
1377c79ef259SPeter Brune +  snes   - the SNES context
1378c79ef259SPeter Brune .  gsfunc - function evaluation routine
1379c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
1380c79ef259SPeter Brune             smoother evaluation routine (may be PETSC_NULL)
1381c79ef259SPeter Brune 
1382c79ef259SPeter Brune    Calling sequence of func:
1383c79ef259SPeter Brune $    func (SNES snes,Vec x,Vec b,void *ctx);
1384c79ef259SPeter Brune 
1385c79ef259SPeter Brune +  X   - solution vector
1386c79ef259SPeter Brune .  B   - RHS vector
1387d28543b3SPeter Brune -  ctx - optional user-defined Gauss-Seidel context
1388c79ef259SPeter Brune 
1389c79ef259SPeter Brune    Notes:
1390c79ef259SPeter Brune    The GS routines are used by the composed nonlinear solver to generate
1391c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
1392c79ef259SPeter Brune 
1393d28543b3SPeter Brune    Level: intermediate
1394c79ef259SPeter Brune 
1395d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel
1396c79ef259SPeter Brune 
1397c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS()
1398c79ef259SPeter Brune @*/
13996cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx)
14006cab3a1bSJed Brown {
14016cab3a1bSJed Brown   PetscErrorCode ierr;
14026cab3a1bSJed Brown   DM dm;
14036cab3a1bSJed Brown 
1404646217ecSPeter Brune   PetscFunctionBegin;
14056cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
14066cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
14076cab3a1bSJed Brown   ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr);
1408646217ecSPeter Brune   PetscFunctionReturn(0);
1409646217ecSPeter Brune }
1410646217ecSPeter Brune 
1411d25893d9SBarry Smith #undef __FUNCT__
141289b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps"
141389b92e6fSPeter Brune /*@
141489b92e6fSPeter Brune    SNESSetGSSweeps - Sets the number of sweeps of GS to use.
141589b92e6fSPeter Brune 
141689b92e6fSPeter Brune    Input Parameters:
141789b92e6fSPeter Brune +  snes   - the SNES context
141889b92e6fSPeter Brune -  sweeps  - the number of sweeps of GS to perform.
141989b92e6fSPeter Brune 
142089b92e6fSPeter Brune    Level: intermediate
142189b92e6fSPeter Brune 
142289b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
142389b92e6fSPeter Brune 
142489b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps()
142589b92e6fSPeter Brune @*/
142689b92e6fSPeter Brune 
142789b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) {
142889b92e6fSPeter Brune   PetscFunctionBegin;
142989b92e6fSPeter Brune   snes->gssweeps = sweeps;
143089b92e6fSPeter Brune   PetscFunctionReturn(0);
143189b92e6fSPeter Brune }
143289b92e6fSPeter Brune 
143389b92e6fSPeter Brune 
143489b92e6fSPeter Brune #undef __FUNCT__
143589b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps"
143689b92e6fSPeter Brune /*@
143789b92e6fSPeter Brune    SNESGetGSSweeps - Gets the number of sweeps GS will use.
143889b92e6fSPeter Brune 
143989b92e6fSPeter Brune    Input Parameters:
144089b92e6fSPeter Brune .  snes   - the SNES context
144189b92e6fSPeter Brune 
144289b92e6fSPeter Brune    Output Parameters:
144389b92e6fSPeter Brune .  sweeps  - the number of sweeps of GS to perform.
144489b92e6fSPeter Brune 
144589b92e6fSPeter Brune    Level: intermediate
144689b92e6fSPeter Brune 
144789b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
144889b92e6fSPeter Brune 
144989b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps()
145089b92e6fSPeter Brune @*/
145189b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) {
145289b92e6fSPeter Brune   PetscFunctionBegin;
145389b92e6fSPeter Brune   *sweeps = snes->gssweeps;
145489b92e6fSPeter Brune   PetscFunctionReturn(0);
145589b92e6fSPeter Brune }
145689b92e6fSPeter Brune 
145789b92e6fSPeter Brune #undef __FUNCT__
14588b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction"
14598b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
14608b0a5094SBarry Smith {
14618b0a5094SBarry Smith   PetscErrorCode ierr;
14626cab3a1bSJed Brown   void *functx,*jacctx;
14636cab3a1bSJed Brown 
14648b0a5094SBarry Smith   PetscFunctionBegin;
14656cab3a1bSJed Brown   ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
14666cab3a1bSJed Brown   ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr);
14678b0a5094SBarry Smith   /*  A(x)*x - b(x) */
14686cab3a1bSJed Brown   ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr);
14696cab3a1bSJed Brown   ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr);
14708b0a5094SBarry Smith   ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
14718b0a5094SBarry Smith   ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
14728b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
14738b0a5094SBarry Smith   ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr);
14748b0a5094SBarry Smith   PetscFunctionReturn(0);
14758b0a5094SBarry Smith }
14768b0a5094SBarry Smith 
14778b0a5094SBarry Smith #undef __FUNCT__
14788b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian"
14798b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
14808b0a5094SBarry Smith {
14818b0a5094SBarry Smith   PetscFunctionBegin;
14828b0a5094SBarry Smith   *flag = snes->matstruct;
14838b0a5094SBarry Smith   PetscFunctionReturn(0);
14848b0a5094SBarry Smith }
14858b0a5094SBarry Smith 
14868b0a5094SBarry Smith #undef __FUNCT__
14878b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard"
14888b0a5094SBarry Smith /*@C
14890d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
14908b0a5094SBarry Smith 
14918b0a5094SBarry Smith    Logically Collective on SNES
14928b0a5094SBarry Smith 
14938b0a5094SBarry Smith    Input Parameters:
14948b0a5094SBarry Smith +  snes - the SNES context
14958b0a5094SBarry Smith .  r - vector to store function value
14968b0a5094SBarry Smith .  func - function evaluation routine
14978b0a5094SBarry Smith .  jmat - normally the same as mat but you can pass another matrix for which you compute the Jacobian of A(x) x - b(x) (see jmat below)
14988b0a5094SBarry Smith .  mat - matrix to store A
14998b0a5094SBarry Smith .  mfunc  - function to compute matrix value
15008b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
15018b0a5094SBarry Smith          function evaluation routine (may be PETSC_NULL)
15028b0a5094SBarry Smith 
15038b0a5094SBarry Smith    Calling sequence of func:
15048b0a5094SBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
15058b0a5094SBarry Smith 
15068b0a5094SBarry Smith +  f - function vector
15078b0a5094SBarry Smith -  ctx - optional user-defined function context
15088b0a5094SBarry Smith 
15098b0a5094SBarry Smith    Calling sequence of mfunc:
15108b0a5094SBarry Smith $     mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx);
15118b0a5094SBarry Smith 
15128b0a5094SBarry Smith +  x - input vector
15138b0a5094SBarry Smith .  jmat - Form Jacobian matrix of A(x) x - b(x) if available, not there is really no reason to use it in this way since then you can just use SNESSetJacobian(),
15148b0a5094SBarry Smith           normally just pass mat in this location
15158b0a5094SBarry Smith .  mat - form A(x) matrix
15168b0a5094SBarry Smith .  flag - flag indicating information about the preconditioner matrix
15178b0a5094SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
15188b0a5094SBarry Smith -  ctx - [optional] user-defined Jacobian context
15198b0a5094SBarry Smith 
15208b0a5094SBarry Smith    Notes:
15218b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
15228b0a5094SBarry Smith 
15238b0a5094SBarry Smith $     Solves the equation A(x) x = b(x) via the defect correction algorithm A(x^{n}) (x^{n+1} - x^{n}) = b(x^{n}) - A(x^{n})x^{n}
15248b0a5094SBarry Smith $     Note that when an exact solver is used this corresponds to the "classic" Picard A(x^{n}) x^{n+1} = b(x^{n}) iteration.
15258b0a5094SBarry Smith 
15268b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
15278b0a5094SBarry Smith 
15280d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
15290d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
15308b0a5094SBarry Smith 
15318b0a5094SBarry Smith    There is some controversity over the definition of a Picard iteration for nonlinear systems but almost everyone agrees that it involves a linear solve and some
15328b0a5094SBarry Smith    believe it is the iteration  A(x^{n}) x^{n+1} = b(x^{n}) hence we use the name Picard. If anyone has an authoritative  reference that defines the Picard iteration
15338b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
15348b0a5094SBarry Smith 
15358b0a5094SBarry Smith    Level: beginner
15368b0a5094SBarry Smith 
15378b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function
15388b0a5094SBarry Smith 
15390d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard()
15408b0a5094SBarry Smith @*/
15418b0a5094SBarry Smith PetscErrorCode  SNESSetPicard(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),Mat jmat, Mat mat, PetscErrorCode (*mfunc)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
15428b0a5094SBarry Smith {
15438b0a5094SBarry Smith   PetscErrorCode ierr;
15448b0a5094SBarry Smith   PetscFunctionBegin;
15458b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15468b0a5094SBarry Smith   snes->ops->computepfunction = func;
15478b0a5094SBarry Smith   snes->ops->computepjacobian = mfunc;
15488b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
15498b0a5094SBarry Smith   ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
15508b0a5094SBarry Smith   PetscFunctionReturn(0);
15518b0a5094SBarry Smith }
15528b0a5094SBarry Smith 
15538b0a5094SBarry Smith #undef __FUNCT__
1554d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess"
1555d25893d9SBarry Smith /*@C
1556d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1557d25893d9SBarry Smith 
1558d25893d9SBarry Smith    Logically Collective on SNES
1559d25893d9SBarry Smith 
1560d25893d9SBarry Smith    Input Parameters:
1561d25893d9SBarry Smith +  snes - the SNES context
1562d25893d9SBarry Smith .  func - function evaluation routine
1563d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
1564d25893d9SBarry Smith          function evaluation routine (may be PETSC_NULL)
1565d25893d9SBarry Smith 
1566d25893d9SBarry Smith    Calling sequence of func:
1567d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
1568d25893d9SBarry Smith 
1569d25893d9SBarry Smith .  f - function vector
1570d25893d9SBarry Smith -  ctx - optional user-defined function context
1571d25893d9SBarry Smith 
1572d25893d9SBarry Smith    Level: intermediate
1573d25893d9SBarry Smith 
1574d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
1575d25893d9SBarry Smith 
1576d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1577d25893d9SBarry Smith @*/
1578d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1579d25893d9SBarry Smith {
1580d25893d9SBarry Smith   PetscFunctionBegin;
1581d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1582d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
1583d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
1584d25893d9SBarry Smith   PetscFunctionReturn(0);
1585d25893d9SBarry Smith }
1586d25893d9SBarry Smith 
15873ab0aad5SBarry Smith /* --------------------------------------------------------------- */
15883ab0aad5SBarry Smith #undef __FUNCT__
15891096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
15901096aae1SMatthew Knepley /*@C
15911096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
15921096aae1SMatthew Knepley    it assumes a zero right hand side.
15931096aae1SMatthew Knepley 
15943f9fe445SBarry Smith    Logically Collective on SNES
15951096aae1SMatthew Knepley 
15961096aae1SMatthew Knepley    Input Parameter:
15971096aae1SMatthew Knepley .  snes - the SNES context
15981096aae1SMatthew Knepley 
15991096aae1SMatthew Knepley    Output Parameter:
1600bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
16011096aae1SMatthew Knepley 
16021096aae1SMatthew Knepley    Level: intermediate
16031096aae1SMatthew Knepley 
16041096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
16051096aae1SMatthew Knepley 
160685385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
16071096aae1SMatthew Knepley @*/
16087087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
16091096aae1SMatthew Knepley {
16101096aae1SMatthew Knepley   PetscFunctionBegin;
16110700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
16121096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
161385385478SLisandro Dalcin   *rhs = snes->vec_rhs;
16141096aae1SMatthew Knepley   PetscFunctionReturn(0);
16151096aae1SMatthew Knepley }
16161096aae1SMatthew Knepley 
16171096aae1SMatthew Knepley #undef __FUNCT__
16184a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
16199b94acceSBarry Smith /*@
162036851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
16219b94acceSBarry Smith                          SNESSetFunction().
16229b94acceSBarry Smith 
1623c7afd0dbSLois Curfman McInnes    Collective on SNES
1624c7afd0dbSLois Curfman McInnes 
16259b94acceSBarry Smith    Input Parameters:
1626c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1627c7afd0dbSLois Curfman McInnes -  x - input vector
16289b94acceSBarry Smith 
16299b94acceSBarry Smith    Output Parameter:
16303638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
16319b94acceSBarry Smith 
16321bffabb2SLois Curfman McInnes    Notes:
163336851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
163436851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
163536851e7fSLois Curfman McInnes    themselves.
163636851e7fSLois Curfman McInnes 
163736851e7fSLois Curfman McInnes    Level: developer
163836851e7fSLois Curfman McInnes 
16399b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
16409b94acceSBarry Smith 
1641a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
16429b94acceSBarry Smith @*/
16437087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
16449b94acceSBarry Smith {
1645dfbe8321SBarry Smith   PetscErrorCode ierr;
16466cab3a1bSJed Brown   DM             dm;
16476cab3a1bSJed Brown   SNESDM         sdm;
16489b94acceSBarry Smith 
16493a40ed3dSBarry Smith   PetscFunctionBegin;
16500700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
16510700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
16520700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
1653c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
1654c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
16554ec14c9cSBarry Smith   VecValidValues(x,2,PETSC_TRUE);
1656184914b5SBarry Smith 
16576cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
16586cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
1659d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
16606cab3a1bSJed Brown   if (sdm->computefunction) {
1661d64ed03dSBarry Smith     PetscStackPush("SNES user function");
16626cab3a1bSJed Brown     ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
1663d64ed03dSBarry Smith     PetscStackPop;
166473250ac0SBarry Smith   } else if (snes->dm) {
1665644e2e5bSBarry Smith     ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr);
1666c90fad12SPeter Brune   } else if (snes->vec_rhs) {
1667c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
1668644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
166985385478SLisandro Dalcin   if (snes->vec_rhs) {
167085385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
16713ab0aad5SBarry Smith   }
1672ae3c334cSLois Curfman McInnes   snes->nfuncs++;
1673d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
16744ec14c9cSBarry Smith   VecValidValues(y,3,PETSC_FALSE);
16753a40ed3dSBarry Smith   PetscFunctionReturn(0);
16769b94acceSBarry Smith }
16779b94acceSBarry Smith 
16784a2ae208SSatish Balay #undef __FUNCT__
1679646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS"
1680c79ef259SPeter Brune /*@
1681c79ef259SPeter Brune    SNESComputeGS - Calls the Gauss-Seidel function that has been set with
1682c79ef259SPeter Brune                    SNESSetGS().
1683c79ef259SPeter Brune 
1684c79ef259SPeter Brune    Collective on SNES
1685c79ef259SPeter Brune 
1686c79ef259SPeter Brune    Input Parameters:
1687c79ef259SPeter Brune +  snes - the SNES context
1688c79ef259SPeter Brune .  x - input vector
1689c79ef259SPeter Brune -  b - rhs vector
1690c79ef259SPeter Brune 
1691c79ef259SPeter Brune    Output Parameter:
1692c79ef259SPeter Brune .  x - new solution vector
1693c79ef259SPeter Brune 
1694c79ef259SPeter Brune    Notes:
1695c79ef259SPeter Brune    SNESComputeGS() is typically used within composed nonlinear solver
1696c79ef259SPeter Brune    implementations, so most users would not generally call this routine
1697c79ef259SPeter Brune    themselves.
1698c79ef259SPeter Brune 
1699c79ef259SPeter Brune    Level: developer
1700c79ef259SPeter Brune 
1701c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function
1702c79ef259SPeter Brune 
1703c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction()
1704c79ef259SPeter Brune @*/
1705646217ecSPeter Brune PetscErrorCode  SNESComputeGS(SNES snes,Vec b,Vec x)
1706646217ecSPeter Brune {
1707646217ecSPeter Brune   PetscErrorCode ierr;
170889b92e6fSPeter Brune   PetscInt i;
17096cab3a1bSJed Brown   DM dm;
17106cab3a1bSJed Brown   SNESDM sdm;
1711646217ecSPeter Brune 
1712646217ecSPeter Brune   PetscFunctionBegin;
1713646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1714646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
1715646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
1716646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
1717646217ecSPeter Brune   if(b) PetscCheckSameComm(snes,1,b,3);
17184ec14c9cSBarry Smith   if (b) VecValidValues(b,2,PETSC_TRUE);
1719701cf23dSPeter Brune   ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
17206cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
17216cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
17226cab3a1bSJed Brown   if (sdm->computegs) {
172389b92e6fSPeter Brune     for (i = 0; i < snes->gssweeps; i++) {
1724646217ecSPeter Brune       PetscStackPush("SNES user GS");
17256cab3a1bSJed Brown       ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
1726646217ecSPeter Brune       PetscStackPop;
172789b92e6fSPeter Brune     }
1728646217ecSPeter Brune   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve().");
1729701cf23dSPeter Brune   ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
17304ec14c9cSBarry Smith   VecValidValues(x,3,PETSC_FALSE);
1731646217ecSPeter Brune   PetscFunctionReturn(0);
1732646217ecSPeter Brune }
1733646217ecSPeter Brune 
1734646217ecSPeter Brune 
1735646217ecSPeter Brune #undef __FUNCT__
17364a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
173762fef451SLois Curfman McInnes /*@
173862fef451SLois Curfman McInnes    SNESComputeJacobian - Computes the Jacobian matrix that has been
173962fef451SLois Curfman McInnes    set with SNESSetJacobian().
174062fef451SLois Curfman McInnes 
1741c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
1742c7afd0dbSLois Curfman McInnes 
174362fef451SLois Curfman McInnes    Input Parameters:
1744c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1745c7afd0dbSLois Curfman McInnes -  x - input vector
174662fef451SLois Curfman McInnes 
174762fef451SLois Curfman McInnes    Output Parameters:
1748c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
174962fef451SLois Curfman McInnes .  B - optional preconditioning matrix
17502b668275SBarry Smith -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1751fee21e36SBarry Smith 
1752e35cf81dSBarry Smith   Options Database Keys:
1753e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
1754693365a8SJed Brown .    -snes_lag_jacobian <lag>
1755693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
1756693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
1757693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
17584c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
1759c01495d3SJed Brown .    -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference
1760c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
1761c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
1762c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
1763c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
17644c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
1765c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
1766c01495d3SJed Brown 
1767e35cf81dSBarry Smith 
176862fef451SLois Curfman McInnes    Notes:
176962fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
177062fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
177162fef451SLois Curfman McInnes 
177294b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the
1773dc5a77f8SLois Curfman McInnes    flag parameter.
177462fef451SLois Curfman McInnes 
177536851e7fSLois Curfman McInnes    Level: developer
177636851e7fSLois Curfman McInnes 
177762fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
177862fef451SLois Curfman McInnes 
1779e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
178062fef451SLois Curfman McInnes @*/
17817087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
17829b94acceSBarry Smith {
1783dfbe8321SBarry Smith   PetscErrorCode ierr;
1784ace3abfcSBarry Smith   PetscBool      flag;
17856cab3a1bSJed Brown   DM             dm;
17866cab3a1bSJed Brown   SNESDM         sdm;
17873a40ed3dSBarry Smith 
17883a40ed3dSBarry Smith   PetscFunctionBegin;
17890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
17900700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
17914482741eSBarry Smith   PetscValidPointer(flg,5);
1792c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
17934ec14c9cSBarry Smith   VecValidValues(X,2,PETSC_TRUE);
17946cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
17956cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
17966cab3a1bSJed Brown   if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
1797ebd3b9afSBarry Smith 
1798ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
1799ebd3b9afSBarry Smith 
1800fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
1801fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
1802fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
1803fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
1804e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1805e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
1806ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1807ebd3b9afSBarry Smith     if (flag) {
1808ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1809ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1810ebd3b9afSBarry Smith     }
1811e35cf81dSBarry Smith     PetscFunctionReturn(0);
1812e35cf81dSBarry Smith   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
1813e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1814e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
1815ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1816ebd3b9afSBarry Smith     if (flag) {
1817ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1818ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1819ebd3b9afSBarry Smith     }
1820e35cf81dSBarry Smith     PetscFunctionReturn(0);
1821e35cf81dSBarry Smith   }
1822e35cf81dSBarry Smith 
1823c4fc05e7SBarry Smith   *flg = DIFFERENT_NONZERO_PATTERN;
1824e35cf81dSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1825d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
18266cab3a1bSJed Brown   ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr);
1827d64ed03dSBarry Smith   PetscStackPop;
1828d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1829a8054027SBarry Smith 
18303b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
18313b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
18323b4f5425SBarry Smith     snes->lagpreconditioner = -1;
18333b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
1834a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1835a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
1836a8054027SBarry Smith   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
1837a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1838a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
1839a8054027SBarry Smith   }
1840a8054027SBarry Smith 
18416d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
18420700a824SBarry Smith   /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
18430700a824SBarry Smith     PetscValidHeaderSpecific(*B,MAT_CLASSID,4);   */
1844693365a8SJed Brown   {
1845693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
1846693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr);
1847693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
1848693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
1849693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr);
1850693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
1851693365a8SJed Brown       Mat Bexp_mine = PETSC_NULL,Bexp,FDexp;
1852693365a8SJed Brown       MatStructure mstruct;
1853693365a8SJed Brown       PetscViewer vdraw,vstdout;
18546b3a5b13SJed Brown       PetscBool flg;
1855693365a8SJed Brown       if (flag_operator) {
1856693365a8SJed Brown         ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr);
1857693365a8SJed Brown         Bexp = Bexp_mine;
1858693365a8SJed Brown       } else {
1859693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
1860693365a8SJed Brown         ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
1861693365a8SJed Brown         if (flg) Bexp = *B;
1862693365a8SJed Brown         else {
1863693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
1864693365a8SJed Brown           ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr);
1865693365a8SJed Brown           Bexp = Bexp_mine;
1866693365a8SJed Brown         }
1867693365a8SJed Brown       }
1868693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
1869693365a8SJed Brown       ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr);
1870693365a8SJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
1871693365a8SJed Brown       if (flag_draw || flag_contour) {
1872693365a8SJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
1873693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
1874693365a8SJed Brown       } else vdraw = PETSC_NULL;
1875693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr);
1876693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
1877693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
1878693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
1879693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
1880693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
1881693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
1882693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
1883693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
1884693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
1885693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
1886693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
1887693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
1888693365a8SJed Brown       }
1889693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
1890693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
1891693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
1892693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
1893693365a8SJed Brown     }
1894693365a8SJed Brown   }
18954c30e9fbSJed Brown   {
18966719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
18976719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
18984c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr);
18996719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr);
19004c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
19014c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
19026719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr);
19036719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr);
19046719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr);
19056719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
19064c30e9fbSJed Brown       Mat Bfd;
19074c30e9fbSJed Brown       MatStructure mstruct;
19084c30e9fbSJed Brown       PetscViewer vdraw,vstdout;
19094c30e9fbSJed Brown       ISColoring iscoloring;
19104c30e9fbSJed Brown       MatFDColoring matfdcoloring;
19114c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
19124c30e9fbSJed Brown       void *funcctx;
19136719d8e4SJed Brown       PetscReal norm1,norm2,normmax;
19144c30e9fbSJed Brown 
19154c30e9fbSJed Brown       ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
19164c30e9fbSJed Brown       ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
19174c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
19184c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
19194c30e9fbSJed Brown 
19204c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
19214c30e9fbSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr);
19224c30e9fbSJed Brown       ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr);
19234c30e9fbSJed Brown       ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
19244c30e9fbSJed Brown       ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
19254c30e9fbSJed Brown       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
19264c30e9fbSJed Brown       ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr);
19274c30e9fbSJed Brown       ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
19284c30e9fbSJed Brown 
19294c30e9fbSJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
19304c30e9fbSJed Brown       if (flag_draw || flag_contour) {
19314c30e9fbSJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
19324c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
19334c30e9fbSJed Brown       } else vdraw = PETSC_NULL;
19344c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
19356719d8e4SJed Brown       if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);}
19364c30e9fbSJed Brown       if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);}
19374c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
19386719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
19394c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
19404c30e9fbSJed Brown       ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
19414c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
19426719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
19434c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
19446719d8e4SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr);
19456719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
19464c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
19474c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
19484c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
19494c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
19504c30e9fbSJed Brown       }
19514c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
19526719d8e4SJed Brown 
19536719d8e4SJed Brown       if (flag_threshold) {
19546719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
19556719d8e4SJed Brown         ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr);
19566719d8e4SJed Brown         ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr);
19576719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
19586719d8e4SJed Brown           const PetscScalar *ba,*ca;
19596719d8e4SJed Brown           const PetscInt *bj,*cj;
19606719d8e4SJed Brown           PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
19616719d8e4SJed Brown           PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0;
19626719d8e4SJed Brown           ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
19636719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
19646719d8e4SJed Brown           if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
19656719d8e4SJed Brown           for (j=0; j<bn; j++) {
19666719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
19676719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
19686719d8e4SJed Brown               maxentrycol = bj[j];
19696719d8e4SJed Brown               maxentry = PetscRealPart(ba[j]);
19706719d8e4SJed Brown             }
19716719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
19726719d8e4SJed Brown               maxdiffcol = bj[j];
19736719d8e4SJed Brown               maxdiff = PetscRealPart(ca[j]);
19746719d8e4SJed Brown             }
19756719d8e4SJed Brown             if (rdiff > maxrdiff) {
19766719d8e4SJed Brown               maxrdiffcol = bj[j];
19776719d8e4SJed Brown               maxrdiff = rdiff;
19786719d8e4SJed Brown             }
19796719d8e4SJed Brown           }
19806719d8e4SJed Brown           if (maxrdiff > 1) {
19816719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"row %D (maxentry=%G at %D, maxdiff=%G at %D, maxrdiff=%G at %D):",i,maxentry,maxentrycol,maxdiff,maxdiffcol,maxrdiff,maxrdiffcol);CHKERRQ(ierr);
19826719d8e4SJed Brown             for (j=0; j<bn; j++) {
19836719d8e4SJed Brown               PetscReal rdiff;
19846719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
19856719d8e4SJed Brown               if (rdiff > 1) {
19866719d8e4SJed Brown                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr);
19876719d8e4SJed Brown               }
19886719d8e4SJed Brown             }
19896719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
19906719d8e4SJed Brown           }
19916719d8e4SJed Brown           ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
19926719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
19936719d8e4SJed Brown         }
19946719d8e4SJed Brown       }
19954c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
19964c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
19974c30e9fbSJed Brown     }
19984c30e9fbSJed Brown   }
19993a40ed3dSBarry Smith   PetscFunctionReturn(0);
20009b94acceSBarry Smith }
20019b94acceSBarry Smith 
20024a2ae208SSatish Balay #undef __FUNCT__
20034a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
20049b94acceSBarry Smith /*@C
20059b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2006044dda88SLois Curfman McInnes    location to store the matrix.
20079b94acceSBarry Smith 
20083f9fe445SBarry Smith    Logically Collective on SNES and Mat
2009c7afd0dbSLois Curfman McInnes 
20109b94acceSBarry Smith    Input Parameters:
2011c7afd0dbSLois Curfman McInnes +  snes - the SNES context
20129b94acceSBarry Smith .  A - Jacobian matrix
20139b94acceSBarry Smith .  B - preconditioner matrix (usually same as the Jacobian)
2014efd51863SBarry Smith .  func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value)
2015c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
2016efd51863SBarry Smith          Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value)
20179b94acceSBarry Smith 
20189b94acceSBarry Smith    Calling sequence of func:
20198d76a1e5SLois Curfman McInnes $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
20209b94acceSBarry Smith 
2021c7afd0dbSLois Curfman McInnes +  x - input vector
20229b94acceSBarry Smith .  A - Jacobian matrix
20239b94acceSBarry Smith .  B - preconditioner matrix, usually the same as A
2024ac21db08SLois Curfman McInnes .  flag - flag indicating information about the preconditioner matrix
20252b668275SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
2026c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined Jacobian context
20279b94acceSBarry Smith 
20289b94acceSBarry Smith    Notes:
202994b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the flag
20302cd2dfdcSLois Curfman McInnes    output parameter in the routine func().  Be sure to read this information!
2031ac21db08SLois Curfman McInnes 
2032ac21db08SLois Curfman McInnes    The routine func() takes Mat * as the matrix arguments rather than Mat.
20339b94acceSBarry Smith    This allows the Jacobian evaluation routine to replace A and/or B with a
20349b94acceSBarry Smith    completely new new matrix structure (not just different matrix elements)
20359b94acceSBarry Smith    when appropriate, for instance, if the nonzero structure is changing
20369b94acceSBarry Smith    throughout the global iterations.
20379b94acceSBarry Smith 
203816913363SBarry Smith    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
203916913363SBarry Smith    each matrix.
204016913363SBarry Smith 
2041a8a26c1eSJed Brown    If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument
2042a8a26c1eSJed Brown    must be a MatFDColoring.
2043a8a26c1eSJed Brown 
2044c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2045c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2046c3cc8fd1SJed Brown 
204736851e7fSLois Curfman McInnes    Level: beginner
204836851e7fSLois Curfman McInnes 
20499b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
20509b94acceSBarry Smith 
20513ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
20529b94acceSBarry Smith @*/
20537087cfbeSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
20549b94acceSBarry Smith {
2055dfbe8321SBarry Smith   PetscErrorCode ierr;
20566cab3a1bSJed Brown   DM             dm;
20573a7fca6bSBarry Smith 
20583a40ed3dSBarry Smith   PetscFunctionBegin;
20590700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
20600700a824SBarry Smith   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
20610700a824SBarry Smith   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
2062c9780b6fSBarry Smith   if (A) PetscCheckSameComm(snes,1,A,2);
206306975374SJed Brown   if (B) PetscCheckSameComm(snes,1,B,3);
20646cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
20656cab3a1bSJed Brown   ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr);
20663a7fca6bSBarry Smith   if (A) {
20677dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
20686bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
20699b94acceSBarry Smith     snes->jacobian = A;
20703a7fca6bSBarry Smith   }
20713a7fca6bSBarry Smith   if (B) {
20727dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
20736bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
20749b94acceSBarry Smith     snes->jacobian_pre = B;
20753a7fca6bSBarry Smith   }
20763a40ed3dSBarry Smith   PetscFunctionReturn(0);
20779b94acceSBarry Smith }
207862fef451SLois Curfman McInnes 
20794a2ae208SSatish Balay #undef __FUNCT__
20804a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
2081c2aafc4cSSatish Balay /*@C
2082b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2083b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2084b4fd4287SBarry Smith 
2085c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2086c7afd0dbSLois Curfman McInnes 
2087b4fd4287SBarry Smith    Input Parameter:
2088b4fd4287SBarry Smith .  snes - the nonlinear solver context
2089b4fd4287SBarry Smith 
2090b4fd4287SBarry Smith    Output Parameters:
2091c7afd0dbSLois Curfman McInnes +  A - location to stash Jacobian matrix (or PETSC_NULL)
2092b4fd4287SBarry Smith .  B - location to stash preconditioner matrix (or PETSC_NULL)
209370e92668SMatthew Knepley .  func - location to put Jacobian function (or PETSC_NULL)
209470e92668SMatthew Knepley -  ctx - location to stash Jacobian ctx (or PETSC_NULL)
2095fee21e36SBarry Smith 
209636851e7fSLois Curfman McInnes    Level: advanced
209736851e7fSLois Curfman McInnes 
2098b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian()
2099b4fd4287SBarry Smith @*/
21007087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
2101b4fd4287SBarry Smith {
21026cab3a1bSJed Brown   PetscErrorCode ierr;
21036cab3a1bSJed Brown   DM             dm;
21046cab3a1bSJed Brown   SNESDM         sdm;
21056cab3a1bSJed Brown 
21063a40ed3dSBarry Smith   PetscFunctionBegin;
21070700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2108b4fd4287SBarry Smith   if (A)    *A    = snes->jacobian;
2109b4fd4287SBarry Smith   if (B)    *B    = snes->jacobian_pre;
21106cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
21116cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
21126cab3a1bSJed Brown   if (func) *func = sdm->computejacobian;
21136cab3a1bSJed Brown   if (ctx)  *ctx  = sdm->jacobianctx;
21143a40ed3dSBarry Smith   PetscFunctionReturn(0);
2115b4fd4287SBarry Smith }
2116b4fd4287SBarry Smith 
21179b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
21189b94acceSBarry Smith 
21194a2ae208SSatish Balay #undef __FUNCT__
21204a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
21219b94acceSBarry Smith /*@
21229b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
2123272ac6f2SLois Curfman McInnes    of a nonlinear solver.
21249b94acceSBarry Smith 
2125fee21e36SBarry Smith    Collective on SNES
2126fee21e36SBarry Smith 
2127c7afd0dbSLois Curfman McInnes    Input Parameters:
212870e92668SMatthew Knepley .  snes - the SNES context
2129c7afd0dbSLois Curfman McInnes 
2130272ac6f2SLois Curfman McInnes    Notes:
2131272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
2132272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
2133272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
2134272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
2135272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
2136272ac6f2SLois Curfman McInnes 
213736851e7fSLois Curfman McInnes    Level: advanced
213836851e7fSLois Curfman McInnes 
21399b94acceSBarry Smith .keywords: SNES, nonlinear, setup
21409b94acceSBarry Smith 
21419b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
21429b94acceSBarry Smith @*/
21437087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
21449b94acceSBarry Smith {
2145dfbe8321SBarry Smith   PetscErrorCode ierr;
21466cab3a1bSJed Brown   DM             dm;
21476cab3a1bSJed Brown   SNESDM         sdm;
21483a40ed3dSBarry Smith 
21493a40ed3dSBarry Smith   PetscFunctionBegin;
21500700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
21514dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
21529b94acceSBarry Smith 
21537adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
215485385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
215585385478SLisandro Dalcin   }
215685385478SLisandro Dalcin 
2157a63bb30eSJed Brown   ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
215817186662SBarry Smith   if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
215958c9b817SLisandro Dalcin   if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
216058c9b817SLisandro Dalcin 
216158c9b817SLisandro Dalcin   if (!snes->vec_sol_update /* && snes->vec_sol */) {
216258c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
216358c9b817SLisandro Dalcin     ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr);
216458c9b817SLisandro Dalcin   }
216558c9b817SLisandro Dalcin 
21666cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
21676cab3a1bSJed Brown   ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */
21686cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
21696cab3a1bSJed Brown   if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc");
21706cab3a1bSJed Brown   if (!snes->vec_func) {
21716cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2172214df951SJed Brown   }
2173efd51863SBarry Smith 
2174b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
2175b710008aSBarry Smith 
2176f1c6b773SPeter Brune   if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);}
21779e764e56SPeter Brune 
2178d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
2179d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
2180d25893d9SBarry Smith   }
2181d25893d9SBarry Smith 
2182410397dcSLisandro Dalcin   if (snes->ops->setup) {
2183410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2184410397dcSLisandro Dalcin   }
218558c9b817SLisandro Dalcin 
21867aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
21873a40ed3dSBarry Smith   PetscFunctionReturn(0);
21889b94acceSBarry Smith }
21899b94acceSBarry Smith 
21904a2ae208SSatish Balay #undef __FUNCT__
219137596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
219237596af1SLisandro Dalcin /*@
219337596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
219437596af1SLisandro Dalcin 
219537596af1SLisandro Dalcin    Collective on SNES
219637596af1SLisandro Dalcin 
219737596af1SLisandro Dalcin    Input Parameter:
219837596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
219937596af1SLisandro Dalcin 
2200d25893d9SBarry Smith    Level: intermediate
2201d25893d9SBarry Smith 
2202d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
220337596af1SLisandro Dalcin 
220437596af1SLisandro Dalcin .keywords: SNES, destroy
220537596af1SLisandro Dalcin 
220637596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
220737596af1SLisandro Dalcin @*/
220837596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
220937596af1SLisandro Dalcin {
221037596af1SLisandro Dalcin   PetscErrorCode ierr;
221137596af1SLisandro Dalcin 
221237596af1SLisandro Dalcin   PetscFunctionBegin;
221337596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2214d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
2215d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
2216d25893d9SBarry Smith     snes->user = PETSC_NULL;
2217d25893d9SBarry Smith   }
22188a23116dSBarry Smith   if (snes->pc) {
22198a23116dSBarry Smith     ierr = SNESReset(snes->pc);CHKERRQ(ierr);
22208a23116dSBarry Smith   }
22218a23116dSBarry Smith 
222237596af1SLisandro Dalcin   if (snes->ops->reset) {
222337596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
222437596af1SLisandro Dalcin   }
22259e764e56SPeter Brune   if (snes->ksp) {
22269e764e56SPeter Brune     ierr = KSPReset(snes->ksp);CHKERRQ(ierr);
22279e764e56SPeter Brune   }
22289e764e56SPeter Brune 
22299e764e56SPeter Brune   if (snes->linesearch) {
2230f1c6b773SPeter Brune     ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr);
22319e764e56SPeter Brune   }
22329e764e56SPeter Brune 
22336bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
22346bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
22356bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
22366bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
22376bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
22386bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2239c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
2240c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
224137596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
224237596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
224337596af1SLisandro Dalcin   PetscFunctionReturn(0);
224437596af1SLisandro Dalcin }
224537596af1SLisandro Dalcin 
224637596af1SLisandro Dalcin #undef __FUNCT__
22474a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
224852baeb72SSatish Balay /*@
22499b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
22509b94acceSBarry Smith    with SNESCreate().
22519b94acceSBarry Smith 
2252c7afd0dbSLois Curfman McInnes    Collective on SNES
2253c7afd0dbSLois Curfman McInnes 
22549b94acceSBarry Smith    Input Parameter:
22559b94acceSBarry Smith .  snes - the SNES context
22569b94acceSBarry Smith 
225736851e7fSLois Curfman McInnes    Level: beginner
225836851e7fSLois Curfman McInnes 
22599b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
22609b94acceSBarry Smith 
226163a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
22629b94acceSBarry Smith @*/
22636bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
22649b94acceSBarry Smith {
22656849ba73SBarry Smith   PetscErrorCode ierr;
22663a40ed3dSBarry Smith 
22673a40ed3dSBarry Smith   PetscFunctionBegin;
22686bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
22696bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
22706bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2271d4bb536fSBarry Smith 
22726bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
22738a23116dSBarry Smith   ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr);
22746b8b9a38SLisandro Dalcin 
2275be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
22766bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
22776bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
22786d4c513bSLisandro Dalcin 
22796bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
22806bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
2281f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr);
22826b8b9a38SLisandro Dalcin 
22836bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
22846bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
22856bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
22866b8b9a38SLisandro Dalcin   }
22876bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
22886bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
22896bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
229058c9b817SLisandro Dalcin   }
22916bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2292a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
22933a40ed3dSBarry Smith  PetscFunctionReturn(0);
22949b94acceSBarry Smith }
22959b94acceSBarry Smith 
22969b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
22979b94acceSBarry Smith 
22984a2ae208SSatish Balay #undef __FUNCT__
2299a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
2300a8054027SBarry Smith /*@
2301a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2302a8054027SBarry Smith 
23033f9fe445SBarry Smith    Logically Collective on SNES
2304a8054027SBarry Smith 
2305a8054027SBarry Smith    Input Parameters:
2306a8054027SBarry Smith +  snes - the SNES context
2307a8054027SBarry 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
23083b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2309a8054027SBarry Smith 
2310a8054027SBarry Smith    Options Database Keys:
2311a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2312a8054027SBarry Smith 
2313a8054027SBarry Smith    Notes:
2314a8054027SBarry Smith    The default is 1
2315a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2316a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2317a8054027SBarry Smith 
2318a8054027SBarry Smith    Level: intermediate
2319a8054027SBarry Smith 
2320a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2321a8054027SBarry Smith 
2322e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2323a8054027SBarry Smith 
2324a8054027SBarry Smith @*/
23257087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2326a8054027SBarry Smith {
2327a8054027SBarry Smith   PetscFunctionBegin;
23280700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2329e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2330e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2331c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2332a8054027SBarry Smith   snes->lagpreconditioner = lag;
2333a8054027SBarry Smith   PetscFunctionReturn(0);
2334a8054027SBarry Smith }
2335a8054027SBarry Smith 
2336a8054027SBarry Smith #undef __FUNCT__
2337efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
2338efd51863SBarry Smith /*@
2339efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2340efd51863SBarry Smith 
2341efd51863SBarry Smith    Logically Collective on SNES
2342efd51863SBarry Smith 
2343efd51863SBarry Smith    Input Parameters:
2344efd51863SBarry Smith +  snes - the SNES context
2345efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
2346efd51863SBarry Smith 
2347efd51863SBarry Smith    Options Database Keys:
2348efd51863SBarry Smith .    -snes_grid_sequence <steps>
2349efd51863SBarry Smith 
2350efd51863SBarry Smith    Level: intermediate
2351efd51863SBarry Smith 
2352c0df2a02SJed Brown    Notes:
2353c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2354c0df2a02SJed Brown 
2355efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2356efd51863SBarry Smith 
2357efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2358efd51863SBarry Smith 
2359efd51863SBarry Smith @*/
2360efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2361efd51863SBarry Smith {
2362efd51863SBarry Smith   PetscFunctionBegin;
2363efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2364efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
2365efd51863SBarry Smith   snes->gridsequence = steps;
2366efd51863SBarry Smith   PetscFunctionReturn(0);
2367efd51863SBarry Smith }
2368efd51863SBarry Smith 
2369efd51863SBarry Smith #undef __FUNCT__
2370a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
2371a8054027SBarry Smith /*@
2372a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
2373a8054027SBarry Smith 
23743f9fe445SBarry Smith    Not Collective
2375a8054027SBarry Smith 
2376a8054027SBarry Smith    Input Parameter:
2377a8054027SBarry Smith .  snes - the SNES context
2378a8054027SBarry Smith 
2379a8054027SBarry Smith    Output Parameter:
2380a8054027SBarry 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
23813b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2382a8054027SBarry Smith 
2383a8054027SBarry Smith    Options Database Keys:
2384a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2385a8054027SBarry Smith 
2386a8054027SBarry Smith    Notes:
2387a8054027SBarry Smith    The default is 1
2388a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2389a8054027SBarry Smith 
2390a8054027SBarry Smith    Level: intermediate
2391a8054027SBarry Smith 
2392a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2393a8054027SBarry Smith 
2394a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
2395a8054027SBarry Smith 
2396a8054027SBarry Smith @*/
23977087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
2398a8054027SBarry Smith {
2399a8054027SBarry Smith   PetscFunctionBegin;
24000700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2401a8054027SBarry Smith   *lag = snes->lagpreconditioner;
2402a8054027SBarry Smith   PetscFunctionReturn(0);
2403a8054027SBarry Smith }
2404a8054027SBarry Smith 
2405a8054027SBarry Smith #undef __FUNCT__
2406e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
2407e35cf81dSBarry Smith /*@
2408e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
2409e35cf81dSBarry Smith      often the preconditioner is rebuilt.
2410e35cf81dSBarry Smith 
24113f9fe445SBarry Smith    Logically Collective on SNES
2412e35cf81dSBarry Smith 
2413e35cf81dSBarry Smith    Input Parameters:
2414e35cf81dSBarry Smith +  snes - the SNES context
2415e35cf81dSBarry 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
2416fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
2417e35cf81dSBarry Smith 
2418e35cf81dSBarry Smith    Options Database Keys:
2419e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2420e35cf81dSBarry Smith 
2421e35cf81dSBarry Smith    Notes:
2422e35cf81dSBarry Smith    The default is 1
2423e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2424fe3ffe1eSBarry 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
2425fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
2426e35cf81dSBarry Smith 
2427e35cf81dSBarry Smith    Level: intermediate
2428e35cf81dSBarry Smith 
2429e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2430e35cf81dSBarry Smith 
2431e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
2432e35cf81dSBarry Smith 
2433e35cf81dSBarry Smith @*/
24347087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
2435e35cf81dSBarry Smith {
2436e35cf81dSBarry Smith   PetscFunctionBegin;
24370700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2438e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2439e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2440c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2441e35cf81dSBarry Smith   snes->lagjacobian = lag;
2442e35cf81dSBarry Smith   PetscFunctionReturn(0);
2443e35cf81dSBarry Smith }
2444e35cf81dSBarry Smith 
2445e35cf81dSBarry Smith #undef __FUNCT__
2446e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
2447e35cf81dSBarry Smith /*@
2448e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
2449e35cf81dSBarry Smith 
24503f9fe445SBarry Smith    Not Collective
2451e35cf81dSBarry Smith 
2452e35cf81dSBarry Smith    Input Parameter:
2453e35cf81dSBarry Smith .  snes - the SNES context
2454e35cf81dSBarry Smith 
2455e35cf81dSBarry Smith    Output Parameter:
2456e35cf81dSBarry 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
2457e35cf81dSBarry Smith          the Jacobian is built etc.
2458e35cf81dSBarry Smith 
2459e35cf81dSBarry Smith    Options Database Keys:
2460e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2461e35cf81dSBarry Smith 
2462e35cf81dSBarry Smith    Notes:
2463e35cf81dSBarry Smith    The default is 1
2464e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2465e35cf81dSBarry Smith 
2466e35cf81dSBarry Smith    Level: intermediate
2467e35cf81dSBarry Smith 
2468e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2469e35cf81dSBarry Smith 
2470e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
2471e35cf81dSBarry Smith 
2472e35cf81dSBarry Smith @*/
24737087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
2474e35cf81dSBarry Smith {
2475e35cf81dSBarry Smith   PetscFunctionBegin;
24760700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2477e35cf81dSBarry Smith   *lag = snes->lagjacobian;
2478e35cf81dSBarry Smith   PetscFunctionReturn(0);
2479e35cf81dSBarry Smith }
2480e35cf81dSBarry Smith 
2481e35cf81dSBarry Smith #undef __FUNCT__
24824a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
24839b94acceSBarry Smith /*@
2484d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
24859b94acceSBarry Smith 
24863f9fe445SBarry Smith    Logically Collective on SNES
2487c7afd0dbSLois Curfman McInnes 
24889b94acceSBarry Smith    Input Parameters:
2489c7afd0dbSLois Curfman McInnes +  snes - the SNES context
249070441072SBarry Smith .  abstol - absolute convergence tolerance
249133174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
249233174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
249333174efeSLois Curfman McInnes            of the change in the solution between steps
249433174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2495c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2496fee21e36SBarry Smith 
249733174efeSLois Curfman McInnes    Options Database Keys:
249870441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
2499c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
2500c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
2501c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
2502c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
25039b94acceSBarry Smith 
2504d7a720efSLois Curfman McInnes    Notes:
25059b94acceSBarry Smith    The default maximum number of iterations is 50.
25069b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
25079b94acceSBarry Smith 
250836851e7fSLois Curfman McInnes    Level: intermediate
250936851e7fSLois Curfman McInnes 
251033174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
25119b94acceSBarry Smith 
25122492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
25139b94acceSBarry Smith @*/
25147087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
25159b94acceSBarry Smith {
25163a40ed3dSBarry Smith   PetscFunctionBegin;
25170700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2518c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
2519c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
2520c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
2521c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
2522c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
2523c5eb9154SBarry Smith 
2524ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
2525ab54825eSJed Brown     if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol);
2526ab54825eSJed Brown     snes->abstol = abstol;
2527ab54825eSJed Brown   }
2528ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
2529ab54825eSJed Brown     if (rtol < 0.0 || 1.0 <= rtol) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Relative tolerance %G must be non-negative and less than 1.0",rtol);
2530ab54825eSJed Brown     snes->rtol = rtol;
2531ab54825eSJed Brown   }
2532ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
2533ab54825eSJed Brown     if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol);
2534ab54825eSJed Brown     snes->xtol = stol;
2535ab54825eSJed Brown   }
2536ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
2537ab54825eSJed Brown     if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
2538ab54825eSJed Brown     snes->max_its = maxit;
2539ab54825eSJed Brown   }
2540ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
2541ab54825eSJed Brown     if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
2542ab54825eSJed Brown     snes->max_funcs = maxf;
2543ab54825eSJed Brown   }
25443a40ed3dSBarry Smith   PetscFunctionReturn(0);
25459b94acceSBarry Smith }
25469b94acceSBarry Smith 
25474a2ae208SSatish Balay #undef __FUNCT__
25484a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
25499b94acceSBarry Smith /*@
255033174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
255133174efeSLois Curfman McInnes 
2552c7afd0dbSLois Curfman McInnes    Not Collective
2553c7afd0dbSLois Curfman McInnes 
255433174efeSLois Curfman McInnes    Input Parameters:
2555c7afd0dbSLois Curfman McInnes +  snes - the SNES context
255685385478SLisandro Dalcin .  atol - absolute convergence tolerance
255733174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
255833174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
255933174efeSLois Curfman McInnes            of the change in the solution between steps
256033174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2561c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2562fee21e36SBarry Smith 
256333174efeSLois Curfman McInnes    Notes:
256433174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
256533174efeSLois Curfman McInnes 
256636851e7fSLois Curfman McInnes    Level: intermediate
256736851e7fSLois Curfman McInnes 
256833174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
256933174efeSLois Curfman McInnes 
257033174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
257133174efeSLois Curfman McInnes @*/
25727087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
257333174efeSLois Curfman McInnes {
25743a40ed3dSBarry Smith   PetscFunctionBegin;
25750700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
257685385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
257733174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
257833174efeSLois Curfman McInnes   if (stol)  *stol  = snes->xtol;
257933174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
258033174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
25813a40ed3dSBarry Smith   PetscFunctionReturn(0);
258233174efeSLois Curfman McInnes }
258333174efeSLois Curfman McInnes 
25844a2ae208SSatish Balay #undef __FUNCT__
25854a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
258633174efeSLois Curfman McInnes /*@
25879b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
25889b94acceSBarry Smith 
25893f9fe445SBarry Smith    Logically Collective on SNES
2590fee21e36SBarry Smith 
2591c7afd0dbSLois Curfman McInnes    Input Parameters:
2592c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2593c7afd0dbSLois Curfman McInnes -  tol - tolerance
2594c7afd0dbSLois Curfman McInnes 
25959b94acceSBarry Smith    Options Database Key:
2596c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
25979b94acceSBarry Smith 
259836851e7fSLois Curfman McInnes    Level: intermediate
259936851e7fSLois Curfman McInnes 
26009b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
26019b94acceSBarry Smith 
26022492ecdbSBarry Smith .seealso: SNESSetTolerances()
26039b94acceSBarry Smith @*/
26047087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
26059b94acceSBarry Smith {
26063a40ed3dSBarry Smith   PetscFunctionBegin;
26070700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2608c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
26099b94acceSBarry Smith   snes->deltatol = tol;
26103a40ed3dSBarry Smith   PetscFunctionReturn(0);
26119b94acceSBarry Smith }
26129b94acceSBarry Smith 
2613df9fa365SBarry Smith /*
2614df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
2615df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
2616df9fa365SBarry Smith    macros instead of functions
2617df9fa365SBarry Smith */
26184a2ae208SSatish Balay #undef __FUNCT__
2619a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
26207087cfbeSBarry Smith PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2621ce1608b8SBarry Smith {
2622dfbe8321SBarry Smith   PetscErrorCode ierr;
2623ce1608b8SBarry Smith 
2624ce1608b8SBarry Smith   PetscFunctionBegin;
26250700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2626a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
2627ce1608b8SBarry Smith   PetscFunctionReturn(0);
2628ce1608b8SBarry Smith }
2629ce1608b8SBarry Smith 
26304a2ae208SSatish Balay #undef __FUNCT__
2631a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
26327087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2633df9fa365SBarry Smith {
2634dfbe8321SBarry Smith   PetscErrorCode ierr;
2635df9fa365SBarry Smith 
2636df9fa365SBarry Smith   PetscFunctionBegin;
2637a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2638df9fa365SBarry Smith   PetscFunctionReturn(0);
2639df9fa365SBarry Smith }
2640df9fa365SBarry Smith 
26414a2ae208SSatish Balay #undef __FUNCT__
2642a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
26436bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
2644df9fa365SBarry Smith {
2645dfbe8321SBarry Smith   PetscErrorCode ierr;
2646df9fa365SBarry Smith 
2647df9fa365SBarry Smith   PetscFunctionBegin;
2648a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2649df9fa365SBarry Smith   PetscFunctionReturn(0);
2650df9fa365SBarry Smith }
2651df9fa365SBarry Smith 
26527087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
2653b271bb04SBarry Smith #undef __FUNCT__
2654b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
26557087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2656b271bb04SBarry Smith {
2657b271bb04SBarry Smith   PetscDrawLG      lg;
2658b271bb04SBarry Smith   PetscErrorCode   ierr;
2659b271bb04SBarry Smith   PetscReal        x,y,per;
2660b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
2661b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
2662b271bb04SBarry Smith   PetscDraw        draw;
2663b271bb04SBarry Smith   PetscFunctionBegin;
2664b271bb04SBarry Smith   if (!monctx) {
2665b271bb04SBarry Smith     MPI_Comm    comm;
2666b271bb04SBarry Smith 
2667b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2668b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
2669b271bb04SBarry Smith   }
2670b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
2671b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2672b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2673b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
2674b271bb04SBarry Smith   x = (PetscReal) n;
2675b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
2676b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2677b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2678b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2679b271bb04SBarry Smith   }
2680b271bb04SBarry Smith 
2681b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
2682b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2683b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2684b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
2685b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
2686b271bb04SBarry Smith   x = (PetscReal) n;
2687b271bb04SBarry Smith   y = 100.0*per;
2688b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2689b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2690b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2691b271bb04SBarry Smith   }
2692b271bb04SBarry Smith 
2693b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
2694b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2695b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2696b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
2697b271bb04SBarry Smith   x = (PetscReal) n;
2698b271bb04SBarry Smith   y = (prev - rnorm)/prev;
2699b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2700b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2701b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2702b271bb04SBarry Smith   }
2703b271bb04SBarry Smith 
2704b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
2705b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2706b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2707b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
2708b271bb04SBarry Smith   x = (PetscReal) n;
2709b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
2710b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
2711b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2712b271bb04SBarry Smith   }
2713b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2714b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2715b271bb04SBarry Smith   }
2716b271bb04SBarry Smith   prev = rnorm;
2717b271bb04SBarry Smith   PetscFunctionReturn(0);
2718b271bb04SBarry Smith }
2719b271bb04SBarry Smith 
2720b271bb04SBarry Smith #undef __FUNCT__
2721b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
27227087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2723b271bb04SBarry Smith {
2724b271bb04SBarry Smith   PetscErrorCode ierr;
2725b271bb04SBarry Smith 
2726b271bb04SBarry Smith   PetscFunctionBegin;
2727b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2728b271bb04SBarry Smith   PetscFunctionReturn(0);
2729b271bb04SBarry Smith }
2730b271bb04SBarry Smith 
2731b271bb04SBarry Smith #undef __FUNCT__
2732b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
27336bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG *draw)
2734b271bb04SBarry Smith {
2735b271bb04SBarry Smith   PetscErrorCode ierr;
2736b271bb04SBarry Smith 
2737b271bb04SBarry Smith   PetscFunctionBegin;
2738b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2739b271bb04SBarry Smith   PetscFunctionReturn(0);
2740b271bb04SBarry Smith }
2741b271bb04SBarry Smith 
27427a03ce2fSLisandro Dalcin #undef __FUNCT__
27437a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
2744228d79bcSJed Brown /*@
2745228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
2746228d79bcSJed Brown 
2747228d79bcSJed Brown    Collective on SNES
2748228d79bcSJed Brown 
2749228d79bcSJed Brown    Input Parameters:
2750228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
2751228d79bcSJed Brown .  iter - iteration number
2752228d79bcSJed Brown -  rnorm - relative norm of the residual
2753228d79bcSJed Brown 
2754228d79bcSJed Brown    Notes:
2755228d79bcSJed Brown    This routine is called by the SNES implementations.
2756228d79bcSJed Brown    It does not typically need to be called by the user.
2757228d79bcSJed Brown 
2758228d79bcSJed Brown    Level: developer
2759228d79bcSJed Brown 
2760228d79bcSJed Brown .seealso: SNESMonitorSet()
2761228d79bcSJed Brown @*/
27627a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
27637a03ce2fSLisandro Dalcin {
27647a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
27657a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
27667a03ce2fSLisandro Dalcin 
27677a03ce2fSLisandro Dalcin   PetscFunctionBegin;
27687a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
27697a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
27707a03ce2fSLisandro Dalcin   }
27717a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
27727a03ce2fSLisandro Dalcin }
27737a03ce2fSLisandro Dalcin 
27749b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
27759b94acceSBarry Smith 
27764a2ae208SSatish Balay #undef __FUNCT__
2777a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
27789b94acceSBarry Smith /*@C
2779a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
27809b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
27819b94acceSBarry Smith    progress.
27829b94acceSBarry Smith 
27833f9fe445SBarry Smith    Logically Collective on SNES
2784fee21e36SBarry Smith 
2785c7afd0dbSLois Curfman McInnes    Input Parameters:
2786c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2787c7afd0dbSLois Curfman McInnes .  func - monitoring routine
2788b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
2789e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
2790b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
2791b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
27929b94acceSBarry Smith 
2793c7afd0dbSLois Curfman McInnes    Calling sequence of func:
2794a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
2795c7afd0dbSLois Curfman McInnes 
2796c7afd0dbSLois Curfman McInnes +    snes - the SNES context
2797c7afd0dbSLois Curfman McInnes .    its - iteration number
2798c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
279940a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
28009b94acceSBarry Smith 
28019665c990SLois Curfman McInnes    Options Database Keys:
2802a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
2803a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
2804a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
2805cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
2806c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
2807a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
2808c7afd0dbSLois Curfman McInnes                             does not cancel those set via
2809c7afd0dbSLois Curfman McInnes                             the options database.
28109665c990SLois Curfman McInnes 
2811639f9d9dSBarry Smith    Notes:
28126bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
2813a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
28146bc08f3fSLois Curfman McInnes    order in which they were set.
2815639f9d9dSBarry Smith 
2816025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
2817025f1a04SBarry Smith 
281836851e7fSLois Curfman McInnes    Level: intermediate
281936851e7fSLois Curfman McInnes 
28209b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
28219b94acceSBarry Smith 
2822a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
28239b94acceSBarry Smith @*/
2824c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
28259b94acceSBarry Smith {
2826b90d0a6eSBarry Smith   PetscInt       i;
2827649052a6SBarry Smith   PetscErrorCode ierr;
2828b90d0a6eSBarry Smith 
28293a40ed3dSBarry Smith   PetscFunctionBegin;
28300700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
283117186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
2832b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
2833649052a6SBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
2834649052a6SBarry Smith       if (monitordestroy) {
2835c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
2836649052a6SBarry Smith       }
2837b90d0a6eSBarry Smith       PetscFunctionReturn(0);
2838b90d0a6eSBarry Smith     }
2839b90d0a6eSBarry Smith   }
2840b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
2841b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
2842639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
28433a40ed3dSBarry Smith   PetscFunctionReturn(0);
28449b94acceSBarry Smith }
28459b94acceSBarry Smith 
28464a2ae208SSatish Balay #undef __FUNCT__
2847a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
28485cd90555SBarry Smith /*@C
2849a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
28505cd90555SBarry Smith 
28513f9fe445SBarry Smith    Logically Collective on SNES
2852c7afd0dbSLois Curfman McInnes 
28535cd90555SBarry Smith    Input Parameters:
28545cd90555SBarry Smith .  snes - the SNES context
28555cd90555SBarry Smith 
28561a480d89SAdministrator    Options Database Key:
2857a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
2858a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
2859c7afd0dbSLois Curfman McInnes     set via the options database
28605cd90555SBarry Smith 
28615cd90555SBarry Smith    Notes:
28625cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
28635cd90555SBarry Smith 
286436851e7fSLois Curfman McInnes    Level: intermediate
286536851e7fSLois Curfman McInnes 
28665cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
28675cd90555SBarry Smith 
2868a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
28695cd90555SBarry Smith @*/
28707087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
28715cd90555SBarry Smith {
2872d952e501SBarry Smith   PetscErrorCode ierr;
2873d952e501SBarry Smith   PetscInt       i;
2874d952e501SBarry Smith 
28755cd90555SBarry Smith   PetscFunctionBegin;
28760700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2877d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
2878d952e501SBarry Smith     if (snes->monitordestroy[i]) {
28793c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
2880d952e501SBarry Smith     }
2881d952e501SBarry Smith   }
28825cd90555SBarry Smith   snes->numbermonitors = 0;
28835cd90555SBarry Smith   PetscFunctionReturn(0);
28845cd90555SBarry Smith }
28855cd90555SBarry Smith 
28864a2ae208SSatish Balay #undef __FUNCT__
28874a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
28889b94acceSBarry Smith /*@C
28899b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
28909b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
28919b94acceSBarry Smith 
28923f9fe445SBarry Smith    Logically Collective on SNES
2893fee21e36SBarry Smith 
2894c7afd0dbSLois Curfman McInnes    Input Parameters:
2895c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2896c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
28977f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
28987f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
28999b94acceSBarry Smith 
2900c7afd0dbSLois Curfman McInnes    Calling sequence of func:
290106ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
2902c7afd0dbSLois Curfman McInnes 
2903c7afd0dbSLois Curfman McInnes +    snes - the SNES context
290406ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
2905c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
2906184914b5SBarry Smith .    reason - reason for convergence/divergence
2907c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
29084b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
29094b27c08aSLois Curfman McInnes -    f - 2-norm of function
29109b94acceSBarry Smith 
291136851e7fSLois Curfman McInnes    Level: advanced
291236851e7fSLois Curfman McInnes 
29139b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
29149b94acceSBarry Smith 
291585385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
29169b94acceSBarry Smith @*/
29177087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
29189b94acceSBarry Smith {
29197f7931b9SBarry Smith   PetscErrorCode ierr;
29207f7931b9SBarry Smith 
29213a40ed3dSBarry Smith   PetscFunctionBegin;
29220700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
292385385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
29247f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
29257f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
29267f7931b9SBarry Smith   }
292785385478SLisandro Dalcin   snes->ops->converged        = func;
29287f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
292985385478SLisandro Dalcin   snes->cnvP                  = cctx;
29303a40ed3dSBarry Smith   PetscFunctionReturn(0);
29319b94acceSBarry Smith }
29329b94acceSBarry Smith 
29334a2ae208SSatish Balay #undef __FUNCT__
29344a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
293552baeb72SSatish Balay /*@
2936184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
2937184914b5SBarry Smith 
2938184914b5SBarry Smith    Not Collective
2939184914b5SBarry Smith 
2940184914b5SBarry Smith    Input Parameter:
2941184914b5SBarry Smith .  snes - the SNES context
2942184914b5SBarry Smith 
2943184914b5SBarry Smith    Output Parameter:
29444d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
2945184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
2946184914b5SBarry Smith 
2947184914b5SBarry Smith    Level: intermediate
2948184914b5SBarry Smith 
2949184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
2950184914b5SBarry Smith 
2951184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
2952184914b5SBarry Smith 
295385385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
2954184914b5SBarry Smith @*/
29557087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
2956184914b5SBarry Smith {
2957184914b5SBarry Smith   PetscFunctionBegin;
29580700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
29594482741eSBarry Smith   PetscValidPointer(reason,2);
2960184914b5SBarry Smith   *reason = snes->reason;
2961184914b5SBarry Smith   PetscFunctionReturn(0);
2962184914b5SBarry Smith }
2963184914b5SBarry Smith 
29644a2ae208SSatish Balay #undef __FUNCT__
29654a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
2966c9005455SLois Curfman McInnes /*@
2967c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
2968c9005455SLois Curfman McInnes 
29693f9fe445SBarry Smith    Logically Collective on SNES
2970fee21e36SBarry Smith 
2971c7afd0dbSLois Curfman McInnes    Input Parameters:
2972c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
29738c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
2974cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
2975758f92a0SBarry Smith .  na  - size of a and its
297664731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
2977758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
2978c7afd0dbSLois Curfman McInnes 
2979308dcc3eSBarry Smith    Notes:
2980308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
2981308dcc3eSBarry Smith    default array of length 10000 is allocated.
2982308dcc3eSBarry Smith 
2983c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
2984c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
2985c9005455SLois Curfman McInnes    during the section of code that is being timed.
2986c9005455SLois Curfman McInnes 
298736851e7fSLois Curfman McInnes    Level: intermediate
298836851e7fSLois Curfman McInnes 
2989c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
2990758f92a0SBarry Smith 
299108405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
2992758f92a0SBarry Smith 
2993c9005455SLois Curfman McInnes @*/
29947087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
2995c9005455SLois Curfman McInnes {
2996308dcc3eSBarry Smith   PetscErrorCode ierr;
2997308dcc3eSBarry Smith 
29983a40ed3dSBarry Smith   PetscFunctionBegin;
29990700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
30004482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
3001a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
3002308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
3003308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
3004308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
3005308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
3006308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
3007308dcc3eSBarry Smith   }
3008c9005455SLois Curfman McInnes   snes->conv_hist       = a;
3009758f92a0SBarry Smith   snes->conv_hist_its   = its;
3010758f92a0SBarry Smith   snes->conv_hist_max   = na;
3011a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
3012758f92a0SBarry Smith   snes->conv_hist_reset = reset;
3013758f92a0SBarry Smith   PetscFunctionReturn(0);
3014758f92a0SBarry Smith }
3015758f92a0SBarry Smith 
3016308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3017c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
3018c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
3019308dcc3eSBarry Smith EXTERN_C_BEGIN
3020308dcc3eSBarry Smith #undef __FUNCT__
3021308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
3022308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
3023308dcc3eSBarry Smith {
3024308dcc3eSBarry Smith   mxArray        *mat;
3025308dcc3eSBarry Smith   PetscInt       i;
3026308dcc3eSBarry Smith   PetscReal      *ar;
3027308dcc3eSBarry Smith 
3028308dcc3eSBarry Smith   PetscFunctionBegin;
3029308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
3030308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
3031308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
3032308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
3033308dcc3eSBarry Smith   }
3034308dcc3eSBarry Smith   PetscFunctionReturn(mat);
3035308dcc3eSBarry Smith }
3036308dcc3eSBarry Smith EXTERN_C_END
3037308dcc3eSBarry Smith #endif
3038308dcc3eSBarry Smith 
3039308dcc3eSBarry Smith 
30404a2ae208SSatish Balay #undef __FUNCT__
30414a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
30420c4c9dddSBarry Smith /*@C
3043758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
3044758f92a0SBarry Smith 
30453f9fe445SBarry Smith    Not Collective
3046758f92a0SBarry Smith 
3047758f92a0SBarry Smith    Input Parameter:
3048758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
3049758f92a0SBarry Smith 
3050758f92a0SBarry Smith    Output Parameters:
3051758f92a0SBarry Smith .  a   - array to hold history
3052758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
3053758f92a0SBarry Smith          negative if not converged) for each solve.
3054758f92a0SBarry Smith -  na  - size of a and its
3055758f92a0SBarry Smith 
3056758f92a0SBarry Smith    Notes:
3057758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
3058758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
3059758f92a0SBarry Smith 
3060758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
3061758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
3062758f92a0SBarry Smith    during the section of code that is being timed.
3063758f92a0SBarry Smith 
3064758f92a0SBarry Smith    Level: intermediate
3065758f92a0SBarry Smith 
3066758f92a0SBarry Smith .keywords: SNES, get, convergence, history
3067758f92a0SBarry Smith 
3068758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
3069758f92a0SBarry Smith 
3070758f92a0SBarry Smith @*/
30717087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3072758f92a0SBarry Smith {
3073758f92a0SBarry Smith   PetscFunctionBegin;
30740700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3075758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
3076758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
3077758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
30783a40ed3dSBarry Smith   PetscFunctionReturn(0);
3079c9005455SLois Curfman McInnes }
3080c9005455SLois Curfman McInnes 
3081e74ef692SMatthew Knepley #undef __FUNCT__
3082e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
3083ac226902SBarry Smith /*@C
308476b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
3085eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
30867e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
308776b2cf59SMatthew Knepley 
30883f9fe445SBarry Smith   Logically Collective on SNES
308976b2cf59SMatthew Knepley 
309076b2cf59SMatthew Knepley   Input Parameters:
309176b2cf59SMatthew Knepley . snes - The nonlinear solver context
309276b2cf59SMatthew Knepley . func - The function
309376b2cf59SMatthew Knepley 
309476b2cf59SMatthew Knepley   Calling sequence of func:
3095b5d30489SBarry Smith . func (SNES snes, PetscInt step);
309676b2cf59SMatthew Knepley 
309776b2cf59SMatthew Knepley . step - The current step of the iteration
309876b2cf59SMatthew Knepley 
3099fe97e370SBarry Smith   Level: advanced
3100fe97e370SBarry Smith 
3101fe97e370SBarry 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()
3102fe97e370SBarry Smith         This is not used by most users.
310376b2cf59SMatthew Knepley 
310476b2cf59SMatthew Knepley .keywords: SNES, update
3105b5d30489SBarry Smith 
310685385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
310776b2cf59SMatthew Knepley @*/
31087087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
310976b2cf59SMatthew Knepley {
311076b2cf59SMatthew Knepley   PetscFunctionBegin;
31110700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
3112e7788613SBarry Smith   snes->ops->update = func;
311376b2cf59SMatthew Knepley   PetscFunctionReturn(0);
311476b2cf59SMatthew Knepley }
311576b2cf59SMatthew Knepley 
3116e74ef692SMatthew Knepley #undef __FUNCT__
3117e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
311876b2cf59SMatthew Knepley /*@
311976b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
312076b2cf59SMatthew Knepley 
312176b2cf59SMatthew Knepley   Not collective
312276b2cf59SMatthew Knepley 
312376b2cf59SMatthew Knepley   Input Parameters:
312476b2cf59SMatthew Knepley . snes - The nonlinear solver context
312576b2cf59SMatthew Knepley . step - The current step of the iteration
312676b2cf59SMatthew Knepley 
3127205452f4SMatthew Knepley   Level: intermediate
3128205452f4SMatthew Knepley 
312976b2cf59SMatthew Knepley .keywords: SNES, update
3130a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
313176b2cf59SMatthew Knepley @*/
31327087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
313376b2cf59SMatthew Knepley {
313476b2cf59SMatthew Knepley   PetscFunctionBegin;
313576b2cf59SMatthew Knepley   PetscFunctionReturn(0);
313676b2cf59SMatthew Knepley }
313776b2cf59SMatthew Knepley 
31384a2ae208SSatish Balay #undef __FUNCT__
31394a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
31409b94acceSBarry Smith /*
31419b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
31429b94acceSBarry Smith    positive parameter delta.
31439b94acceSBarry Smith 
31449b94acceSBarry Smith     Input Parameters:
3145c7afd0dbSLois Curfman McInnes +   snes - the SNES context
31469b94acceSBarry Smith .   y - approximate solution of linear system
31479b94acceSBarry Smith .   fnorm - 2-norm of current function
3148c7afd0dbSLois Curfman McInnes -   delta - trust region size
31499b94acceSBarry Smith 
31509b94acceSBarry Smith     Output Parameters:
3151c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
31529b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
31539b94acceSBarry Smith     region, and exceeds zero otherwise.
3154c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
31559b94acceSBarry Smith 
31569b94acceSBarry Smith     Note:
31574b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
31589b94acceSBarry Smith     is set to be the maximum allowable step size.
31599b94acceSBarry Smith 
31609b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
31619b94acceSBarry Smith */
3162dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
31639b94acceSBarry Smith {
3164064f8208SBarry Smith   PetscReal      nrm;
3165ea709b57SSatish Balay   PetscScalar    cnorm;
3166dfbe8321SBarry Smith   PetscErrorCode ierr;
31673a40ed3dSBarry Smith 
31683a40ed3dSBarry Smith   PetscFunctionBegin;
31690700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
31700700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3171c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
3172184914b5SBarry Smith 
3173064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
3174064f8208SBarry Smith   if (nrm > *delta) {
3175064f8208SBarry Smith      nrm = *delta/nrm;
3176064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
3177064f8208SBarry Smith      cnorm = nrm;
31782dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
31799b94acceSBarry Smith      *ynorm = *delta;
31809b94acceSBarry Smith   } else {
31819b94acceSBarry Smith      *gpnorm = 0.0;
3182064f8208SBarry Smith      *ynorm = nrm;
31839b94acceSBarry Smith   }
31843a40ed3dSBarry Smith   PetscFunctionReturn(0);
31859b94acceSBarry Smith }
31869b94acceSBarry Smith 
31874a2ae208SSatish Balay #undef __FUNCT__
31884a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
31896ce558aeSBarry Smith /*@C
3190f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
3191f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
31929b94acceSBarry Smith 
3193c7afd0dbSLois Curfman McInnes    Collective on SNES
3194c7afd0dbSLois Curfman McInnes 
3195b2002411SLois Curfman McInnes    Input Parameters:
3196c7afd0dbSLois Curfman McInnes +  snes - the SNES context
31973cebf274SJed Brown .  b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero.
319885385478SLisandro Dalcin -  x - the solution vector.
31999b94acceSBarry Smith 
3200b2002411SLois Curfman McInnes    Notes:
32018ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
32028ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
32038ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
32048ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
32058ddd3da0SLois Curfman McInnes 
320636851e7fSLois Curfman McInnes    Level: beginner
320736851e7fSLois Curfman McInnes 
32089b94acceSBarry Smith .keywords: SNES, nonlinear, solve
32099b94acceSBarry Smith 
3210c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
32119b94acceSBarry Smith @*/
32127087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
32139b94acceSBarry Smith {
3214dfbe8321SBarry Smith   PetscErrorCode ierr;
3215ace3abfcSBarry Smith   PetscBool      flg;
3216eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
3217eabae89aSBarry Smith   PetscViewer    viewer;
3218efd51863SBarry Smith   PetscInt       grid;
3219a69afd8bSBarry Smith   Vec            xcreated = PETSC_NULL;
3220*caa4e7f2SJed Brown   DM             dm;
3221052efed2SBarry Smith 
32223a40ed3dSBarry Smith   PetscFunctionBegin;
32230700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3224a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3225a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
32260700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
322785385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
322885385478SLisandro Dalcin 
3229*caa4e7f2SJed Brown   if (!x) {
3230*caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3231*caa4e7f2SJed Brown     ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr);
3232a69afd8bSBarry Smith     x    = xcreated;
3233a69afd8bSBarry Smith   }
3234a69afd8bSBarry Smith 
3235a8248277SBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);}
3236efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
3237efd51863SBarry Smith 
323885385478SLisandro Dalcin     /* set solution vector */
3239efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
32406bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
324185385478SLisandro Dalcin     snes->vec_sol = x;
3242*caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3243*caa4e7f2SJed Brown     ierr = DMSNESSetSolution(snes->dm,snes->vec_sol);CHKERRQ(ierr); /* Post the solution vector so that it can be restricted to coarse levels for KSP */
3244*caa4e7f2SJed Brown 
3245*caa4e7f2SJed Brown     /* set affine vector if provided */
324685385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
32476bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
324885385478SLisandro Dalcin     snes->vec_rhs = b;
324985385478SLisandro Dalcin 
325070e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
32513f149594SLisandro Dalcin 
32527eee914bSBarry Smith     if (!grid) {
32537eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
3254d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
3255dd568438SSatish Balay       } else if (snes->dm) {
3256dd568438SSatish Balay         PetscBool ig;
3257dd568438SSatish Balay         ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr);
3258dd568438SSatish Balay         if (ig) {
32597eee914bSBarry Smith           ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr);
32607eee914bSBarry Smith         }
3261d25893d9SBarry Smith       }
3262dd568438SSatish Balay     }
3263d25893d9SBarry Smith 
3264abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
326550ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
3266d5e45103SBarry Smith 
32673f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
32684936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
326985385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
32704936397dSBarry Smith     if (snes->domainerror){
32714936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
32724936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
32734936397dSBarry Smith     }
327417186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
3275*caa4e7f2SJed Brown     ierr = DMSNESSetSolution(snes->dm,PETSC_NULL);CHKERRQ(ierr); /* Un-post solution because inner contexts are done using it */
32763f149594SLisandro Dalcin 
32777adad957SLisandro Dalcin     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
3278eabae89aSBarry Smith     if (flg && !PetscPreLoadingOn) {
32797adad957SLisandro Dalcin       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
3280eabae89aSBarry Smith       ierr = SNESView(snes,viewer);CHKERRQ(ierr);
32816bf464f9SBarry Smith       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3282eabae89aSBarry Smith     }
3283eabae89aSBarry Smith 
328490d69ab7SBarry Smith     flg  = PETSC_FALSE;
3285acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
3286da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
32875968eb51SBarry Smith     if (snes->printreason) {
3288a8248277SBarry Smith       ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
32895968eb51SBarry Smith       if (snes->reason > 0) {
3290c7e7b494SJed Brown         ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
32915968eb51SBarry Smith       } else {
3292c7e7b494SJed Brown         ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
32935968eb51SBarry Smith       }
3294a8248277SBarry Smith       ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
32955968eb51SBarry Smith     }
32965968eb51SBarry Smith 
32978501fc72SJed Brown     flg = PETSC_FALSE;
32988501fc72SJed Brown     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
32998501fc72SJed Brown     if (flg) {
33008501fc72SJed Brown       PetscViewer viewer;
33018501fc72SJed Brown       ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
33028501fc72SJed Brown       ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr);
33038501fc72SJed Brown       ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr);
33048501fc72SJed Brown       ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr);
33058501fc72SJed Brown       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
33068501fc72SJed Brown     }
33078501fc72SJed Brown 
3308e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
3309efd51863SBarry Smith     if (grid <  snes->gridsequence) {
3310efd51863SBarry Smith       DM  fine;
3311efd51863SBarry Smith       Vec xnew;
3312efd51863SBarry Smith       Mat interp;
3313efd51863SBarry Smith 
3314efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
3315e727c939SJed Brown       ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
3316efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
3317efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
3318efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
3319efd51863SBarry Smith       x    = xnew;
3320efd51863SBarry Smith 
3321efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
3322efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
3323efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
3324a8248277SBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);
3325efd51863SBarry Smith     }
3326efd51863SBarry Smith   }
3327a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
33283a40ed3dSBarry Smith   PetscFunctionReturn(0);
33299b94acceSBarry Smith }
33309b94acceSBarry Smith 
33319b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
33329b94acceSBarry Smith 
33334a2ae208SSatish Balay #undef __FUNCT__
33344a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
333582bf6240SBarry Smith /*@C
33364b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
33379b94acceSBarry Smith 
3338fee21e36SBarry Smith    Collective on SNES
3339fee21e36SBarry Smith 
3340c7afd0dbSLois Curfman McInnes    Input Parameters:
3341c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3342454a90a3SBarry Smith -  type - a known method
3343c7afd0dbSLois Curfman McInnes 
3344c7afd0dbSLois Curfman McInnes    Options Database Key:
3345454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
3346c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
3347ae12b187SLois Curfman McInnes 
33489b94acceSBarry Smith    Notes:
3349e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
33504b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
3351c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
33524b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
3353c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
33549b94acceSBarry Smith 
3355ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
3356ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
3357ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
3358ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
3359ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
3360ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
3361ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
3362ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
3363ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
3364b0a32e0cSBarry Smith   appropriate method.
336536851e7fSLois Curfman McInnes 
336636851e7fSLois Curfman McInnes   Level: intermediate
3367a703fe33SLois Curfman McInnes 
3368454a90a3SBarry Smith .keywords: SNES, set, type
3369435da068SBarry Smith 
3370435da068SBarry Smith .seealso: SNESType, SNESCreate()
3371435da068SBarry Smith 
33729b94acceSBarry Smith @*/
33737087cfbeSBarry Smith PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
33749b94acceSBarry Smith {
3375dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
3376ace3abfcSBarry Smith   PetscBool      match;
33773a40ed3dSBarry Smith 
33783a40ed3dSBarry Smith   PetscFunctionBegin;
33790700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
33804482741eSBarry Smith   PetscValidCharPointer(type,2);
338182bf6240SBarry Smith 
33826831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
33830f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
338492ff6ae8SBarry Smith 
33854b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
3386e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
338775396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
3388b5c23020SJed Brown   if (snes->ops->destroy) {
3389b5c23020SJed Brown     ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
3390b5c23020SJed Brown     snes->ops->destroy = PETSC_NULL;
3391b5c23020SJed Brown   }
339275396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
339375396ef9SLisandro Dalcin   snes->ops->setup          = 0;
339475396ef9SLisandro Dalcin   snes->ops->solve          = 0;
339575396ef9SLisandro Dalcin   snes->ops->view           = 0;
339675396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
339775396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
339875396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
339975396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
3400454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
340103bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
34029fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
34039fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
34049fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
34059fb22e1aSBarry Smith   }
34069fb22e1aSBarry Smith #endif
34073a40ed3dSBarry Smith   PetscFunctionReturn(0);
34089b94acceSBarry Smith }
34099b94acceSBarry Smith 
3410a847f771SSatish Balay 
34119b94acceSBarry Smith /* --------------------------------------------------------------------- */
34124a2ae208SSatish Balay #undef __FUNCT__
34134a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
341452baeb72SSatish Balay /*@
34159b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
3416f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
34179b94acceSBarry Smith 
3418fee21e36SBarry Smith    Not Collective
3419fee21e36SBarry Smith 
342036851e7fSLois Curfman McInnes    Level: advanced
342136851e7fSLois Curfman McInnes 
34229b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
34239b94acceSBarry Smith 
34249b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
34259b94acceSBarry Smith @*/
34267087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
34279b94acceSBarry Smith {
3428dfbe8321SBarry Smith   PetscErrorCode ierr;
342982bf6240SBarry Smith 
34303a40ed3dSBarry Smith   PetscFunctionBegin;
34311441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
34324c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
34333a40ed3dSBarry Smith   PetscFunctionReturn(0);
34349b94acceSBarry Smith }
34359b94acceSBarry Smith 
34364a2ae208SSatish Balay #undef __FUNCT__
34374a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
34389b94acceSBarry Smith /*@C
34399a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
34409b94acceSBarry Smith 
3441c7afd0dbSLois Curfman McInnes    Not Collective
3442c7afd0dbSLois Curfman McInnes 
34439b94acceSBarry Smith    Input Parameter:
34444b0e389bSBarry Smith .  snes - nonlinear solver context
34459b94acceSBarry Smith 
34469b94acceSBarry Smith    Output Parameter:
34473a7fca6bSBarry Smith .  type - SNES method (a character string)
34489b94acceSBarry Smith 
344936851e7fSLois Curfman McInnes    Level: intermediate
345036851e7fSLois Curfman McInnes 
3451454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
34529b94acceSBarry Smith @*/
34537087cfbeSBarry Smith PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
34549b94acceSBarry Smith {
34553a40ed3dSBarry Smith   PetscFunctionBegin;
34560700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
34574482741eSBarry Smith   PetscValidPointer(type,2);
34587adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
34593a40ed3dSBarry Smith   PetscFunctionReturn(0);
34609b94acceSBarry Smith }
34619b94acceSBarry Smith 
34624a2ae208SSatish Balay #undef __FUNCT__
34634a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
346452baeb72SSatish Balay /*@
34659b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
3466c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
34679b94acceSBarry Smith 
3468c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3469c7afd0dbSLois Curfman McInnes 
34709b94acceSBarry Smith    Input Parameter:
34719b94acceSBarry Smith .  snes - the SNES context
34729b94acceSBarry Smith 
34739b94acceSBarry Smith    Output Parameter:
34749b94acceSBarry Smith .  x - the solution
34759b94acceSBarry Smith 
347670e92668SMatthew Knepley    Level: intermediate
347736851e7fSLois Curfman McInnes 
34789b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
34799b94acceSBarry Smith 
348085385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
34819b94acceSBarry Smith @*/
34827087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
34839b94acceSBarry Smith {
34843a40ed3dSBarry Smith   PetscFunctionBegin;
34850700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
34864482741eSBarry Smith   PetscValidPointer(x,2);
348785385478SLisandro Dalcin   *x = snes->vec_sol;
348870e92668SMatthew Knepley   PetscFunctionReturn(0);
348970e92668SMatthew Knepley }
349070e92668SMatthew Knepley 
349170e92668SMatthew Knepley #undef __FUNCT__
34924a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
349352baeb72SSatish Balay /*@
34949b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
34959b94acceSBarry Smith    stored.
34969b94acceSBarry Smith 
3497c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3498c7afd0dbSLois Curfman McInnes 
34999b94acceSBarry Smith    Input Parameter:
35009b94acceSBarry Smith .  snes - the SNES context
35019b94acceSBarry Smith 
35029b94acceSBarry Smith    Output Parameter:
35039b94acceSBarry Smith .  x - the solution update
35049b94acceSBarry Smith 
350536851e7fSLois Curfman McInnes    Level: advanced
350636851e7fSLois Curfman McInnes 
35079b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
35089b94acceSBarry Smith 
350985385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
35109b94acceSBarry Smith @*/
35117087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
35129b94acceSBarry Smith {
35133a40ed3dSBarry Smith   PetscFunctionBegin;
35140700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35154482741eSBarry Smith   PetscValidPointer(x,2);
351685385478SLisandro Dalcin   *x = snes->vec_sol_update;
35173a40ed3dSBarry Smith   PetscFunctionReturn(0);
35189b94acceSBarry Smith }
35199b94acceSBarry Smith 
35204a2ae208SSatish Balay #undef __FUNCT__
35214a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
35229b94acceSBarry Smith /*@C
35233638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
35249b94acceSBarry Smith 
3525a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
3526c7afd0dbSLois Curfman McInnes 
35279b94acceSBarry Smith    Input Parameter:
35289b94acceSBarry Smith .  snes - the SNES context
35299b94acceSBarry Smith 
35309b94acceSBarry Smith    Output Parameter:
35317bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
353270e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
353370e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
35349b94acceSBarry Smith 
353536851e7fSLois Curfman McInnes    Level: advanced
353636851e7fSLois Curfman McInnes 
3537a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
35389b94acceSBarry Smith 
35394b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
35409b94acceSBarry Smith @*/
35417087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
35429b94acceSBarry Smith {
3543a63bb30eSJed Brown   PetscErrorCode ierr;
35446cab3a1bSJed Brown   DM             dm;
3545a63bb30eSJed Brown 
35463a40ed3dSBarry Smith   PetscFunctionBegin;
35470700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3548a63bb30eSJed Brown   if (r) {
3549a63bb30eSJed Brown     if (!snes->vec_func) {
3550a63bb30eSJed Brown       if (snes->vec_rhs) {
3551a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
3552a63bb30eSJed Brown       } else if (snes->vec_sol) {
3553a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
3554a63bb30eSJed Brown       } else if (snes->dm) {
3555a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
3556a63bb30eSJed Brown       }
3557a63bb30eSJed Brown     }
3558a63bb30eSJed Brown     *r = snes->vec_func;
3559a63bb30eSJed Brown   }
35606cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
35616cab3a1bSJed Brown   ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr);
35623a40ed3dSBarry Smith   PetscFunctionReturn(0);
35639b94acceSBarry Smith }
35649b94acceSBarry Smith 
3565c79ef259SPeter Brune /*@C
3566c79ef259SPeter Brune    SNESGetGS - Returns the GS function and context.
3567c79ef259SPeter Brune 
3568c79ef259SPeter Brune    Input Parameter:
3569c79ef259SPeter Brune .  snes - the SNES context
3570c79ef259SPeter Brune 
3571c79ef259SPeter Brune    Output Parameter:
3572c79ef259SPeter Brune +  gsfunc - the function (or PETSC_NULL)
3573c79ef259SPeter Brune -  ctx    - the function context (or PETSC_NULL)
3574c79ef259SPeter Brune 
3575c79ef259SPeter Brune    Level: advanced
3576c79ef259SPeter Brune 
3577c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
3578c79ef259SPeter Brune 
3579c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction()
3580c79ef259SPeter Brune @*/
3581c79ef259SPeter Brune 
35824a2ae208SSatish Balay #undef __FUNCT__
3583646217ecSPeter Brune #define __FUNCT__ "SNESGetGS"
3584646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx)
3585646217ecSPeter Brune {
35866cab3a1bSJed Brown   PetscErrorCode ierr;
35876cab3a1bSJed Brown   DM             dm;
35886cab3a1bSJed Brown 
3589646217ecSPeter Brune   PetscFunctionBegin;
3590646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35916cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
35926cab3a1bSJed Brown   ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr);
3593646217ecSPeter Brune   PetscFunctionReturn(0);
3594646217ecSPeter Brune }
3595646217ecSPeter Brune 
35964a2ae208SSatish Balay #undef __FUNCT__
35974a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
35983c7409f5SSatish Balay /*@C
35993c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
3600d850072dSLois Curfman McInnes    SNES options in the database.
36013c7409f5SSatish Balay 
36023f9fe445SBarry Smith    Logically Collective on SNES
3603fee21e36SBarry Smith 
3604c7afd0dbSLois Curfman McInnes    Input Parameter:
3605c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3606c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3607c7afd0dbSLois Curfman McInnes 
3608d850072dSLois Curfman McInnes    Notes:
3609a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3610c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3611d850072dSLois Curfman McInnes 
361236851e7fSLois Curfman McInnes    Level: advanced
361336851e7fSLois Curfman McInnes 
36143c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
3615a86d99e1SLois Curfman McInnes 
3616a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
36173c7409f5SSatish Balay @*/
36187087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
36193c7409f5SSatish Balay {
3620dfbe8321SBarry Smith   PetscErrorCode ierr;
36213c7409f5SSatish Balay 
36223a40ed3dSBarry Smith   PetscFunctionBegin;
36230700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3624639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
36251cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
362694b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
36273a40ed3dSBarry Smith   PetscFunctionReturn(0);
36283c7409f5SSatish Balay }
36293c7409f5SSatish Balay 
36304a2ae208SSatish Balay #undef __FUNCT__
36314a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
36323c7409f5SSatish Balay /*@C
3633f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
3634d850072dSLois Curfman McInnes    SNES options in the database.
36353c7409f5SSatish Balay 
36363f9fe445SBarry Smith    Logically Collective on SNES
3637fee21e36SBarry Smith 
3638c7afd0dbSLois Curfman McInnes    Input Parameters:
3639c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3640c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3641c7afd0dbSLois Curfman McInnes 
3642d850072dSLois Curfman McInnes    Notes:
3643a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3644c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3645d850072dSLois Curfman McInnes 
364636851e7fSLois Curfman McInnes    Level: advanced
364736851e7fSLois Curfman McInnes 
36483c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
3649a86d99e1SLois Curfman McInnes 
3650a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
36513c7409f5SSatish Balay @*/
36527087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
36533c7409f5SSatish Balay {
3654dfbe8321SBarry Smith   PetscErrorCode ierr;
36553c7409f5SSatish Balay 
36563a40ed3dSBarry Smith   PetscFunctionBegin;
36570700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3658639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
36591cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
366094b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
36613a40ed3dSBarry Smith   PetscFunctionReturn(0);
36623c7409f5SSatish Balay }
36633c7409f5SSatish Balay 
36644a2ae208SSatish Balay #undef __FUNCT__
36654a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
36669ab63eb5SSatish Balay /*@C
36673c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
36683c7409f5SSatish Balay    SNES options in the database.
36693c7409f5SSatish Balay 
3670c7afd0dbSLois Curfman McInnes    Not Collective
3671c7afd0dbSLois Curfman McInnes 
36723c7409f5SSatish Balay    Input Parameter:
36733c7409f5SSatish Balay .  snes - the SNES context
36743c7409f5SSatish Balay 
36753c7409f5SSatish Balay    Output Parameter:
36763c7409f5SSatish Balay .  prefix - pointer to the prefix string used
36773c7409f5SSatish Balay 
36784ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
36799ab63eb5SSatish Balay    sufficient length to hold the prefix.
36809ab63eb5SSatish Balay 
368136851e7fSLois Curfman McInnes    Level: advanced
368236851e7fSLois Curfman McInnes 
36833c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
3684a86d99e1SLois Curfman McInnes 
3685a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
36863c7409f5SSatish Balay @*/
36877087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
36883c7409f5SSatish Balay {
3689dfbe8321SBarry Smith   PetscErrorCode ierr;
36903c7409f5SSatish Balay 
36913a40ed3dSBarry Smith   PetscFunctionBegin;
36920700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3693639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
36943a40ed3dSBarry Smith   PetscFunctionReturn(0);
36953c7409f5SSatish Balay }
36963c7409f5SSatish Balay 
3697b2002411SLois Curfman McInnes 
36984a2ae208SSatish Balay #undef __FUNCT__
36994a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
37003cea93caSBarry Smith /*@C
37013cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
37023cea93caSBarry Smith 
37037f6c08e0SMatthew Knepley   Level: advanced
37043cea93caSBarry Smith @*/
37057087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
3706b2002411SLois Curfman McInnes {
3707e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
3708dfbe8321SBarry Smith   PetscErrorCode ierr;
3709b2002411SLois Curfman McInnes 
3710b2002411SLois Curfman McInnes   PetscFunctionBegin;
3711b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3712c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3713b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
3714b2002411SLois Curfman McInnes }
3715da9b6338SBarry Smith 
3716da9b6338SBarry Smith #undef __FUNCT__
3717da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
37187087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
3719da9b6338SBarry Smith {
3720dfbe8321SBarry Smith   PetscErrorCode ierr;
372177431f27SBarry Smith   PetscInt       N,i,j;
3722da9b6338SBarry Smith   Vec            u,uh,fh;
3723da9b6338SBarry Smith   PetscScalar    value;
3724da9b6338SBarry Smith   PetscReal      norm;
3725da9b6338SBarry Smith 
3726da9b6338SBarry Smith   PetscFunctionBegin;
3727da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
3728da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
3729da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
3730da9b6338SBarry Smith 
3731da9b6338SBarry Smith   /* currently only works for sequential */
3732da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
3733da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
3734da9b6338SBarry Smith   for (i=0; i<N; i++) {
3735da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
373677431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
3737da9b6338SBarry Smith     for (j=-10; j<11; j++) {
3738ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
3739da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
37403ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
3741da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
374277431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
3743da9b6338SBarry Smith       value = -value;
3744da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
3745da9b6338SBarry Smith     }
3746da9b6338SBarry Smith   }
37476bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
37486bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
3749da9b6338SBarry Smith   PetscFunctionReturn(0);
3750da9b6338SBarry Smith }
375171f87433Sdalcinl 
375271f87433Sdalcinl #undef __FUNCT__
3753fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
375471f87433Sdalcinl /*@
3755fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
375671f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
375771f87433Sdalcinl    Newton method.
375871f87433Sdalcinl 
37593f9fe445SBarry Smith    Logically Collective on SNES
376071f87433Sdalcinl 
376171f87433Sdalcinl    Input Parameters:
376271f87433Sdalcinl +  snes - SNES context
376371f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
376471f87433Sdalcinl 
376564ba62caSBarry Smith     Options Database:
376664ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
376764ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
376864ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
376964ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
377064ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
377164ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
377264ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
377364ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
377464ba62caSBarry Smith 
377571f87433Sdalcinl    Notes:
377671f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
377771f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
377871f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
377971f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
378071f87433Sdalcinl    solver.
378171f87433Sdalcinl 
378271f87433Sdalcinl    Level: advanced
378371f87433Sdalcinl 
378471f87433Sdalcinl    Reference:
378571f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
378671f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
378771f87433Sdalcinl 
378871f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
378971f87433Sdalcinl 
3790fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
379171f87433Sdalcinl @*/
37927087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
379371f87433Sdalcinl {
379471f87433Sdalcinl   PetscFunctionBegin;
37950700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3796acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
379771f87433Sdalcinl   snes->ksp_ewconv = flag;
379871f87433Sdalcinl   PetscFunctionReturn(0);
379971f87433Sdalcinl }
380071f87433Sdalcinl 
380171f87433Sdalcinl #undef __FUNCT__
3802fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
380371f87433Sdalcinl /*@
3804fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
380571f87433Sdalcinl    for computing relative tolerance for linear solvers within an
380671f87433Sdalcinl    inexact Newton method.
380771f87433Sdalcinl 
380871f87433Sdalcinl    Not Collective
380971f87433Sdalcinl 
381071f87433Sdalcinl    Input Parameter:
381171f87433Sdalcinl .  snes - SNES context
381271f87433Sdalcinl 
381371f87433Sdalcinl    Output Parameter:
381471f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
381571f87433Sdalcinl 
381671f87433Sdalcinl    Notes:
381771f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
381871f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
381971f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
382071f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
382171f87433Sdalcinl    solver.
382271f87433Sdalcinl 
382371f87433Sdalcinl    Level: advanced
382471f87433Sdalcinl 
382571f87433Sdalcinl    Reference:
382671f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
382771f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
382871f87433Sdalcinl 
382971f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
383071f87433Sdalcinl 
3831fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
383271f87433Sdalcinl @*/
38337087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
383471f87433Sdalcinl {
383571f87433Sdalcinl   PetscFunctionBegin;
38360700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
383771f87433Sdalcinl   PetscValidPointer(flag,2);
383871f87433Sdalcinl   *flag = snes->ksp_ewconv;
383971f87433Sdalcinl   PetscFunctionReturn(0);
384071f87433Sdalcinl }
384171f87433Sdalcinl 
384271f87433Sdalcinl #undef __FUNCT__
3843fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
384471f87433Sdalcinl /*@
3845fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
384671f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
384771f87433Sdalcinl    Newton method.
384871f87433Sdalcinl 
38493f9fe445SBarry Smith    Logically Collective on SNES
385071f87433Sdalcinl 
385171f87433Sdalcinl    Input Parameters:
385271f87433Sdalcinl +    snes - SNES context
385371f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
385471f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
385571f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
385671f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
385771f87433Sdalcinl              (0 <= gamma2 <= 1)
385871f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
385971f87433Sdalcinl .    alpha2 - power for safeguard
386071f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
386171f87433Sdalcinl 
386271f87433Sdalcinl    Note:
386371f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
386471f87433Sdalcinl 
386571f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
386671f87433Sdalcinl 
386771f87433Sdalcinl    Level: advanced
386871f87433Sdalcinl 
386971f87433Sdalcinl    Reference:
387071f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
387171f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
387271f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
387371f87433Sdalcinl 
387471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
387571f87433Sdalcinl 
3876fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
387771f87433Sdalcinl @*/
38787087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
387971f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
388071f87433Sdalcinl {
3881fa9f3622SBarry Smith   SNESKSPEW *kctx;
388271f87433Sdalcinl   PetscFunctionBegin;
38830700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3884fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3885e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
3886c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
3887c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
3888c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
3889c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
3890c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
3891c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
3892c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
389371f87433Sdalcinl 
389471f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
389571f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
389671f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
389771f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
389871f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
389971f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
390071f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
390171f87433Sdalcinl 
390271f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
3903e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
390471f87433Sdalcinl   }
390571f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
3906e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
390771f87433Sdalcinl   }
390871f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
3909e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
391071f87433Sdalcinl   }
391171f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
3912e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
391371f87433Sdalcinl   }
391471f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
3915e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
391671f87433Sdalcinl   }
391771f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
3918e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
391971f87433Sdalcinl   }
392071f87433Sdalcinl   PetscFunctionReturn(0);
392171f87433Sdalcinl }
392271f87433Sdalcinl 
392371f87433Sdalcinl #undef __FUNCT__
3924fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
392571f87433Sdalcinl /*@
3926fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
392771f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
392871f87433Sdalcinl    Newton method.
392971f87433Sdalcinl 
393071f87433Sdalcinl    Not Collective
393171f87433Sdalcinl 
393271f87433Sdalcinl    Input Parameters:
393371f87433Sdalcinl      snes - SNES context
393471f87433Sdalcinl 
393571f87433Sdalcinl    Output Parameters:
393671f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
393771f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
393871f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
393971f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
394071f87433Sdalcinl              (0 <= gamma2 <= 1)
394171f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
394271f87433Sdalcinl .    alpha2 - power for safeguard
394371f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
394471f87433Sdalcinl 
394571f87433Sdalcinl    Level: advanced
394671f87433Sdalcinl 
394771f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
394871f87433Sdalcinl 
3949fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
395071f87433Sdalcinl @*/
39517087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
395271f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
395371f87433Sdalcinl {
3954fa9f3622SBarry Smith   SNESKSPEW *kctx;
395571f87433Sdalcinl   PetscFunctionBegin;
39560700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3957fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3958e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
395971f87433Sdalcinl   if(version)   *version   = kctx->version;
396071f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
396171f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
396271f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
396371f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
396471f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
396571f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
396671f87433Sdalcinl   PetscFunctionReturn(0);
396771f87433Sdalcinl }
396871f87433Sdalcinl 
396971f87433Sdalcinl #undef __FUNCT__
3970fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
3971fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
397271f87433Sdalcinl {
397371f87433Sdalcinl   PetscErrorCode ierr;
3974fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
397571f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
397671f87433Sdalcinl 
397771f87433Sdalcinl   PetscFunctionBegin;
3978e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
397971f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
398071f87433Sdalcinl     rtol = kctx->rtol_0;
398171f87433Sdalcinl   } else {
398271f87433Sdalcinl     if (kctx->version == 1) {
398371f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
398471f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
398571f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
398671f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
398771f87433Sdalcinl     } else if (kctx->version == 2) {
398871f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
398971f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
399071f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
399171f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
399271f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
399371f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
399471f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
399571f87433Sdalcinl       stol = PetscMax(rtol,stol);
399671f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
399771f87433Sdalcinl       /* safeguard: avoid oversolving */
399871f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
399971f87433Sdalcinl       stol = PetscMax(rtol,stol);
400071f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
4001e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
400271f87433Sdalcinl   }
400371f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
400471f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
400571f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
400671f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
400771f87433Sdalcinl   PetscFunctionReturn(0);
400871f87433Sdalcinl }
400971f87433Sdalcinl 
401071f87433Sdalcinl #undef __FUNCT__
4011fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
4012fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
401371f87433Sdalcinl {
401471f87433Sdalcinl   PetscErrorCode ierr;
4015fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
401671f87433Sdalcinl   PCSide         pcside;
401771f87433Sdalcinl   Vec            lres;
401871f87433Sdalcinl 
401971f87433Sdalcinl   PetscFunctionBegin;
4020e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
402171f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
402271f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
402371f87433Sdalcinl   if (kctx->version == 1) {
4024b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
402571f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
402671f87433Sdalcinl       /* KSP residual is true linear residual */
402771f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
402871f87433Sdalcinl     } else {
402971f87433Sdalcinl       /* KSP residual is preconditioned residual */
403071f87433Sdalcinl       /* compute true linear residual norm */
403171f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
403271f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
403371f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
403471f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
40356bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
403671f87433Sdalcinl     }
403771f87433Sdalcinl   }
403871f87433Sdalcinl   PetscFunctionReturn(0);
403971f87433Sdalcinl }
404071f87433Sdalcinl 
404171f87433Sdalcinl #undef __FUNCT__
404271f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
404371f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
404471f87433Sdalcinl {
404571f87433Sdalcinl   PetscErrorCode ierr;
404671f87433Sdalcinl 
404771f87433Sdalcinl   PetscFunctionBegin;
4048fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
404971f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
4050fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
405171f87433Sdalcinl   PetscFunctionReturn(0);
405271f87433Sdalcinl }
40536c699258SBarry Smith 
40546c699258SBarry Smith #undef __FUNCT__
40556c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
40566c699258SBarry Smith /*@
40576c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
40586c699258SBarry Smith 
40593f9fe445SBarry Smith    Logically Collective on SNES
40606c699258SBarry Smith 
40616c699258SBarry Smith    Input Parameters:
40626c699258SBarry Smith +  snes - the preconditioner context
40636c699258SBarry Smith -  dm - the dm
40646c699258SBarry Smith 
40656c699258SBarry Smith    Level: intermediate
40666c699258SBarry Smith 
40676c699258SBarry Smith 
40686c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
40696c699258SBarry Smith @*/
40707087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
40716c699258SBarry Smith {
40726c699258SBarry Smith   PetscErrorCode ierr;
4073345fed2cSBarry Smith   KSP            ksp;
40746cab3a1bSJed Brown   SNESDM         sdm;
40756c699258SBarry Smith 
40766c699258SBarry Smith   PetscFunctionBegin;
40770700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4078d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
40796cab3a1bSJed Brown   if (snes->dm) {               /* Move the SNESDM context over to the new DM unless the new DM already has one */
40806cab3a1bSJed Brown     PetscContainer oldcontainer,container;
40816cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr);
40826cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr);
40836cab3a1bSJed Brown     if (oldcontainer && !container) {
40846cab3a1bSJed Brown       ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr);
40856cab3a1bSJed Brown       ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr);
40866cab3a1bSJed Brown       if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */
40876cab3a1bSJed Brown         sdm->originaldm = dm;
40886cab3a1bSJed Brown       }
40896cab3a1bSJed Brown     }
40906bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
40916cab3a1bSJed Brown   }
40926c699258SBarry Smith   snes->dm = dm;
4093345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4094345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4095f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
40962c155ee1SBarry Smith   if (snes->pc) {
40972c155ee1SBarry Smith     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
40982c155ee1SBarry Smith   }
40996c699258SBarry Smith   PetscFunctionReturn(0);
41006c699258SBarry Smith }
41016c699258SBarry Smith 
41026c699258SBarry Smith #undef __FUNCT__
41036c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
41046c699258SBarry Smith /*@
41056c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
41066c699258SBarry Smith 
41073f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
41086c699258SBarry Smith 
41096c699258SBarry Smith    Input Parameter:
41106c699258SBarry Smith . snes - the preconditioner context
41116c699258SBarry Smith 
41126c699258SBarry Smith    Output Parameter:
41136c699258SBarry Smith .  dm - the dm
41146c699258SBarry Smith 
41156c699258SBarry Smith    Level: intermediate
41166c699258SBarry Smith 
41176c699258SBarry Smith 
41186c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
41196c699258SBarry Smith @*/
41207087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
41216c699258SBarry Smith {
41226cab3a1bSJed Brown   PetscErrorCode ierr;
41236cab3a1bSJed Brown 
41246c699258SBarry Smith   PetscFunctionBegin;
41250700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
41266cab3a1bSJed Brown   if (!snes->dm) {
41276cab3a1bSJed Brown     ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr);
41286cab3a1bSJed Brown   }
41296c699258SBarry Smith   *dm = snes->dm;
41306c699258SBarry Smith   PetscFunctionReturn(0);
41316c699258SBarry Smith }
41320807856dSBarry Smith 
413331823bd8SMatthew G Knepley #undef __FUNCT__
413431823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
413531823bd8SMatthew G Knepley /*@
4136fd4b34e9SJed Brown   SNESSetPC - Sets the nonlinear preconditioner to be used.
413731823bd8SMatthew G Knepley 
413831823bd8SMatthew G Knepley   Collective on SNES
413931823bd8SMatthew G Knepley 
414031823bd8SMatthew G Knepley   Input Parameters:
414131823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
414231823bd8SMatthew G Knepley - pc   - the preconditioner object
414331823bd8SMatthew G Knepley 
414431823bd8SMatthew G Knepley   Notes:
414531823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
414631823bd8SMatthew G Knepley   to configure it using the API).
414731823bd8SMatthew G Knepley 
414831823bd8SMatthew G Knepley   Level: developer
414931823bd8SMatthew G Knepley 
415031823bd8SMatthew G Knepley .keywords: SNES, set, precondition
415131823bd8SMatthew G Knepley .seealso: SNESGetPC()
415231823bd8SMatthew G Knepley @*/
415331823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
415431823bd8SMatthew G Knepley {
415531823bd8SMatthew G Knepley   PetscErrorCode ierr;
415631823bd8SMatthew G Knepley 
415731823bd8SMatthew G Knepley   PetscFunctionBegin;
415831823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
415931823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
416031823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
416131823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4162bf11d3b6SBarry Smith   ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr);
416331823bd8SMatthew G Knepley   snes->pc = pc;
416431823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
416531823bd8SMatthew G Knepley   PetscFunctionReturn(0);
416631823bd8SMatthew G Knepley }
416731823bd8SMatthew G Knepley 
416831823bd8SMatthew G Knepley #undef __FUNCT__
416931823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
417031823bd8SMatthew G Knepley /*@
4171fd4b34e9SJed Brown   SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().
417231823bd8SMatthew G Knepley 
417331823bd8SMatthew G Knepley   Not Collective
417431823bd8SMatthew G Knepley 
417531823bd8SMatthew G Knepley   Input Parameter:
417631823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
417731823bd8SMatthew G Knepley 
417831823bd8SMatthew G Knepley   Output Parameter:
417931823bd8SMatthew G Knepley . pc - preconditioner context
418031823bd8SMatthew G Knepley 
418131823bd8SMatthew G Knepley   Level: developer
418231823bd8SMatthew G Knepley 
418331823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
418431823bd8SMatthew G Knepley .seealso: SNESSetPC()
418531823bd8SMatthew G Knepley @*/
418631823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
418731823bd8SMatthew G Knepley {
418831823bd8SMatthew G Knepley   PetscErrorCode ierr;
418931823bd8SMatthew G Knepley 
419031823bd8SMatthew G Knepley   PetscFunctionBegin;
419131823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
419231823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
419331823bd8SMatthew G Knepley   if (!snes->pc) {
419431823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr);
41954a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr);
419631823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
419731823bd8SMatthew G Knepley   }
419831823bd8SMatthew G Knepley   *pc = snes->pc;
419931823bd8SMatthew G Knepley   PetscFunctionReturn(0);
420031823bd8SMatthew G Knepley }
420131823bd8SMatthew G Knepley 
42029e764e56SPeter Brune #undef __FUNCT__
4203f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch"
42049e764e56SPeter Brune /*@
4205f1c6b773SPeter Brune   SNESSetSNESLineSearch - Sets the linesearch.
42069e764e56SPeter Brune 
42079e764e56SPeter Brune   Collective on SNES
42089e764e56SPeter Brune 
42099e764e56SPeter Brune   Input Parameters:
42109e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
42119e764e56SPeter Brune - linesearch   - the linesearch object
42129e764e56SPeter Brune 
42139e764e56SPeter Brune   Notes:
4214f1c6b773SPeter Brune   Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example,
42159e764e56SPeter Brune   to configure it using the API).
42169e764e56SPeter Brune 
42179e764e56SPeter Brune   Level: developer
42189e764e56SPeter Brune 
42199e764e56SPeter Brune .keywords: SNES, set, linesearch
4220f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch()
42219e764e56SPeter Brune @*/
4222f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch)
42239e764e56SPeter Brune {
42249e764e56SPeter Brune   PetscErrorCode ierr;
42259e764e56SPeter Brune 
42269e764e56SPeter Brune   PetscFunctionBegin;
42279e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4228f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
42299e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
42309e764e56SPeter Brune   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
4231f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
42329e764e56SPeter Brune   snes->linesearch = linesearch;
42339e764e56SPeter Brune   ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
42349e764e56SPeter Brune   PetscFunctionReturn(0);
42359e764e56SPeter Brune }
42369e764e56SPeter Brune 
42379e764e56SPeter Brune #undef __FUNCT__
4238f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch"
4239ea5d4fccSPeter Brune /*@C
4240f1c6b773SPeter Brune   SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch().
42419e764e56SPeter Brune 
42429e764e56SPeter Brune   Not Collective
42439e764e56SPeter Brune 
42449e764e56SPeter Brune   Input Parameter:
42459e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
42469e764e56SPeter Brune 
42479e764e56SPeter Brune   Output Parameter:
42489e764e56SPeter Brune . linesearch - linesearch context
42499e764e56SPeter Brune 
42509e764e56SPeter Brune   Level: developer
42519e764e56SPeter Brune 
42529e764e56SPeter Brune .keywords: SNES, get, linesearch
4253f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch()
42549e764e56SPeter Brune @*/
4255f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch)
42569e764e56SPeter Brune {
42579e764e56SPeter Brune   PetscErrorCode ierr;
42589e764e56SPeter Brune   const char     *optionsprefix;
42599e764e56SPeter Brune 
42609e764e56SPeter Brune   PetscFunctionBegin;
42619e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
42629e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
42639e764e56SPeter Brune   if (!snes->linesearch) {
42649e764e56SPeter Brune     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
4265f1c6b773SPeter Brune     ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr);
4266f1c6b773SPeter Brune     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
42679e764e56SPeter Brune     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
42689e764e56SPeter Brune     ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
42699e764e56SPeter Brune   }
42709e764e56SPeter Brune   *linesearch = snes->linesearch;
42719e764e56SPeter Brune   PetscFunctionReturn(0);
42729e764e56SPeter Brune }
42739e764e56SPeter Brune 
427469b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4275c6db04a5SJed Brown #include <mex.h>
427669b4f73cSBarry Smith 
42778f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
42788f6e6473SBarry Smith 
42790807856dSBarry Smith #undef __FUNCT__
42800807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
42810807856dSBarry Smith /*
42820807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
42830807856dSBarry Smith                          SNESSetFunctionMatlab().
42840807856dSBarry Smith 
42850807856dSBarry Smith    Collective on SNES
42860807856dSBarry Smith 
42870807856dSBarry Smith    Input Parameters:
42880807856dSBarry Smith +  snes - the SNES context
42890807856dSBarry Smith -  x - input vector
42900807856dSBarry Smith 
42910807856dSBarry Smith    Output Parameter:
42920807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
42930807856dSBarry Smith 
42940807856dSBarry Smith    Notes:
42950807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
42960807856dSBarry Smith    implementations, so most users would not generally call this routine
42970807856dSBarry Smith    themselves.
42980807856dSBarry Smith 
42990807856dSBarry Smith    Level: developer
43000807856dSBarry Smith 
43010807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
43020807856dSBarry Smith 
43030807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
430461b2408cSBarry Smith */
43057087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
43060807856dSBarry Smith {
4307e650e774SBarry Smith   PetscErrorCode    ierr;
43088f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
43098f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
43108f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
431191621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
4312e650e774SBarry Smith 
43130807856dSBarry Smith   PetscFunctionBegin;
43140807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
43150807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
43160807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
43170807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
43180807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
43190807856dSBarry Smith 
43200807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
4321e650e774SBarry Smith 
432291621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4323e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4324e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
432591621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
432691621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
432791621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
43288f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
43298f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
4330b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
4331e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4332e650e774SBarry Smith   mxDestroyArray(prhs[0]);
4333e650e774SBarry Smith   mxDestroyArray(prhs[1]);
4334e650e774SBarry Smith   mxDestroyArray(prhs[2]);
43358f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
4336e650e774SBarry Smith   mxDestroyArray(plhs[0]);
43370807856dSBarry Smith   PetscFunctionReturn(0);
43380807856dSBarry Smith }
43390807856dSBarry Smith 
43400807856dSBarry Smith 
43410807856dSBarry Smith #undef __FUNCT__
43420807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
434361b2408cSBarry Smith /*
43440807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
43450807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4346e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
43470807856dSBarry Smith 
43480807856dSBarry Smith    Logically Collective on SNES
43490807856dSBarry Smith 
43500807856dSBarry Smith    Input Parameters:
43510807856dSBarry Smith +  snes - the SNES context
43520807856dSBarry Smith .  r - vector to store function value
43530807856dSBarry Smith -  func - function evaluation routine
43540807856dSBarry Smith 
43550807856dSBarry Smith    Calling sequence of func:
435661b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
43570807856dSBarry Smith 
43580807856dSBarry Smith 
43590807856dSBarry Smith    Notes:
43600807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
43610807856dSBarry Smith $      f'(x) x = -f(x),
43620807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
43630807856dSBarry Smith 
43640807856dSBarry Smith    Level: beginner
43650807856dSBarry Smith 
43660807856dSBarry Smith .keywords: SNES, nonlinear, set, function
43670807856dSBarry Smith 
43680807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
436961b2408cSBarry Smith */
43707087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
43710807856dSBarry Smith {
43720807856dSBarry Smith   PetscErrorCode    ierr;
43738f6e6473SBarry Smith   SNESMatlabContext *sctx;
43740807856dSBarry Smith 
43750807856dSBarry Smith   PetscFunctionBegin;
43768f6e6473SBarry Smith   /* currently sctx is memory bleed */
43778f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
43788f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
43798f6e6473SBarry Smith   /*
43808f6e6473SBarry Smith      This should work, but it doesn't
43818f6e6473SBarry Smith   sctx->ctx = ctx;
43828f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
43838f6e6473SBarry Smith   */
43848f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
43858f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
43860807856dSBarry Smith   PetscFunctionReturn(0);
43870807856dSBarry Smith }
438869b4f73cSBarry Smith 
438961b2408cSBarry Smith #undef __FUNCT__
439061b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
439161b2408cSBarry Smith /*
439261b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
439361b2408cSBarry Smith                          SNESSetJacobianMatlab().
439461b2408cSBarry Smith 
439561b2408cSBarry Smith    Collective on SNES
439661b2408cSBarry Smith 
439761b2408cSBarry Smith    Input Parameters:
439861b2408cSBarry Smith +  snes - the SNES context
439961b2408cSBarry Smith .  x - input vector
440061b2408cSBarry Smith .  A, B - the matrices
440161b2408cSBarry Smith -  ctx - user context
440261b2408cSBarry Smith 
440361b2408cSBarry Smith    Output Parameter:
440461b2408cSBarry Smith .  flag - structure of the matrix
440561b2408cSBarry Smith 
440661b2408cSBarry Smith    Level: developer
440761b2408cSBarry Smith 
440861b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
440961b2408cSBarry Smith 
441061b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
441161b2408cSBarry Smith @*/
44127087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
441361b2408cSBarry Smith {
441461b2408cSBarry Smith   PetscErrorCode    ierr;
441561b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
441661b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
441761b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
441861b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
441961b2408cSBarry Smith 
442061b2408cSBarry Smith   PetscFunctionBegin;
442161b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
442261b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
442361b2408cSBarry Smith 
442461b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
442561b2408cSBarry Smith 
442661b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
442761b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
442861b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
442961b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
443061b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
443161b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
443261b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
443361b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
443461b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
443561b2408cSBarry Smith   prhs[5] =  sctx->ctx;
4436b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
443761b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
443861b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
443961b2408cSBarry Smith   mxDestroyArray(prhs[0]);
444061b2408cSBarry Smith   mxDestroyArray(prhs[1]);
444161b2408cSBarry Smith   mxDestroyArray(prhs[2]);
444261b2408cSBarry Smith   mxDestroyArray(prhs[3]);
444361b2408cSBarry Smith   mxDestroyArray(prhs[4]);
444461b2408cSBarry Smith   mxDestroyArray(plhs[0]);
444561b2408cSBarry Smith   mxDestroyArray(plhs[1]);
444661b2408cSBarry Smith   PetscFunctionReturn(0);
444761b2408cSBarry Smith }
444861b2408cSBarry Smith 
444961b2408cSBarry Smith 
445061b2408cSBarry Smith #undef __FUNCT__
445161b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
445261b2408cSBarry Smith /*
445361b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
445461b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4455e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
445661b2408cSBarry Smith 
445761b2408cSBarry Smith    Logically Collective on SNES
445861b2408cSBarry Smith 
445961b2408cSBarry Smith    Input Parameters:
446061b2408cSBarry Smith +  snes - the SNES context
446161b2408cSBarry Smith .  A,B - Jacobian matrices
446261b2408cSBarry Smith .  func - function evaluation routine
446361b2408cSBarry Smith -  ctx - user context
446461b2408cSBarry Smith 
446561b2408cSBarry Smith    Calling sequence of func:
446661b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
446761b2408cSBarry Smith 
446861b2408cSBarry Smith 
446961b2408cSBarry Smith    Level: developer
447061b2408cSBarry Smith 
447161b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
447261b2408cSBarry Smith 
447361b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
447461b2408cSBarry Smith */
44757087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
447661b2408cSBarry Smith {
447761b2408cSBarry Smith   PetscErrorCode    ierr;
447861b2408cSBarry Smith   SNESMatlabContext *sctx;
447961b2408cSBarry Smith 
448061b2408cSBarry Smith   PetscFunctionBegin;
448161b2408cSBarry Smith   /* currently sctx is memory bleed */
448261b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
448361b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
448461b2408cSBarry Smith   /*
448561b2408cSBarry Smith      This should work, but it doesn't
448661b2408cSBarry Smith   sctx->ctx = ctx;
448761b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
448861b2408cSBarry Smith   */
448961b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
449061b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
449161b2408cSBarry Smith   PetscFunctionReturn(0);
449261b2408cSBarry Smith }
449369b4f73cSBarry Smith 
4494f9eb7ae2SShri Abhyankar #undef __FUNCT__
4495f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
4496f9eb7ae2SShri Abhyankar /*
4497f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
4498f9eb7ae2SShri Abhyankar 
4499f9eb7ae2SShri Abhyankar    Collective on SNES
4500f9eb7ae2SShri Abhyankar 
4501f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
4502f9eb7ae2SShri Abhyankar @*/
45037087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
4504f9eb7ae2SShri Abhyankar {
4505f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
450648f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
4507f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
4508f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
4509f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
4510f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
4511f9eb7ae2SShri Abhyankar 
4512f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4513f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4514f9eb7ae2SShri Abhyankar 
4515f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4516f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4517f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
4518f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
4519f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
4520f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
4521f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
4522f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
4523f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
4524f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4525f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
4526f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
4527f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
4528f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
4529f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
4530f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
4531f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4532f9eb7ae2SShri Abhyankar }
4533f9eb7ae2SShri Abhyankar 
4534f9eb7ae2SShri Abhyankar 
4535f9eb7ae2SShri Abhyankar #undef __FUNCT__
4536f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
4537f9eb7ae2SShri Abhyankar /*
4538e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
4539f9eb7ae2SShri Abhyankar 
4540f9eb7ae2SShri Abhyankar    Level: developer
4541f9eb7ae2SShri Abhyankar 
4542f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
4543f9eb7ae2SShri Abhyankar 
4544f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
4545f9eb7ae2SShri Abhyankar */
45467087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
4547f9eb7ae2SShri Abhyankar {
4548f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
4549f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
4550f9eb7ae2SShri Abhyankar 
4551f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4552f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
4553f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
4554f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4555f9eb7ae2SShri Abhyankar   /*
4556f9eb7ae2SShri Abhyankar      This should work, but it doesn't
4557f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
4558f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
4559f9eb7ae2SShri Abhyankar   */
4560f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
4561f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4562f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4563f9eb7ae2SShri Abhyankar }
4564f9eb7ae2SShri Abhyankar 
456569b4f73cSBarry Smith #endif
4566