xref: /petsc/src/snes/interface/snes.c (revision 140836e41be6fc4e8e9f21a5573348b58ed12f73)
19b94acceSBarry Smith 
2b45d2f2cSJed Brown #include <petsc-private/snesimpl.h>      /*I "petscsnes.h"  I*/
36cab3a1bSJed Brown #include <petscdmshell.h>                /*I "petscdmshell.h" I*/
4a64e098fSPeter Brune #include <petscsys.h>                    /*I "petscsys.h" I*/
59b94acceSBarry Smith 
6ace3abfcSBarry Smith PetscBool  SNESRegisterAllCalled = PETSC_FALSE;
78ba1e511SMatthew Knepley PetscFList SNESList              = PETSC_NULL;
88ba1e511SMatthew Knepley 
98ba1e511SMatthew Knepley /* Logging support */
107087cfbeSBarry Smith PetscClassId  SNES_CLASSID;
11f1c6b773SPeter Brune PetscLogEvent  SNES_Solve, SNES_FunctionEval, SNES_JacobianEval, SNES_GSEval;
12a09944afSBarry Smith 
13a09944afSBarry Smith #undef __FUNCT__
14e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged"
15e113a28aSBarry Smith /*@
16e113a28aSBarry Smith    SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged.
17e113a28aSBarry Smith 
183f9fe445SBarry Smith    Logically Collective on SNES
19e113a28aSBarry Smith 
20e113a28aSBarry Smith    Input Parameters:
21e113a28aSBarry Smith +  snes - iterative context obtained from SNESCreate()
22e113a28aSBarry Smith -  flg - PETSC_TRUE indicates you want the error generated
23e113a28aSBarry Smith 
24e113a28aSBarry Smith    Options database keys:
25e113a28aSBarry Smith .  -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false)
26e113a28aSBarry Smith 
27e113a28aSBarry Smith    Level: intermediate
28e113a28aSBarry Smith 
29e113a28aSBarry Smith    Notes:
30e113a28aSBarry Smith     Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve()
31e113a28aSBarry Smith     to determine if it has converged.
32e113a28aSBarry Smith 
33e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
34e113a28aSBarry Smith 
35e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
36e113a28aSBarry Smith @*/
377087cfbeSBarry Smith PetscErrorCode  SNESSetErrorIfNotConverged(SNES snes,PetscBool  flg)
38e113a28aSBarry Smith {
39e113a28aSBarry Smith   PetscFunctionBegin;
40e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
41acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flg,2);
42e113a28aSBarry Smith   snes->errorifnotconverged = flg;
43dd568438SSatish Balay 
44e113a28aSBarry Smith   PetscFunctionReturn(0);
45e113a28aSBarry Smith }
46e113a28aSBarry Smith 
47e113a28aSBarry Smith #undef __FUNCT__
48e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged"
49e113a28aSBarry Smith /*@
50e113a28aSBarry Smith    SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge?
51e113a28aSBarry Smith 
52e113a28aSBarry Smith    Not Collective
53e113a28aSBarry Smith 
54e113a28aSBarry Smith    Input Parameter:
55e113a28aSBarry Smith .  snes - iterative context obtained from SNESCreate()
56e113a28aSBarry Smith 
57e113a28aSBarry Smith    Output Parameter:
58e113a28aSBarry Smith .  flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE
59e113a28aSBarry Smith 
60e113a28aSBarry Smith    Level: intermediate
61e113a28aSBarry Smith 
62e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
63e113a28aSBarry Smith 
64e113a28aSBarry Smith .seealso:  SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
65e113a28aSBarry Smith @*/
667087cfbeSBarry Smith PetscErrorCode  SNESGetErrorIfNotConverged(SNES snes,PetscBool  *flag)
67e113a28aSBarry Smith {
68e113a28aSBarry Smith   PetscFunctionBegin;
69e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
70e113a28aSBarry Smith   PetscValidPointer(flag,2);
71e113a28aSBarry Smith   *flag = snes->errorifnotconverged;
72e113a28aSBarry Smith   PetscFunctionReturn(0);
73e113a28aSBarry Smith }
74e113a28aSBarry Smith 
75e113a28aSBarry Smith #undef __FUNCT__
764936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError"
77e725d27bSBarry Smith /*@
784936397dSBarry Smith    SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not
794936397dSBarry Smith      in the functions domain. For example, negative pressure.
804936397dSBarry Smith 
813f9fe445SBarry Smith    Logically Collective on SNES
824936397dSBarry Smith 
834936397dSBarry Smith    Input Parameters:
846a388c36SPeter Brune .  snes - the SNES context
854936397dSBarry Smith 
8628529972SSatish Balay    Level: advanced
874936397dSBarry Smith 
884936397dSBarry Smith .keywords: SNES, view
894936397dSBarry Smith 
904936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction()
914936397dSBarry Smith @*/
927087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionDomainError(SNES snes)
934936397dSBarry Smith {
944936397dSBarry Smith   PetscFunctionBegin;
950700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
964936397dSBarry Smith   snes->domainerror = PETSC_TRUE;
974936397dSBarry Smith   PetscFunctionReturn(0);
984936397dSBarry Smith }
994936397dSBarry Smith 
1006a388c36SPeter Brune 
1016a388c36SPeter Brune #undef __FUNCT__
1026a388c36SPeter Brune #define __FUNCT__ "SNESGetFunctionDomainError"
1036a388c36SPeter Brune /*@
104c77b2880SPeter Brune    SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction;
1056a388c36SPeter Brune 
1066a388c36SPeter Brune    Logically Collective on SNES
1076a388c36SPeter Brune 
1086a388c36SPeter Brune    Input Parameters:
1096a388c36SPeter Brune .  snes - the SNES context
1106a388c36SPeter Brune 
1116a388c36SPeter Brune    Output Parameters:
1126a388c36SPeter Brune .  domainerror Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise.
1136a388c36SPeter Brune 
1146a388c36SPeter Brune    Level: advanced
1156a388c36SPeter Brune 
1166a388c36SPeter Brune .keywords: SNES, view
1176a388c36SPeter Brune 
1186a388c36SPeter Brune .seealso: SNESSetFunctionDomainError, SNESComputeFunction()
1196a388c36SPeter Brune @*/
1206a388c36SPeter Brune PetscErrorCode  SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror)
1216a388c36SPeter Brune {
1226a388c36SPeter Brune   PetscFunctionBegin;
1236a388c36SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1246a388c36SPeter Brune   PetscValidPointer(domainerror, 2);
1256a388c36SPeter Brune   *domainerror = snes->domainerror;
1266a388c36SPeter Brune   PetscFunctionReturn(0);
1276a388c36SPeter Brune }
1286a388c36SPeter Brune 
1296a388c36SPeter Brune 
1304936397dSBarry Smith #undef __FUNCT__
1314a2ae208SSatish Balay #define __FUNCT__ "SNESView"
1327e2c5f70SBarry Smith /*@C
1339b94acceSBarry Smith    SNESView - Prints the SNES data structure.
1349b94acceSBarry Smith 
1354c49b128SBarry Smith    Collective on SNES
136fee21e36SBarry Smith 
137c7afd0dbSLois Curfman McInnes    Input Parameters:
138c7afd0dbSLois Curfman McInnes +  SNES - the SNES context
139c7afd0dbSLois Curfman McInnes -  viewer - visualization context
140c7afd0dbSLois Curfman McInnes 
1419b94acceSBarry Smith    Options Database Key:
142c8a8ba5cSLois Curfman McInnes .  -snes_view - Calls SNESView() at end of SNESSolve()
1439b94acceSBarry Smith 
1449b94acceSBarry Smith    Notes:
1459b94acceSBarry Smith    The available visualization contexts include
146b0a32e0cSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
147b0a32e0cSBarry Smith -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
148c8a8ba5cSLois Curfman McInnes          output where only the first processor opens
149c8a8ba5cSLois Curfman McInnes          the file.  All other processors send their
150c8a8ba5cSLois Curfman McInnes          data to the first processor to print.
1519b94acceSBarry Smith 
1523e081fefSLois Curfman McInnes    The user can open an alternative visualization context with
153b0a32e0cSBarry Smith    PetscViewerASCIIOpen() - output to a specified file.
1549b94acceSBarry Smith 
15536851e7fSLois Curfman McInnes    Level: beginner
15636851e7fSLois Curfman McInnes 
1579b94acceSBarry Smith .keywords: SNES, view
1589b94acceSBarry Smith 
159b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen()
1609b94acceSBarry Smith @*/
1617087cfbeSBarry Smith PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
1629b94acceSBarry Smith {
163fa9f3622SBarry Smith   SNESKSPEW           *kctx;
164dfbe8321SBarry Smith   PetscErrorCode      ierr;
16594b7f48cSBarry Smith   KSP                 ksp;
1667f1410a3SPeter Brune   SNESLineSearch      linesearch;
167ace3abfcSBarry Smith   PetscBool           iascii,isstring;
1689b94acceSBarry Smith 
1693a40ed3dSBarry Smith   PetscFunctionBegin;
1700700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1713050cee2SBarry Smith   if (!viewer) {
1727adad957SLisandro Dalcin     ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
1733050cee2SBarry Smith   }
1740700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
175c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,viewer,2);
17674679c65SBarry Smith 
177251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
178251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
17932077d6dSBarry Smith   if (iascii) {
180317d6ea6SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr);
181e7788613SBarry Smith     if (snes->ops->view) {
182b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
183e7788613SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
184b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1850ef38995SBarry Smith     }
18677431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr);
187a83599f4SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%G, absolute=%G, solution=%G\n",
188c60f73f4SPeter Brune                  snes->rtol,snes->abstol,snes->stol);CHKERRQ(ierr);
18977431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr);
19077431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr);
19117fe4bdfSPeter Brune     if (snes->gridsequence) {
19217fe4bdfSPeter Brune       ierr = PetscViewerASCIIPrintf(viewer,"  total number of grid sequence refinements=%D\n",snes->gridsequence);CHKERRQ(ierr);
19317fe4bdfSPeter Brune     }
1949b94acceSBarry Smith     if (snes->ksp_ewconv) {
195fa9f3622SBarry Smith       kctx = (SNESKSPEW *)snes->kspconvctx;
1969b94acceSBarry Smith       if (kctx) {
19777431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr);
198a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr);
199a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr);
2009b94acceSBarry Smith       }
2019b94acceSBarry Smith     }
202eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
203eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");CHKERRQ(ierr);
204eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
205eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr);
206eb1f6c34SBarry Smith     }
207eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
208eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");CHKERRQ(ierr);
209eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
21042f4f86dSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr);
211eb1f6c34SBarry Smith     }
2120f5bd95cSBarry Smith   } else if (isstring) {
213317d6ea6SBarry Smith     const char *type;
214454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
215b0a32e0cSBarry Smith     ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr);
21619bcc07fSBarry Smith   }
21742f4f86dSBarry Smith   if (snes->pc && snes->usespc) {
2184a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2194a0c5b0cSMatthew G Knepley     ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr);
2204a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2214a0c5b0cSMatthew G Knepley   }
2222c155ee1SBarry Smith   if (snes->usesksp) {
2232c155ee1SBarry Smith     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
224b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
22594b7f48cSBarry Smith     ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
226b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2272c155ee1SBarry Smith   }
2287f1410a3SPeter Brune   if (snes->linesearch) {
2297f1410a3SPeter Brune     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2307f1410a3SPeter Brune     ierr = SNESGetSNESLineSearch(snes, &linesearch);CHKERRQ(ierr);
2317f1410a3SPeter Brune     ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr);
2327f1410a3SPeter Brune     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2337f1410a3SPeter Brune   }
2343a40ed3dSBarry Smith   PetscFunctionReturn(0);
2359b94acceSBarry Smith }
2369b94acceSBarry Smith 
23776b2cf59SMatthew Knepley /*
23876b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
23976b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
24076b2cf59SMatthew Knepley */
24176b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
242a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
2436849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
24476b2cf59SMatthew Knepley 
245e74ef692SMatthew Knepley #undef __FUNCT__
246e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker"
247ac226902SBarry Smith /*@C
24876b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
24976b2cf59SMatthew Knepley 
25076b2cf59SMatthew Knepley   Not Collective
25176b2cf59SMatthew Knepley 
25276b2cf59SMatthew Knepley   Input Parameter:
25376b2cf59SMatthew Knepley . snescheck - function that checks for options
25476b2cf59SMatthew Knepley 
25576b2cf59SMatthew Knepley   Level: developer
25676b2cf59SMatthew Knepley 
25776b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
25876b2cf59SMatthew Knepley @*/
2597087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
26076b2cf59SMatthew Knepley {
26176b2cf59SMatthew Knepley   PetscFunctionBegin;
26276b2cf59SMatthew Knepley   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
263e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
26476b2cf59SMatthew Knepley   }
26576b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
26676b2cf59SMatthew Knepley   PetscFunctionReturn(0);
26776b2cf59SMatthew Knepley }
26876b2cf59SMatthew Knepley 
2697087cfbeSBarry Smith extern PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
270aa3661deSLisandro Dalcin 
271aa3661deSLisandro Dalcin #undef __FUNCT__
272aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private"
273ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool  hasOperator, PetscInt version)
274aa3661deSLisandro Dalcin {
275aa3661deSLisandro Dalcin   Mat            J;
276aa3661deSLisandro Dalcin   KSP            ksp;
277aa3661deSLisandro Dalcin   PC             pc;
278ace3abfcSBarry Smith   PetscBool      match;
279aa3661deSLisandro Dalcin   PetscErrorCode ierr;
280aa3661deSLisandro Dalcin 
281aa3661deSLisandro Dalcin   PetscFunctionBegin;
2820700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
283aa3661deSLisandro Dalcin 
28498613b67SLisandro Dalcin   if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
28598613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
28698613b67SLisandro Dalcin     ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr);
28798613b67SLisandro Dalcin   }
28898613b67SLisandro Dalcin 
289aa3661deSLisandro Dalcin   if (version == 1) {
290aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
29198613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
2929c6ac3b3SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
293aa3661deSLisandro Dalcin   } else if (version == 2) {
294e32f2f54SBarry Smith     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
29582a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
296aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
297aa3661deSLisandro Dalcin #else
298e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
299aa3661deSLisandro Dalcin #endif
300a8248277SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
301aa3661deSLisandro Dalcin 
302aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
303d3462f78SMatthew Knepley   if (hasOperator) {
304aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
305aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
306aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
307aa3661deSLisandro Dalcin   } else {
308aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
309aa3661deSLisandro Dalcin        provided preconditioner matrix with the default matrix free version. */
3106cab3a1bSJed Brown     void *functx;
3116cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
3126cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
313aa3661deSLisandro Dalcin     /* Force no preconditioner */
314aa3661deSLisandro Dalcin     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
315aa3661deSLisandro Dalcin     ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
316251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
317aa3661deSLisandro Dalcin     if (!match) {
318aa3661deSLisandro Dalcin       ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
319aa3661deSLisandro Dalcin       ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
320aa3661deSLisandro Dalcin     }
321aa3661deSLisandro Dalcin   }
3226bf464f9SBarry Smith   ierr = MatDestroy(&J);CHKERRQ(ierr);
323aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
324aa3661deSLisandro Dalcin }
325aa3661deSLisandro Dalcin 
3264a2ae208SSatish Balay #undef __FUNCT__
327dfe15315SJed Brown #define __FUNCT__ "DMRestrictHook_SNESVecSol"
328dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx)
329dfe15315SJed Brown {
330dfe15315SJed Brown   SNES snes = (SNES)ctx;
331dfe15315SJed Brown   PetscErrorCode ierr;
332dfe15315SJed Brown   Vec Xfine,Xfine_named = PETSC_NULL,Xcoarse;
333dfe15315SJed Brown 
334dfe15315SJed Brown   PetscFunctionBegin;
335dfe15315SJed Brown   if (dmfine == snes->dm) Xfine = snes->vec_sol;
336dfe15315SJed Brown   else {
337dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);
338dfe15315SJed Brown     Xfine = Xfine_named;
339dfe15315SJed Brown   }
340dfe15315SJed Brown   ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
341dfe15315SJed Brown   ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr);
342dfe15315SJed Brown   ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr);
343dfe15315SJed Brown   ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
344dfe15315SJed Brown   if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);}
345dfe15315SJed Brown   PetscFunctionReturn(0);
346dfe15315SJed Brown }
347dfe15315SJed Brown 
348dfe15315SJed Brown #undef __FUNCT__
349caa4e7f2SJed Brown #define __FUNCT__ "KSPComputeOperators_SNES"
350a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can
351a6950cb2SJed Brown  * safely call SNESGetDM() in their residual evaluation routine. */
352caa4e7f2SJed Brown static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,MatStructure *mstruct,void *ctx)
353caa4e7f2SJed Brown {
354caa4e7f2SJed Brown   SNES snes = (SNES)ctx;
355caa4e7f2SJed Brown   PetscErrorCode ierr;
356caa4e7f2SJed Brown   Mat Asave = A,Bsave = B;
357dfe15315SJed Brown   Vec X,Xnamed = PETSC_NULL;
358dfe15315SJed Brown   DM dmsave;
359caa4e7f2SJed Brown 
360caa4e7f2SJed Brown   PetscFunctionBegin;
361dfe15315SJed Brown   dmsave = snes->dm;
362dfe15315SJed Brown   ierr = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr);
363dfe15315SJed Brown   if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */
364dfe15315SJed Brown   else {                                     /* We are on a coarser level, this vec was initialized using a DM restrict hook */
365dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
366dfe15315SJed Brown     X = Xnamed;
367dfe15315SJed Brown   }
368dfe15315SJed Brown   ierr = SNESComputeJacobian(snes,X,&A,&B,mstruct);CHKERRQ(ierr);
369caa4e7f2SJed Brown   if (A != Asave || B != Bsave) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_SUP,"No support for changing matrices at this time");
370dfe15315SJed Brown   if (Xnamed) {
371dfe15315SJed Brown     ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
372dfe15315SJed Brown   }
373dfe15315SJed Brown   snes->dm = dmsave;
374caa4e7f2SJed Brown   PetscFunctionReturn(0);
375caa4e7f2SJed Brown }
376caa4e7f2SJed Brown 
377caa4e7f2SJed Brown #undef __FUNCT__
3786cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices"
3796cab3a1bSJed Brown /*@
3806cab3a1bSJed Brown    SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX()
3816cab3a1bSJed Brown 
3826cab3a1bSJed Brown    Collective
3836cab3a1bSJed Brown 
3846cab3a1bSJed Brown    Input Arguments:
3856cab3a1bSJed Brown .  snes - snes to configure
3866cab3a1bSJed Brown 
3876cab3a1bSJed Brown    Level: developer
3886cab3a1bSJed Brown 
3896cab3a1bSJed Brown .seealso: SNESSetUp()
3906cab3a1bSJed Brown @*/
3916cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes)
3926cab3a1bSJed Brown {
3936cab3a1bSJed Brown   PetscErrorCode ierr;
3946cab3a1bSJed Brown   DM             dm;
3956cab3a1bSJed Brown   SNESDM         sdm;
3966cab3a1bSJed Brown 
3976cab3a1bSJed Brown   PetscFunctionBegin;
3986cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3996cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
400caa4e7f2SJed Brown   if (!sdm->computejacobian) {
40117842b4fSJed Brown     SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_PLIB,"SNESDM not improperly configured");
4026cab3a1bSJed Brown   } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) {
4036cab3a1bSJed Brown     Mat J;
4046cab3a1bSJed Brown     void *functx;
4056cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4066cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4076cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4086cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
4096cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
4106cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
411caa4e7f2SJed Brown   } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
4126cab3a1bSJed Brown     Mat J,B;
4136cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4146cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4156cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4166cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
41706f20277SJed Brown     /* sdm->computejacobian was already set to reach here */
41806f20277SJed Brown     ierr = SNESSetJacobian(snes,J,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
4196cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
4206cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
421caa4e7f2SJed Brown   } else if (!snes->jacobian_pre) {
4226cab3a1bSJed Brown     Mat J,B;
4236cab3a1bSJed Brown     J = snes->jacobian;
4246cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4256cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
4266cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
4276cab3a1bSJed Brown   }
428caa4e7f2SJed Brown   {
42960a3618bSJed Brown     PetscBool flg = PETSC_FALSE;
430caa4e7f2SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_kspcompute",&flg,PETSC_NULL);CHKERRQ(ierr);
431caa4e7f2SJed Brown     if (flg) {                  /* Plan to transition to this model */
432caa4e7f2SJed Brown       KSP ksp;
433caa4e7f2SJed Brown       ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
434caa4e7f2SJed Brown       ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr);
435dfe15315SJed Brown       ierr = DMCoarsenHookAdd(snes->dm,PETSC_NULL,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr);
436caa4e7f2SJed Brown     }
437caa4e7f2SJed Brown   }
4386cab3a1bSJed Brown   PetscFunctionReturn(0);
4396cab3a1bSJed Brown }
4406cab3a1bSJed Brown 
4416cab3a1bSJed Brown #undef __FUNCT__
4424a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions"
4439b94acceSBarry Smith /*@
44494b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
4459b94acceSBarry Smith 
446c7afd0dbSLois Curfman McInnes    Collective on SNES
447c7afd0dbSLois Curfman McInnes 
4489b94acceSBarry Smith    Input Parameter:
4499b94acceSBarry Smith .  snes - the SNES context
4509b94acceSBarry Smith 
45136851e7fSLois Curfman McInnes    Options Database Keys:
452ea630c6eSPeter Brune +  -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas
45382738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
45482738288SBarry Smith                 of the change in the solution between steps
45570441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
456b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
457b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
458b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
4594839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
460ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
461a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
462e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
463b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
4642492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
46582738288SBarry Smith                                solver; hence iterations will continue until max_it
4661fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
46782738288SBarry Smith                                of convergence test
468e8105e01SRichard Katz .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
469e8105e01SRichard Katz                                        filename given prints to stdout
470a6570f20SBarry Smith .  -snes_monitor_solution - plots solution at each iteration
471a6570f20SBarry Smith .  -snes_monitor_residual - plots residual (not its norm) at each iteration
472a6570f20SBarry Smith .  -snes_monitor_solution_update - plots update to solution at each iteration
473a6570f20SBarry Smith .  -snes_monitor_draw - plots residual norm at each iteration
474e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
4755968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
476fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
47782738288SBarry Smith 
47882738288SBarry Smith     Options Database for Eisenstat-Walker method:
479fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
4804b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
48136851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
48236851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
48336851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
48436851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
48536851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
48636851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
48782738288SBarry Smith 
48811ca99fdSLois Curfman McInnes    Notes:
48911ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
4900598bfebSBarry Smith    the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>.
49183e2fdc7SBarry Smith 
49236851e7fSLois Curfman McInnes    Level: beginner
49336851e7fSLois Curfman McInnes 
4949b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
4959b94acceSBarry Smith 
49669ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
4979b94acceSBarry Smith @*/
4987087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
4999b94acceSBarry Smith {
500872b6db9SPeter Brune   PetscBool               flg,mf,mf_operator,pcset;
501efd51863SBarry Smith   PetscInt                i,indx,lag,mf_version,grids;
502aa3661deSLisandro Dalcin   MatStructure            matflag;
50385385478SLisandro Dalcin   const char              *deft = SNESLS;
50485385478SLisandro Dalcin   const char              *convtests[] = {"default","skip"};
50585385478SLisandro Dalcin   SNESKSPEW               *kctx = NULL;
506e8105e01SRichard Katz   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
507649052a6SBarry Smith   PetscViewer             monviewer;
50885385478SLisandro Dalcin   PetscErrorCode          ierr;
509a64e098fSPeter Brune   const char              *optionsprefix;
5109b94acceSBarry Smith 
5113a40ed3dSBarry Smith   PetscFunctionBegin;
5120700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
513ca161407SBarry Smith 
514186905e3SBarry Smith   if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
5153194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
5167adad957SLisandro Dalcin     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
517b0a32e0cSBarry Smith     ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
518d64ed03dSBarry Smith     if (flg) {
519186905e3SBarry Smith       ierr = SNESSetType(snes,type);CHKERRQ(ierr);
5207adad957SLisandro Dalcin     } else if (!((PetscObject)snes)->type_name) {
521186905e3SBarry Smith       ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
522d64ed03dSBarry Smith     }
52390d69ab7SBarry Smith     /* not used here, but called so will go into help messaage */
524909c8a9fSBarry Smith     ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr);
52593c39befSBarry Smith 
526c60f73f4SPeter Brune     ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);CHKERRQ(ierr);
52757034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr);
528186905e3SBarry Smith 
52957034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr);
530b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr);
531b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr);
53224254dc1SJed Brown     ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr);
533ddf469c8SBarry Smith     ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr);
534acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr);
53585385478SLisandro Dalcin 
536a8054027SBarry Smith     ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
537a8054027SBarry Smith     if (flg) {
538a8054027SBarry Smith       ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
539a8054027SBarry Smith     }
540e35cf81dSBarry Smith     ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
541e35cf81dSBarry Smith     if (flg) {
542e35cf81dSBarry Smith       ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
543e35cf81dSBarry Smith     }
544efd51863SBarry Smith     ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
545efd51863SBarry Smith     if (flg) {
546efd51863SBarry Smith       ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
547efd51863SBarry Smith     }
548a8054027SBarry Smith 
54985385478SLisandro Dalcin     ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
55085385478SLisandro Dalcin     if (flg) {
55185385478SLisandro Dalcin       switch (indx) {
5527f7931b9SBarry Smith       case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break;
5537f7931b9SBarry Smith       case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);    break;
55485385478SLisandro Dalcin       }
55585385478SLisandro Dalcin     }
55685385478SLisandro Dalcin 
557acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr);
558186905e3SBarry Smith 
559fdacfa88SPeter Brune     ierr = PetscOptionsEList("-snes_norm_type","SNES Norm type","SNESSetNormType",SNESNormTypes,5,"function",&indx,&flg);CHKERRQ(ierr);
560fdacfa88SPeter Brune     if (flg) { ierr = SNESSetNormType(snes,(SNESNormType)indx);CHKERRQ(ierr); }
561fdacfa88SPeter Brune 
56285385478SLisandro Dalcin     kctx = (SNESKSPEW *)snes->kspconvctx;
56385385478SLisandro Dalcin 
564acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr);
565186905e3SBarry Smith 
566fa9f3622SBarry Smith     ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr);
567fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr);
568fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr);
569fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr);
570fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr);
571fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr);
572fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr);
573186905e3SBarry Smith 
57490d69ab7SBarry Smith     flg  = PETSC_FALSE;
575acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
576a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
577eabae89aSBarry Smith 
578a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
579e8105e01SRichard Katz     if (flg) {
580649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
581649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
582e8105e01SRichard Katz     }
583eabae89aSBarry Smith 
584b271bb04SBarry Smith     ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
585b271bb04SBarry Smith     if (flg) {
586b271bb04SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr);
587b271bb04SBarry Smith     }
588b271bb04SBarry Smith 
589a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
590eabae89aSBarry Smith     if (flg) {
591649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
592f1bef1bcSMatthew Knepley       ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr);
593e8105e01SRichard Katz     }
594eabae89aSBarry Smith 
595a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
596eabae89aSBarry Smith     if (flg) {
597649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
598649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
599eabae89aSBarry Smith     }
600eabae89aSBarry Smith 
6015180491cSLisandro Dalcin     ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
6025180491cSLisandro Dalcin     if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);}
6035180491cSLisandro Dalcin 
60490d69ab7SBarry Smith     flg  = PETSC_FALSE;
605acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
606a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
60790d69ab7SBarry Smith     flg  = PETSC_FALSE;
608acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
609a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
61090d69ab7SBarry Smith     flg  = PETSC_FALSE;
611acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
612a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
61390d69ab7SBarry Smith     flg  = PETSC_FALSE;
614acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
615a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
61690d69ab7SBarry Smith     flg  = PETSC_FALSE;
617acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
618b271bb04SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
619e24b481bSBarry Smith 
62090d69ab7SBarry Smith     flg  = PETSC_FALSE;
621acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
6224b27c08aSLois Curfman McInnes     if (flg) {
6236cab3a1bSJed Brown       void *functx;
6246cab3a1bSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
6256cab3a1bSJed Brown       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr);
626ae15b995SBarry Smith       ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
6279b94acceSBarry Smith     }
628639f9d9dSBarry Smith 
629aa3661deSLisandro Dalcin     mf = mf_operator = PETSC_FALSE;
630aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
631acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr);
632a8248277SBarry Smith     if (flg && mf_operator) {
633a8248277SBarry Smith       snes->mf_operator = PETSC_TRUE;
634a8248277SBarry Smith       mf = PETSC_TRUE;
635a8248277SBarry Smith     }
636aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
637acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr);
638aa3661deSLisandro Dalcin     if (!flg && mf_operator) mf = PETSC_TRUE;
639aa3661deSLisandro Dalcin     mf_version = 1;
640aa3661deSLisandro Dalcin     ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr);
641aa3661deSLisandro Dalcin 
642d28543b3SPeter Brune 
64389b92e6fSPeter Brune     /* GS Options */
64489b92e6fSPeter Brune     ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr);
64589b92e6fSPeter Brune 
64676b2cf59SMatthew Knepley     for(i = 0; i < numberofsetfromoptions; i++) {
64776b2cf59SMatthew Knepley       ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
64876b2cf59SMatthew Knepley     }
64976b2cf59SMatthew Knepley 
650e7788613SBarry Smith     if (snes->ops->setfromoptions) {
651e7788613SBarry Smith       ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr);
652639f9d9dSBarry Smith     }
6535d973c19SBarry Smith 
6545d973c19SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
6555d973c19SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr);
656b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
6574bbc92c1SBarry Smith 
658aa3661deSLisandro Dalcin   if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); }
6591cee3971SBarry Smith 
6601cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
661aa3661deSLisandro Dalcin   ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
662aa3661deSLisandro Dalcin   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr);
66385385478SLisandro Dalcin   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
66493993e2dSLois Curfman McInnes 
6659e764e56SPeter Brune   if (!snes->linesearch) {
666f1c6b773SPeter Brune     ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
6679e764e56SPeter Brune   }
668f1c6b773SPeter Brune   ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr);
6699e764e56SPeter Brune 
67051e86f29SPeter Brune   /* if someone has set the SNES PC type, create it. */
67151e86f29SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
67251e86f29SPeter Brune   ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr);
67351e86f29SPeter Brune   if (pcset && (!snes->pc)) {
67451e86f29SPeter Brune     ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr);
67551e86f29SPeter Brune   }
6763a40ed3dSBarry Smith   PetscFunctionReturn(0);
6779b94acceSBarry Smith }
6789b94acceSBarry Smith 
679d25893d9SBarry Smith #undef __FUNCT__
680d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext"
681d25893d9SBarry Smith /*@
682d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
683d25893d9SBarry Smith    the nonlinear solvers.
684d25893d9SBarry Smith 
685d25893d9SBarry Smith    Logically Collective on SNES
686d25893d9SBarry Smith 
687d25893d9SBarry Smith    Input Parameters:
688d25893d9SBarry Smith +  snes - the SNES context
689d25893d9SBarry Smith .  compute - function to compute the context
690d25893d9SBarry Smith -  destroy - function to destroy the context
691d25893d9SBarry Smith 
692d25893d9SBarry Smith    Level: intermediate
693d25893d9SBarry Smith 
694d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
695d25893d9SBarry Smith 
696d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
697d25893d9SBarry Smith @*/
698d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
699d25893d9SBarry Smith {
700d25893d9SBarry Smith   PetscFunctionBegin;
701d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
702d25893d9SBarry Smith   snes->ops->usercompute = compute;
703d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
704d25893d9SBarry Smith   PetscFunctionReturn(0);
705d25893d9SBarry Smith }
706a847f771SSatish Balay 
7074a2ae208SSatish Balay #undef __FUNCT__
7084a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
709b07ff414SBarry Smith /*@
7109b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
7119b94acceSBarry Smith    the nonlinear solvers.
7129b94acceSBarry Smith 
7133f9fe445SBarry Smith    Logically Collective on SNES
714fee21e36SBarry Smith 
715c7afd0dbSLois Curfman McInnes    Input Parameters:
716c7afd0dbSLois Curfman McInnes +  snes - the SNES context
717c7afd0dbSLois Curfman McInnes -  usrP - optional user context
718c7afd0dbSLois Curfman McInnes 
71936851e7fSLois Curfman McInnes    Level: intermediate
72036851e7fSLois Curfman McInnes 
7219b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
7229b94acceSBarry Smith 
723ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext()
7249b94acceSBarry Smith @*/
7257087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
7269b94acceSBarry Smith {
7271b2093e4SBarry Smith   PetscErrorCode ierr;
728b07ff414SBarry Smith   KSP            ksp;
7291b2093e4SBarry Smith 
7303a40ed3dSBarry Smith   PetscFunctionBegin;
7310700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
732b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
733b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
7349b94acceSBarry Smith   snes->user = usrP;
7353a40ed3dSBarry Smith   PetscFunctionReturn(0);
7369b94acceSBarry Smith }
73774679c65SBarry Smith 
7384a2ae208SSatish Balay #undef __FUNCT__
7394a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
740b07ff414SBarry Smith /*@
7419b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
7429b94acceSBarry Smith    nonlinear solvers.
7439b94acceSBarry Smith 
744c7afd0dbSLois Curfman McInnes    Not Collective
745c7afd0dbSLois Curfman McInnes 
7469b94acceSBarry Smith    Input Parameter:
7479b94acceSBarry Smith .  snes - SNES context
7489b94acceSBarry Smith 
7499b94acceSBarry Smith    Output Parameter:
7509b94acceSBarry Smith .  usrP - user context
7519b94acceSBarry Smith 
75236851e7fSLois Curfman McInnes    Level: intermediate
75336851e7fSLois Curfman McInnes 
7549b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
7559b94acceSBarry Smith 
7569b94acceSBarry Smith .seealso: SNESSetApplicationContext()
7579b94acceSBarry Smith @*/
758e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
7599b94acceSBarry Smith {
7603a40ed3dSBarry Smith   PetscFunctionBegin;
7610700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
762e71120c6SJed Brown   *(void**)usrP = snes->user;
7633a40ed3dSBarry Smith   PetscFunctionReturn(0);
7649b94acceSBarry Smith }
76574679c65SBarry Smith 
7664a2ae208SSatish Balay #undef __FUNCT__
7674a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
7689b94acceSBarry Smith /*@
769c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
770c8228a4eSBarry Smith    at this time.
7719b94acceSBarry Smith 
772c7afd0dbSLois Curfman McInnes    Not Collective
773c7afd0dbSLois Curfman McInnes 
7749b94acceSBarry Smith    Input Parameter:
7759b94acceSBarry Smith .  snes - SNES context
7769b94acceSBarry Smith 
7779b94acceSBarry Smith    Output Parameter:
7789b94acceSBarry Smith .  iter - iteration number
7799b94acceSBarry Smith 
780c8228a4eSBarry Smith    Notes:
781c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
782c8228a4eSBarry Smith 
783c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
78408405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
78508405cd6SLois Curfman McInnes .vb
78608405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
78708405cd6SLois Curfman McInnes       if (!(it % 2)) {
78808405cd6SLois Curfman McInnes         [compute Jacobian here]
78908405cd6SLois Curfman McInnes       }
79008405cd6SLois Curfman McInnes .ve
791c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
79208405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
793c8228a4eSBarry Smith 
79436851e7fSLois Curfman McInnes    Level: intermediate
79536851e7fSLois Curfman McInnes 
7962b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
7972b668275SBarry Smith 
798b850b91aSLisandro Dalcin .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
7999b94acceSBarry Smith @*/
8007087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
8019b94acceSBarry Smith {
8023a40ed3dSBarry Smith   PetscFunctionBegin;
8030700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8044482741eSBarry Smith   PetscValidIntPointer(iter,2);
8059b94acceSBarry Smith   *iter = snes->iter;
8063a40ed3dSBarry Smith   PetscFunctionReturn(0);
8079b94acceSBarry Smith }
80874679c65SBarry Smith 
8094a2ae208SSatish Balay #undef __FUNCT__
810360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber"
811360c497dSPeter Brune /*@
812360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
813360c497dSPeter Brune 
814360c497dSPeter Brune    Not Collective
815360c497dSPeter Brune 
816360c497dSPeter Brune    Input Parameter:
817360c497dSPeter Brune .  snes - SNES context
818360c497dSPeter Brune .  iter - iteration number
819360c497dSPeter Brune 
820360c497dSPeter Brune    Level: developer
821360c497dSPeter Brune 
822360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number,
823360c497dSPeter Brune 
824360c497dSPeter Brune .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
825360c497dSPeter Brune @*/
826360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
827360c497dSPeter Brune {
828360c497dSPeter Brune   PetscErrorCode ierr;
829360c497dSPeter Brune 
830360c497dSPeter Brune   PetscFunctionBegin;
831360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
832360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
833360c497dSPeter Brune   snes->iter = iter;
834360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
835360c497dSPeter Brune   PetscFunctionReturn(0);
836360c497dSPeter Brune }
837360c497dSPeter Brune 
838360c497dSPeter Brune #undef __FUNCT__
8394a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm"
8409b94acceSBarry Smith /*@
8419b94acceSBarry Smith    SNESGetFunctionNorm - Gets the norm of the current function that was set
8429b94acceSBarry Smith    with SNESSSetFunction().
8439b94acceSBarry Smith 
844c7afd0dbSLois Curfman McInnes    Collective on SNES
845c7afd0dbSLois Curfman McInnes 
8469b94acceSBarry Smith    Input Parameter:
8479b94acceSBarry Smith .  snes - SNES context
8489b94acceSBarry Smith 
8499b94acceSBarry Smith    Output Parameter:
8509b94acceSBarry Smith .  fnorm - 2-norm of function
8519b94acceSBarry Smith 
85236851e7fSLois Curfman McInnes    Level: intermediate
85336851e7fSLois Curfman McInnes 
8549b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm
855a86d99e1SLois Curfman McInnes 
856b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
8579b94acceSBarry Smith @*/
8587087cfbeSBarry Smith PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
8599b94acceSBarry Smith {
8603a40ed3dSBarry Smith   PetscFunctionBegin;
8610700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8624482741eSBarry Smith   PetscValidScalarPointer(fnorm,2);
8639b94acceSBarry Smith   *fnorm = snes->norm;
8643a40ed3dSBarry Smith   PetscFunctionReturn(0);
8659b94acceSBarry Smith }
86674679c65SBarry Smith 
867360c497dSPeter Brune 
868360c497dSPeter Brune #undef __FUNCT__
869360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm"
870360c497dSPeter Brune /*@
871360c497dSPeter Brune    SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm().
872360c497dSPeter Brune 
873360c497dSPeter Brune    Collective on SNES
874360c497dSPeter Brune 
875360c497dSPeter Brune    Input Parameter:
876360c497dSPeter Brune .  snes - SNES context
877360c497dSPeter Brune .  fnorm - 2-norm of function
878360c497dSPeter Brune 
879360c497dSPeter Brune    Level: developer
880360c497dSPeter Brune 
881360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm
882360c497dSPeter Brune 
883360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm().
884360c497dSPeter Brune @*/
885360c497dSPeter Brune PetscErrorCode  SNESSetFunctionNorm(SNES snes,PetscReal fnorm)
886360c497dSPeter Brune {
887360c497dSPeter Brune 
888360c497dSPeter Brune   PetscErrorCode ierr;
889360c497dSPeter Brune 
890360c497dSPeter Brune   PetscFunctionBegin;
891360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
892360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
893360c497dSPeter Brune   snes->norm = fnorm;
894360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
895360c497dSPeter Brune   PetscFunctionReturn(0);
896360c497dSPeter Brune }
897360c497dSPeter Brune 
8984a2ae208SSatish Balay #undef __FUNCT__
899b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
9009b94acceSBarry Smith /*@
901b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
9029b94acceSBarry Smith    attempted by the nonlinear solver.
9039b94acceSBarry Smith 
904c7afd0dbSLois Curfman McInnes    Not Collective
905c7afd0dbSLois Curfman McInnes 
9069b94acceSBarry Smith    Input Parameter:
9079b94acceSBarry Smith .  snes - SNES context
9089b94acceSBarry Smith 
9099b94acceSBarry Smith    Output Parameter:
9109b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
9119b94acceSBarry Smith 
912c96a6f78SLois Curfman McInnes    Notes:
913c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
914c96a6f78SLois Curfman McInnes 
91536851e7fSLois Curfman McInnes    Level: intermediate
91636851e7fSLois Curfman McInnes 
9179b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
91858ebbce7SBarry Smith 
919e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
92058ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
9219b94acceSBarry Smith @*/
9227087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
9239b94acceSBarry Smith {
9243a40ed3dSBarry Smith   PetscFunctionBegin;
9250700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9264482741eSBarry Smith   PetscValidIntPointer(nfails,2);
92750ffb88aSMatthew Knepley   *nfails = snes->numFailures;
92850ffb88aSMatthew Knepley   PetscFunctionReturn(0);
92950ffb88aSMatthew Knepley }
93050ffb88aSMatthew Knepley 
93150ffb88aSMatthew Knepley #undef __FUNCT__
932b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
93350ffb88aSMatthew Knepley /*@
934b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
93550ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
93650ffb88aSMatthew Knepley 
93750ffb88aSMatthew Knepley    Not Collective
93850ffb88aSMatthew Knepley 
93950ffb88aSMatthew Knepley    Input Parameters:
94050ffb88aSMatthew Knepley +  snes     - SNES context
94150ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
94250ffb88aSMatthew Knepley 
94350ffb88aSMatthew Knepley    Level: intermediate
94450ffb88aSMatthew Knepley 
94550ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
94658ebbce7SBarry Smith 
947e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
94858ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
94950ffb88aSMatthew Knepley @*/
9507087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
95150ffb88aSMatthew Knepley {
95250ffb88aSMatthew Knepley   PetscFunctionBegin;
9530700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
95450ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
95550ffb88aSMatthew Knepley   PetscFunctionReturn(0);
95650ffb88aSMatthew Knepley }
95750ffb88aSMatthew Knepley 
95850ffb88aSMatthew Knepley #undef __FUNCT__
959b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
96050ffb88aSMatthew Knepley /*@
961b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
96250ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
96350ffb88aSMatthew Knepley 
96450ffb88aSMatthew Knepley    Not Collective
96550ffb88aSMatthew Knepley 
96650ffb88aSMatthew Knepley    Input Parameter:
96750ffb88aSMatthew Knepley .  snes     - SNES context
96850ffb88aSMatthew Knepley 
96950ffb88aSMatthew Knepley    Output Parameter:
97050ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
97150ffb88aSMatthew Knepley 
97250ffb88aSMatthew Knepley    Level: intermediate
97350ffb88aSMatthew Knepley 
97450ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
97558ebbce7SBarry Smith 
976e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
97758ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
97858ebbce7SBarry Smith 
97950ffb88aSMatthew Knepley @*/
9807087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
98150ffb88aSMatthew Knepley {
98250ffb88aSMatthew Knepley   PetscFunctionBegin;
9830700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9844482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
98550ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
9863a40ed3dSBarry Smith   PetscFunctionReturn(0);
9879b94acceSBarry Smith }
988a847f771SSatish Balay 
9894a2ae208SSatish Balay #undef __FUNCT__
9902541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
9912541af92SBarry Smith /*@
9922541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
9932541af92SBarry Smith      done by SNES.
9942541af92SBarry Smith 
9952541af92SBarry Smith    Not Collective
9962541af92SBarry Smith 
9972541af92SBarry Smith    Input Parameter:
9982541af92SBarry Smith .  snes     - SNES context
9992541af92SBarry Smith 
10002541af92SBarry Smith    Output Parameter:
10012541af92SBarry Smith .  nfuncs - number of evaluations
10022541af92SBarry Smith 
10032541af92SBarry Smith    Level: intermediate
10042541af92SBarry Smith 
10052541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
100658ebbce7SBarry Smith 
1007e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
10082541af92SBarry Smith @*/
10097087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
10102541af92SBarry Smith {
10112541af92SBarry Smith   PetscFunctionBegin;
10120700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10132541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
10142541af92SBarry Smith   *nfuncs = snes->nfuncs;
10152541af92SBarry Smith   PetscFunctionReturn(0);
10162541af92SBarry Smith }
10172541af92SBarry Smith 
10182541af92SBarry Smith #undef __FUNCT__
10193d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
10203d4c4710SBarry Smith /*@
10213d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
10223d4c4710SBarry Smith    linear solvers.
10233d4c4710SBarry Smith 
10243d4c4710SBarry Smith    Not Collective
10253d4c4710SBarry Smith 
10263d4c4710SBarry Smith    Input Parameter:
10273d4c4710SBarry Smith .  snes - SNES context
10283d4c4710SBarry Smith 
10293d4c4710SBarry Smith    Output Parameter:
10303d4c4710SBarry Smith .  nfails - number of failed solves
10313d4c4710SBarry Smith 
10323d4c4710SBarry Smith    Notes:
10333d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
10343d4c4710SBarry Smith 
10353d4c4710SBarry Smith    Level: intermediate
10363d4c4710SBarry Smith 
10373d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
103858ebbce7SBarry Smith 
1039e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
10403d4c4710SBarry Smith @*/
10417087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
10423d4c4710SBarry Smith {
10433d4c4710SBarry Smith   PetscFunctionBegin;
10440700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10453d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
10463d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
10473d4c4710SBarry Smith   PetscFunctionReturn(0);
10483d4c4710SBarry Smith }
10493d4c4710SBarry Smith 
10503d4c4710SBarry Smith #undef __FUNCT__
10513d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
10523d4c4710SBarry Smith /*@
10533d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
10543d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
10553d4c4710SBarry Smith 
10563f9fe445SBarry Smith    Logically Collective on SNES
10573d4c4710SBarry Smith 
10583d4c4710SBarry Smith    Input Parameters:
10593d4c4710SBarry Smith +  snes     - SNES context
10603d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
10613d4c4710SBarry Smith 
10623d4c4710SBarry Smith    Level: intermediate
10633d4c4710SBarry Smith 
1064a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
10653d4c4710SBarry Smith 
10663d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
10673d4c4710SBarry Smith 
106858ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
10693d4c4710SBarry Smith @*/
10707087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
10713d4c4710SBarry Smith {
10723d4c4710SBarry Smith   PetscFunctionBegin;
10730700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1074c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
10753d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
10763d4c4710SBarry Smith   PetscFunctionReturn(0);
10773d4c4710SBarry Smith }
10783d4c4710SBarry Smith 
10793d4c4710SBarry Smith #undef __FUNCT__
10803d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
10813d4c4710SBarry Smith /*@
10823d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
10833d4c4710SBarry Smith      are allowed before SNES terminates
10843d4c4710SBarry Smith 
10853d4c4710SBarry Smith    Not Collective
10863d4c4710SBarry Smith 
10873d4c4710SBarry Smith    Input Parameter:
10883d4c4710SBarry Smith .  snes     - SNES context
10893d4c4710SBarry Smith 
10903d4c4710SBarry Smith    Output Parameter:
10913d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
10923d4c4710SBarry Smith 
10933d4c4710SBarry Smith    Level: intermediate
10943d4c4710SBarry Smith 
10953d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
10963d4c4710SBarry Smith 
10973d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
10983d4c4710SBarry Smith 
1099e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
11003d4c4710SBarry Smith @*/
11017087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
11023d4c4710SBarry Smith {
11033d4c4710SBarry Smith   PetscFunctionBegin;
11040700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11053d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
11063d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
11073d4c4710SBarry Smith   PetscFunctionReturn(0);
11083d4c4710SBarry Smith }
11093d4c4710SBarry Smith 
11103d4c4710SBarry Smith #undef __FUNCT__
1111b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
1112c96a6f78SLois Curfman McInnes /*@
1113b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1114c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1115c96a6f78SLois Curfman McInnes 
1116c7afd0dbSLois Curfman McInnes    Not Collective
1117c7afd0dbSLois Curfman McInnes 
1118c96a6f78SLois Curfman McInnes    Input Parameter:
1119c96a6f78SLois Curfman McInnes .  snes - SNES context
1120c96a6f78SLois Curfman McInnes 
1121c96a6f78SLois Curfman McInnes    Output Parameter:
1122c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1123c96a6f78SLois Curfman McInnes 
1124c96a6f78SLois Curfman McInnes    Notes:
1125c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1126c96a6f78SLois Curfman McInnes 
112736851e7fSLois Curfman McInnes    Level: intermediate
112836851e7fSLois Curfman McInnes 
1129c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
11302b668275SBarry Smith 
11318c7482ecSBarry Smith .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
1132c96a6f78SLois Curfman McInnes @*/
11337087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
1134c96a6f78SLois Curfman McInnes {
11353a40ed3dSBarry Smith   PetscFunctionBegin;
11360700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11374482741eSBarry Smith   PetscValidIntPointer(lits,2);
1138c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
11393a40ed3dSBarry Smith   PetscFunctionReturn(0);
1140c96a6f78SLois Curfman McInnes }
1141c96a6f78SLois Curfman McInnes 
11424a2ae208SSatish Balay #undef __FUNCT__
114394b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP"
114452baeb72SSatish Balay /*@
114594b7f48cSBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
11469b94acceSBarry Smith 
114794b7f48cSBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
1148c7afd0dbSLois Curfman McInnes 
11499b94acceSBarry Smith    Input Parameter:
11509b94acceSBarry Smith .  snes - the SNES context
11519b94acceSBarry Smith 
11529b94acceSBarry Smith    Output Parameter:
115394b7f48cSBarry Smith .  ksp - the KSP context
11549b94acceSBarry Smith 
11559b94acceSBarry Smith    Notes:
115694b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
11579b94acceSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
11582999313aSBarry Smith    PC contexts as well.
11599b94acceSBarry Smith 
116036851e7fSLois Curfman McInnes    Level: beginner
116136851e7fSLois Curfman McInnes 
116294b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
11639b94acceSBarry Smith 
11642999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
11659b94acceSBarry Smith @*/
11667087cfbeSBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
11679b94acceSBarry Smith {
11681cee3971SBarry Smith   PetscErrorCode ierr;
11691cee3971SBarry Smith 
11703a40ed3dSBarry Smith   PetscFunctionBegin;
11710700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11724482741eSBarry Smith   PetscValidPointer(ksp,2);
11731cee3971SBarry Smith 
11741cee3971SBarry Smith   if (!snes->ksp) {
11751cee3971SBarry Smith     ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr);
11761cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
11771cee3971SBarry Smith     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
11781cee3971SBarry Smith   }
117994b7f48cSBarry Smith   *ksp = snes->ksp;
11803a40ed3dSBarry Smith   PetscFunctionReturn(0);
11819b94acceSBarry Smith }
118282bf6240SBarry Smith 
11834a2ae208SSatish Balay #undef __FUNCT__
11842999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
11852999313aSBarry Smith /*@
11862999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
11872999313aSBarry Smith 
11882999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
11892999313aSBarry Smith 
11902999313aSBarry Smith    Input Parameters:
11912999313aSBarry Smith +  snes - the SNES context
11922999313aSBarry Smith -  ksp - the KSP context
11932999313aSBarry Smith 
11942999313aSBarry Smith    Notes:
11952999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
11962999313aSBarry Smith    so this routine is rarely needed.
11972999313aSBarry Smith 
11982999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
11992999313aSBarry Smith    decreased by one.
12002999313aSBarry Smith 
12012999313aSBarry Smith    Level: developer
12022999313aSBarry Smith 
12032999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
12042999313aSBarry Smith 
12052999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
12062999313aSBarry Smith @*/
12077087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
12082999313aSBarry Smith {
12092999313aSBarry Smith   PetscErrorCode ierr;
12102999313aSBarry Smith 
12112999313aSBarry Smith   PetscFunctionBegin;
12120700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12130700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
12142999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
12157dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1216906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
12172999313aSBarry Smith   snes->ksp = ksp;
12182999313aSBarry Smith   PetscFunctionReturn(0);
12192999313aSBarry Smith }
12202999313aSBarry Smith 
12217adad957SLisandro Dalcin #if 0
12222999313aSBarry Smith #undef __FUNCT__
12234a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc"
12246849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
1225e24b481bSBarry Smith {
1226e24b481bSBarry Smith   PetscFunctionBegin;
1227e24b481bSBarry Smith   PetscFunctionReturn(0);
1228e24b481bSBarry Smith }
12297adad957SLisandro Dalcin #endif
1230e24b481bSBarry Smith 
12319b94acceSBarry Smith /* -----------------------------------------------------------*/
12324a2ae208SSatish Balay #undef __FUNCT__
12334a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
123452baeb72SSatish Balay /*@
12359b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
12369b94acceSBarry Smith 
1237c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1238c7afd0dbSLois Curfman McInnes 
1239c7afd0dbSLois Curfman McInnes    Input Parameters:
1240906ed7ccSBarry Smith .  comm - MPI communicator
12419b94acceSBarry Smith 
12429b94acceSBarry Smith    Output Parameter:
12439b94acceSBarry Smith .  outsnes - the new SNES context
12449b94acceSBarry Smith 
1245c7afd0dbSLois Curfman McInnes    Options Database Keys:
1246c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1247c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1248c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1249c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1250c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1251c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1252c1f60f51SBarry Smith 
125336851e7fSLois Curfman McInnes    Level: beginner
125436851e7fSLois Curfman McInnes 
12559b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
12569b94acceSBarry Smith 
1257a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1258a8054027SBarry Smith 
12599b94acceSBarry Smith @*/
12607087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
12619b94acceSBarry Smith {
1262dfbe8321SBarry Smith   PetscErrorCode      ierr;
12639b94acceSBarry Smith   SNES                snes;
1264fa9f3622SBarry Smith   SNESKSPEW           *kctx;
126537fcc0dbSBarry Smith 
12663a40ed3dSBarry Smith   PetscFunctionBegin;
1267ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
12688ba1e511SMatthew Knepley   *outsnes = PETSC_NULL;
12698ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
12708ba1e511SMatthew Knepley   ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr);
12718ba1e511SMatthew Knepley #endif
12728ba1e511SMatthew Knepley 
12733194b578SJed Brown   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
12747adad957SLisandro Dalcin 
127585385478SLisandro Dalcin   snes->ops->converged    = SNESDefaultConverged;
12762c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
127788976e71SPeter Brune   snes->tolerancesset     = PETSC_FALSE;
12789b94acceSBarry Smith   snes->max_its           = 50;
12799750a799SBarry Smith   snes->max_funcs         = 10000;
12809b94acceSBarry Smith   snes->norm              = 0.0;
1281fdacfa88SPeter Brune   snes->normtype          = SNES_NORM_FUNCTION;
1282b4874afaSBarry Smith   snes->rtol              = 1.e-8;
1283b4874afaSBarry Smith   snes->ttol              = 0.0;
128470441072SBarry Smith   snes->abstol            = 1.e-50;
1285c60f73f4SPeter Brune   snes->stol              = 1.e-8;
12864b27c08aSLois Curfman McInnes   snes->deltatol          = 1.e-12;
12879b94acceSBarry Smith   snes->nfuncs            = 0;
128850ffb88aSMatthew Knepley   snes->numFailures       = 0;
128950ffb88aSMatthew Knepley   snes->maxFailures       = 1;
12907a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1291e35cf81dSBarry Smith   snes->lagjacobian       = 1;
1292a8054027SBarry Smith   snes->lagpreconditioner = 1;
1293639f9d9dSBarry Smith   snes->numbermonitors    = 0;
12949b94acceSBarry Smith   snes->data              = 0;
12954dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1296186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
12976f24a144SLois Curfman McInnes   snes->nwork             = 0;
129858c9b817SLisandro Dalcin   snes->work              = 0;
129958c9b817SLisandro Dalcin   snes->nvwork            = 0;
130058c9b817SLisandro Dalcin   snes->vwork             = 0;
1301758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1302758f92a0SBarry Smith   snes->conv_hist_max     = 0;
1303758f92a0SBarry Smith   snes->conv_hist         = PETSC_NULL;
1304758f92a0SBarry Smith   snes->conv_hist_its     = PETSC_NULL;
1305758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1306e4ed7901SPeter Brune   snes->vec_func_init_set = PETSC_FALSE;
1307e4ed7901SPeter Brune   snes->norm_init         = 0.;
1308e4ed7901SPeter Brune   snes->norm_init_set     = PETSC_FALSE;
1309184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
131089b92e6fSPeter Brune   snes->gssweeps          = 1;
13119b94acceSBarry Smith 
13123d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
13133d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
13143d4c4710SBarry Smith 
13159b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
131638f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr);
13179b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
13189b94acceSBarry Smith   kctx->version     = 2;
13199b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
13209b94acceSBarry Smith                              this was too large for some test cases */
132175567043SBarry Smith   kctx->rtol_last   = 0.0;
13229b94acceSBarry Smith   kctx->rtol_max    = .9;
13239b94acceSBarry Smith   kctx->gamma       = 1.0;
132462d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
132571f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
13269b94acceSBarry Smith   kctx->threshold   = .1;
132775567043SBarry Smith   kctx->lresid_last = 0.0;
132875567043SBarry Smith   kctx->norm_last   = 0.0;
13299b94acceSBarry Smith 
13309b94acceSBarry Smith   *outsnes = snes;
13313a40ed3dSBarry Smith   PetscFunctionReturn(0);
13329b94acceSBarry Smith }
13339b94acceSBarry Smith 
13344a2ae208SSatish Balay #undef __FUNCT__
13354a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
13369b94acceSBarry Smith /*@C
13379b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
13389b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
13399b94acceSBarry Smith    equations.
13409b94acceSBarry Smith 
13413f9fe445SBarry Smith    Logically Collective on SNES
1342fee21e36SBarry Smith 
1343c7afd0dbSLois Curfman McInnes    Input Parameters:
1344c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1345c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1346de044059SHong Zhang .  func - function evaluation routine
1347c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1348c7afd0dbSLois Curfman McInnes          function evaluation routine (may be PETSC_NULL)
13499b94acceSBarry Smith 
1350c7afd0dbSLois Curfman McInnes    Calling sequence of func:
13518d76a1e5SLois Curfman McInnes $    func (SNES snes,Vec x,Vec f,void *ctx);
1352c7afd0dbSLois Curfman McInnes 
1353c586c404SJed Brown +  snes - the SNES context
1354c586c404SJed Brown .  x - state at which to evaluate residual
1355c586c404SJed Brown .  f - vector to put residual
1356c7afd0dbSLois Curfman McInnes -  ctx - optional user-defined function context
13579b94acceSBarry Smith 
13589b94acceSBarry Smith    Notes:
13599b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
13609b94acceSBarry Smith $      f'(x) x = -f(x),
1361c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
13629b94acceSBarry Smith 
136336851e7fSLois Curfman McInnes    Level: beginner
136436851e7fSLois Curfman McInnes 
13659b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
13669b94acceSBarry Smith 
13678b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard()
13689b94acceSBarry Smith @*/
13697087cfbeSBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
13709b94acceSBarry Smith {
137185385478SLisandro Dalcin   PetscErrorCode ierr;
13726cab3a1bSJed Brown   DM             dm;
13736cab3a1bSJed Brown 
13743a40ed3dSBarry Smith   PetscFunctionBegin;
13750700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1376d2a683ecSLisandro Dalcin   if (r) {
1377d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1378d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
137985385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
13806bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
138185385478SLisandro Dalcin     snes->vec_func = r;
1382d2a683ecSLisandro Dalcin   }
13836cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
13846cab3a1bSJed Brown   ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr);
13853a40ed3dSBarry Smith   PetscFunctionReturn(0);
13869b94acceSBarry Smith }
13879b94acceSBarry Smith 
1388646217ecSPeter Brune 
1389646217ecSPeter Brune #undef __FUNCT__
1390e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction"
1391e4ed7901SPeter Brune /*@C
1392e4ed7901SPeter Brune    SNESSetInitialFunction - Sets the function vector to be used as the
1393e4ed7901SPeter Brune    function norm at the initialization of the method.  In some
1394e4ed7901SPeter Brune    instances, the user has precomputed the function before calling
1395e4ed7901SPeter Brune    SNESSolve.  This function allows one to avoid a redundant call
1396e4ed7901SPeter Brune    to SNESComputeFunction in that case.
1397e4ed7901SPeter Brune 
1398e4ed7901SPeter Brune    Logically Collective on SNES
1399e4ed7901SPeter Brune 
1400e4ed7901SPeter Brune    Input Parameters:
1401e4ed7901SPeter Brune +  snes - the SNES context
1402e4ed7901SPeter Brune -  f - vector to store function value
1403e4ed7901SPeter Brune 
1404e4ed7901SPeter Brune    Notes:
1405e4ed7901SPeter Brune    This should not be modified during the solution procedure.
1406e4ed7901SPeter Brune 
1407e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1408e4ed7901SPeter Brune 
1409e4ed7901SPeter Brune    Level: developer
1410e4ed7901SPeter Brune 
1411e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function
1412e4ed7901SPeter Brune 
1413e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm()
1414e4ed7901SPeter Brune @*/
1415e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunction(SNES snes, Vec f)
1416e4ed7901SPeter Brune {
1417e4ed7901SPeter Brune   PetscErrorCode ierr;
1418e4ed7901SPeter Brune   Vec            vec_func;
1419e4ed7901SPeter Brune 
1420e4ed7901SPeter Brune   PetscFunctionBegin;
1421e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1422e4ed7901SPeter Brune   PetscValidHeaderSpecific(f,VEC_CLASSID,2);
1423e4ed7901SPeter Brune   PetscCheckSameComm(snes,1,f,2);
1424e4ed7901SPeter Brune   ierr = SNESGetFunction(snes,&vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
1425e4ed7901SPeter Brune   ierr = VecCopy(f, vec_func);CHKERRQ(ierr);
1426217b9c2eSPeter Brune   snes->vec_func_init_set = PETSC_TRUE;
1427e4ed7901SPeter Brune   PetscFunctionReturn(0);
1428e4ed7901SPeter Brune }
1429e4ed7901SPeter Brune 
1430e4ed7901SPeter Brune 
1431e4ed7901SPeter Brune #undef __FUNCT__
1432e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunctionNorm"
1433e4ed7901SPeter Brune /*@C
1434e4ed7901SPeter Brune    SNESSetInitialFunctionNorm - Sets the function norm to be used as the function norm
1435e4ed7901SPeter Brune    at the initialization of the  method.  In some instances, the user has precomputed
1436e4ed7901SPeter Brune    the function and its norm before calling SNESSolve.  This function allows one to
1437e4ed7901SPeter Brune    avoid a redundant call to SNESComputeFunction() and VecNorm() in that case.
1438e4ed7901SPeter Brune 
1439e4ed7901SPeter Brune    Logically Collective on SNES
1440e4ed7901SPeter Brune 
1441e4ed7901SPeter Brune    Input Parameters:
1442e4ed7901SPeter Brune +  snes - the SNES context
1443e4ed7901SPeter Brune -  fnorm - the norm of F as set by SNESSetInitialFunction()
1444e4ed7901SPeter Brune 
1445e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1446e4ed7901SPeter Brune 
1447e4ed7901SPeter Brune    Level: developer
1448e4ed7901SPeter Brune 
1449e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function, norm
1450e4ed7901SPeter Brune 
1451e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction()
1452e4ed7901SPeter Brune @*/
1453e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm)
1454e4ed7901SPeter Brune {
1455e4ed7901SPeter Brune   PetscFunctionBegin;
1456e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1457e4ed7901SPeter Brune   snes->norm_init = fnorm;
1458e4ed7901SPeter Brune   snes->norm_init_set = PETSC_TRUE;
1459e4ed7901SPeter Brune   PetscFunctionReturn(0);
1460e4ed7901SPeter Brune }
1461e4ed7901SPeter Brune 
1462e4ed7901SPeter Brune #undef __FUNCT__
1463534ebe21SPeter Brune #define __FUNCT__ "SNESSetNormType"
1464534ebe21SPeter Brune /*@
1465534ebe21SPeter Brune    SNESSetNormType - Sets the SNESNormType used in covergence and monitoring
1466534ebe21SPeter Brune    of the SNES method.
1467534ebe21SPeter Brune 
1468534ebe21SPeter Brune    Logically Collective on SNES
1469534ebe21SPeter Brune 
1470534ebe21SPeter Brune    Input Parameters:
1471534ebe21SPeter Brune +  snes - the SNES context
1472534ebe21SPeter Brune -  normtype - the type of the norm used
1473534ebe21SPeter Brune 
1474534ebe21SPeter Brune    Notes:
1475534ebe21SPeter Brune    Only certain SNES methods support certain SNESNormTypes.  Most require evaluation
1476534ebe21SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
1477534ebe21SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1478534ebe21SPeter Brune    (SNESGS) and the like do not require the norm of the function to be computed, and therfore
1479534ebe21SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
1480534ebe21SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
1481534ebe21SPeter Brune    their solution.
1482534ebe21SPeter Brune 
1483534ebe21SPeter Brune    Level: developer
1484534ebe21SPeter Brune 
1485534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1486534ebe21SPeter Brune 
1487534ebe21SPeter Brune .seealso: SNESGetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType
1488534ebe21SPeter Brune @*/
1489534ebe21SPeter Brune PetscErrorCode  SNESSetNormType(SNES snes, SNESNormType normtype)
1490534ebe21SPeter Brune {
1491534ebe21SPeter Brune   PetscFunctionBegin;
1492534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1493534ebe21SPeter Brune   snes->normtype = normtype;
1494534ebe21SPeter Brune   PetscFunctionReturn(0);
1495534ebe21SPeter Brune }
1496534ebe21SPeter Brune 
1497534ebe21SPeter Brune 
1498534ebe21SPeter Brune #undef __FUNCT__
1499534ebe21SPeter Brune #define __FUNCT__ "SNESGetNormType"
1500534ebe21SPeter Brune /*@
1501534ebe21SPeter Brune    SNESGetNormType - Gets the SNESNormType used in covergence and monitoring
1502534ebe21SPeter Brune    of the SNES method.
1503534ebe21SPeter Brune 
1504534ebe21SPeter Brune    Logically Collective on SNES
1505534ebe21SPeter Brune 
1506534ebe21SPeter Brune    Input Parameters:
1507534ebe21SPeter Brune +  snes - the SNES context
1508534ebe21SPeter Brune -  normtype - the type of the norm used
1509534ebe21SPeter Brune 
1510534ebe21SPeter Brune    Level: advanced
1511534ebe21SPeter Brune 
1512534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1513534ebe21SPeter Brune 
1514534ebe21SPeter Brune .seealso: SNESSetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType
1515534ebe21SPeter Brune @*/
1516534ebe21SPeter Brune PetscErrorCode  SNESGetNormType(SNES snes, SNESNormType *normtype)
1517534ebe21SPeter Brune {
1518534ebe21SPeter Brune   PetscFunctionBegin;
1519534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1520534ebe21SPeter Brune   *normtype = snes->normtype;
1521534ebe21SPeter Brune   PetscFunctionReturn(0);
1522534ebe21SPeter Brune }
1523534ebe21SPeter Brune 
1524534ebe21SPeter Brune #undef __FUNCT__
1525646217ecSPeter Brune #define __FUNCT__ "SNESSetGS"
1526c79ef259SPeter Brune /*@C
1527c79ef259SPeter Brune    SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for
1528c79ef259SPeter Brune    use with composed nonlinear solvers.
1529c79ef259SPeter Brune 
1530c79ef259SPeter Brune    Input Parameters:
1531c79ef259SPeter Brune +  snes   - the SNES context
1532c79ef259SPeter Brune .  gsfunc - function evaluation routine
1533c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
1534c79ef259SPeter Brune             smoother evaluation routine (may be PETSC_NULL)
1535c79ef259SPeter Brune 
1536c79ef259SPeter Brune    Calling sequence of func:
1537c79ef259SPeter Brune $    func (SNES snes,Vec x,Vec b,void *ctx);
1538c79ef259SPeter Brune 
1539c79ef259SPeter Brune +  X   - solution vector
1540c79ef259SPeter Brune .  B   - RHS vector
1541d28543b3SPeter Brune -  ctx - optional user-defined Gauss-Seidel context
1542c79ef259SPeter Brune 
1543c79ef259SPeter Brune    Notes:
1544c79ef259SPeter Brune    The GS routines are used by the composed nonlinear solver to generate
1545c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
1546c79ef259SPeter Brune 
1547d28543b3SPeter Brune    Level: intermediate
1548c79ef259SPeter Brune 
1549d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel
1550c79ef259SPeter Brune 
1551c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS()
1552c79ef259SPeter Brune @*/
15536cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx)
15546cab3a1bSJed Brown {
15556cab3a1bSJed Brown   PetscErrorCode ierr;
15566cab3a1bSJed Brown   DM dm;
15576cab3a1bSJed Brown 
1558646217ecSPeter Brune   PetscFunctionBegin;
15596cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15606cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
15616cab3a1bSJed Brown   ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr);
1562646217ecSPeter Brune   PetscFunctionReturn(0);
1563646217ecSPeter Brune }
1564646217ecSPeter Brune 
1565d25893d9SBarry Smith #undef __FUNCT__
156689b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps"
156789b92e6fSPeter Brune /*@
156889b92e6fSPeter Brune    SNESSetGSSweeps - Sets the number of sweeps of GS to use.
156989b92e6fSPeter Brune 
157089b92e6fSPeter Brune    Input Parameters:
157189b92e6fSPeter Brune +  snes   - the SNES context
157289b92e6fSPeter Brune -  sweeps  - the number of sweeps of GS to perform.
157389b92e6fSPeter Brune 
157489b92e6fSPeter Brune    Level: intermediate
157589b92e6fSPeter Brune 
157689b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
157789b92e6fSPeter Brune 
157889b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps()
157989b92e6fSPeter Brune @*/
158089b92e6fSPeter Brune 
158189b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) {
158289b92e6fSPeter Brune   PetscFunctionBegin;
158389b92e6fSPeter Brune   snes->gssweeps = sweeps;
158489b92e6fSPeter Brune   PetscFunctionReturn(0);
158589b92e6fSPeter Brune }
158689b92e6fSPeter Brune 
158789b92e6fSPeter Brune 
158889b92e6fSPeter Brune #undef __FUNCT__
158989b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps"
159089b92e6fSPeter Brune /*@
159189b92e6fSPeter Brune    SNESGetGSSweeps - Gets the number of sweeps GS will use.
159289b92e6fSPeter Brune 
159389b92e6fSPeter Brune    Input Parameters:
159489b92e6fSPeter Brune .  snes   - the SNES context
159589b92e6fSPeter Brune 
159689b92e6fSPeter Brune    Output Parameters:
159789b92e6fSPeter Brune .  sweeps  - the number of sweeps of GS to perform.
159889b92e6fSPeter Brune 
159989b92e6fSPeter Brune    Level: intermediate
160089b92e6fSPeter Brune 
160189b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
160289b92e6fSPeter Brune 
160389b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps()
160489b92e6fSPeter Brune @*/
160589b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) {
160689b92e6fSPeter Brune   PetscFunctionBegin;
160789b92e6fSPeter Brune   *sweeps = snes->gssweeps;
160889b92e6fSPeter Brune   PetscFunctionReturn(0);
160989b92e6fSPeter Brune }
161089b92e6fSPeter Brune 
161189b92e6fSPeter Brune #undef __FUNCT__
16128b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction"
16138b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
16148b0a5094SBarry Smith {
16158b0a5094SBarry Smith   PetscErrorCode ierr;
1616e03ab78fSPeter Brune   DM dm;
1617e03ab78fSPeter Brune   SNESDM sdm;
16186cab3a1bSJed Brown 
16198b0a5094SBarry Smith   PetscFunctionBegin;
1620e03ab78fSPeter Brune   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1621e03ab78fSPeter Brune   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
16228b0a5094SBarry Smith   /*  A(x)*x - b(x) */
1623e03ab78fSPeter Brune   if (sdm->computepfunction) {
1624e03ab78fSPeter Brune     ierr = (*sdm->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr);
1625e03ab78fSPeter Brune   } else if (snes->dm) {
1626e03ab78fSPeter Brune     ierr = DMComputeFunction(snes->dm,x,f);CHKERRQ(ierr);
1627e03ab78fSPeter Brune   } else {
1628e03ab78fSPeter Brune     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() or SNESSetDM() before SNESPicardComputeFunction to provide Picard function.");
1629e03ab78fSPeter Brune   }
1630e03ab78fSPeter Brune 
1631e03ab78fSPeter Brune   if (sdm->computepjacobian) {
1632e03ab78fSPeter Brune     ierr = (*sdm->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,sdm->pctx);CHKERRQ(ierr);
1633e03ab78fSPeter Brune   } else if (snes->dm) {
1634e03ab78fSPeter Brune     ierr = DMComputeJacobian(snes->dm,x,snes->jacobian,snes->jacobian_pre,&snes->matstruct);CHKERRQ(ierr);
1635e03ab78fSPeter Brune   } else {
1636e03ab78fSPeter Brune     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() or SNESSetDM() before SNESPicardComputeFunction to provide Picard matrix.");
1637e03ab78fSPeter Brune   }
1638e03ab78fSPeter Brune 
16398b0a5094SBarry Smith   ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
16408b0a5094SBarry Smith   ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
16418b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
16428b0a5094SBarry Smith   ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr);
16438b0a5094SBarry Smith   PetscFunctionReturn(0);
16448b0a5094SBarry Smith }
16458b0a5094SBarry Smith 
16468b0a5094SBarry Smith #undef __FUNCT__
16478b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian"
16488b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
16498b0a5094SBarry Smith {
16508b0a5094SBarry Smith   PetscFunctionBegin;
1651e03ab78fSPeter Brune   /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */
16528b0a5094SBarry Smith   *flag = snes->matstruct;
16538b0a5094SBarry Smith   PetscFunctionReturn(0);
16548b0a5094SBarry Smith }
16558b0a5094SBarry Smith 
16568b0a5094SBarry Smith #undef __FUNCT__
16578b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard"
16588b0a5094SBarry Smith /*@C
16590d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
16608b0a5094SBarry Smith 
16618b0a5094SBarry Smith    Logically Collective on SNES
16628b0a5094SBarry Smith 
16638b0a5094SBarry Smith    Input Parameters:
16648b0a5094SBarry Smith +  snes - the SNES context
16658b0a5094SBarry Smith .  r - vector to store function value
16668b0a5094SBarry Smith .  func - function evaluation routine
16678b0a5094SBarry 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)
16688b0a5094SBarry Smith .  mat - matrix to store A
16698b0a5094SBarry Smith .  mfunc  - function to compute matrix value
16708b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
16718b0a5094SBarry Smith          function evaluation routine (may be PETSC_NULL)
16728b0a5094SBarry Smith 
16738b0a5094SBarry Smith    Calling sequence of func:
16748b0a5094SBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
16758b0a5094SBarry Smith 
16768b0a5094SBarry Smith +  f - function vector
16778b0a5094SBarry Smith -  ctx - optional user-defined function context
16788b0a5094SBarry Smith 
16798b0a5094SBarry Smith    Calling sequence of mfunc:
16808b0a5094SBarry Smith $     mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx);
16818b0a5094SBarry Smith 
16828b0a5094SBarry Smith +  x - input vector
16838b0a5094SBarry 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(),
16848b0a5094SBarry Smith           normally just pass mat in this location
16858b0a5094SBarry Smith .  mat - form A(x) matrix
16868b0a5094SBarry Smith .  flag - flag indicating information about the preconditioner matrix
16878b0a5094SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
16888b0a5094SBarry Smith -  ctx - [optional] user-defined Jacobian context
16898b0a5094SBarry Smith 
16908b0a5094SBarry Smith    Notes:
16918b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
16928b0a5094SBarry Smith 
16938b0a5094SBarry 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}
16948b0a5094SBarry 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.
16958b0a5094SBarry Smith 
16968b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
16978b0a5094SBarry Smith 
16980d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
16990d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
17008b0a5094SBarry Smith 
17018b0a5094SBarry 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
17028b0a5094SBarry 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
17038b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
17048b0a5094SBarry Smith 
17058b0a5094SBarry Smith    Level: beginner
17068b0a5094SBarry Smith 
17078b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function
17088b0a5094SBarry Smith 
17090d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard()
17108b0a5094SBarry Smith @*/
17118b0a5094SBarry 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)
17128b0a5094SBarry Smith {
17138b0a5094SBarry Smith   PetscErrorCode ierr;
1714e03ab78fSPeter Brune   DM             dm;
1715e03ab78fSPeter Brune 
17168b0a5094SBarry Smith   PetscFunctionBegin;
17178b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1718e03ab78fSPeter Brune   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
1719e03ab78fSPeter Brune   ierr = DMSNESSetPicard(dm,func,mfunc,ctx);CHKERRQ(ierr);
17208b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
17218b0a5094SBarry Smith   ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
17228b0a5094SBarry Smith   PetscFunctionReturn(0);
17238b0a5094SBarry Smith }
17248b0a5094SBarry Smith 
17257971a8bfSPeter Brune 
17267971a8bfSPeter Brune #undef __FUNCT__
17277971a8bfSPeter Brune #define __FUNCT__ "SNESGetPicard"
17287971a8bfSPeter Brune /*@C
17297971a8bfSPeter Brune    SNESGetPicard - Returns the context for the Picard iteration
17307971a8bfSPeter Brune 
17317971a8bfSPeter Brune    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
17327971a8bfSPeter Brune 
17337971a8bfSPeter Brune    Input Parameter:
17347971a8bfSPeter Brune .  snes - the SNES context
17357971a8bfSPeter Brune 
17367971a8bfSPeter Brune    Output Parameter:
17377971a8bfSPeter Brune +  r - the function (or PETSC_NULL)
17387971a8bfSPeter Brune .  func - the function (or PETSC_NULL)
17397971a8bfSPeter Brune .  jmat - the picard matrix (or PETSC_NULL)
17407971a8bfSPeter Brune .  mat  - the picard preconditioner matrix (or PETSC_NULL)
17417971a8bfSPeter Brune .  mfunc - the function for matrix evaluation (or PETSC_NULL)
17427971a8bfSPeter Brune -  ctx - the function context (or PETSC_NULL)
17437971a8bfSPeter Brune 
17447971a8bfSPeter Brune    Level: advanced
17457971a8bfSPeter Brune 
17467971a8bfSPeter Brune .keywords: SNES, nonlinear, get, function
17477971a8bfSPeter Brune 
17487971a8bfSPeter Brune .seealso: SNESSetPicard, SNESGetFunction, SNESGetJacobian, SNESGetDM
17497971a8bfSPeter Brune @*/
17507971a8bfSPeter Brune PetscErrorCode  SNESGetPicard(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),Mat *jmat, Mat *mat, PetscErrorCode (**mfunc)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
17517971a8bfSPeter Brune {
17527971a8bfSPeter Brune   PetscErrorCode ierr;
17537971a8bfSPeter Brune   DM             dm;
17547971a8bfSPeter Brune 
17557971a8bfSPeter Brune   PetscFunctionBegin;
17567971a8bfSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
17577971a8bfSPeter Brune   ierr = SNESGetFunction(snes,r,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
17587971a8bfSPeter Brune   ierr = SNESGetJacobian(snes,jmat,mat,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
17597971a8bfSPeter Brune   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
17607971a8bfSPeter Brune   ierr = DMSNESGetPicard(dm,func,mfunc,ctx);CHKERRQ(ierr);
17617971a8bfSPeter Brune   PetscFunctionReturn(0);
17627971a8bfSPeter Brune }
17637971a8bfSPeter Brune 
17648b0a5094SBarry Smith #undef __FUNCT__
1765d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess"
1766d25893d9SBarry Smith /*@C
1767d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1768d25893d9SBarry Smith 
1769d25893d9SBarry Smith    Logically Collective on SNES
1770d25893d9SBarry Smith 
1771d25893d9SBarry Smith    Input Parameters:
1772d25893d9SBarry Smith +  snes - the SNES context
1773d25893d9SBarry Smith .  func - function evaluation routine
1774d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
1775d25893d9SBarry Smith          function evaluation routine (may be PETSC_NULL)
1776d25893d9SBarry Smith 
1777d25893d9SBarry Smith    Calling sequence of func:
1778d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
1779d25893d9SBarry Smith 
1780d25893d9SBarry Smith .  f - function vector
1781d25893d9SBarry Smith -  ctx - optional user-defined function context
1782d25893d9SBarry Smith 
1783d25893d9SBarry Smith    Level: intermediate
1784d25893d9SBarry Smith 
1785d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
1786d25893d9SBarry Smith 
1787d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1788d25893d9SBarry Smith @*/
1789d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1790d25893d9SBarry Smith {
1791d25893d9SBarry Smith   PetscFunctionBegin;
1792d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1793d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
1794d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
1795d25893d9SBarry Smith   PetscFunctionReturn(0);
1796d25893d9SBarry Smith }
1797d25893d9SBarry Smith 
17983ab0aad5SBarry Smith /* --------------------------------------------------------------- */
17993ab0aad5SBarry Smith #undef __FUNCT__
18001096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
18011096aae1SMatthew Knepley /*@C
18021096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
18031096aae1SMatthew Knepley    it assumes a zero right hand side.
18041096aae1SMatthew Knepley 
18053f9fe445SBarry Smith    Logically Collective on SNES
18061096aae1SMatthew Knepley 
18071096aae1SMatthew Knepley    Input Parameter:
18081096aae1SMatthew Knepley .  snes - the SNES context
18091096aae1SMatthew Knepley 
18101096aae1SMatthew Knepley    Output Parameter:
1811bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
18121096aae1SMatthew Knepley 
18131096aae1SMatthew Knepley    Level: intermediate
18141096aae1SMatthew Knepley 
18151096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
18161096aae1SMatthew Knepley 
181785385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
18181096aae1SMatthew Knepley @*/
18197087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
18201096aae1SMatthew Knepley {
18211096aae1SMatthew Knepley   PetscFunctionBegin;
18220700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
18231096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
182485385478SLisandro Dalcin   *rhs = snes->vec_rhs;
18251096aae1SMatthew Knepley   PetscFunctionReturn(0);
18261096aae1SMatthew Knepley }
18271096aae1SMatthew Knepley 
18281096aae1SMatthew Knepley #undef __FUNCT__
18294a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
18309b94acceSBarry Smith /*@
183136851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
18329b94acceSBarry Smith                          SNESSetFunction().
18339b94acceSBarry Smith 
1834c7afd0dbSLois Curfman McInnes    Collective on SNES
1835c7afd0dbSLois Curfman McInnes 
18369b94acceSBarry Smith    Input Parameters:
1837c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1838c7afd0dbSLois Curfman McInnes -  x - input vector
18399b94acceSBarry Smith 
18409b94acceSBarry Smith    Output Parameter:
18413638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
18429b94acceSBarry Smith 
18431bffabb2SLois Curfman McInnes    Notes:
184436851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
184536851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
184636851e7fSLois Curfman McInnes    themselves.
184736851e7fSLois Curfman McInnes 
184836851e7fSLois Curfman McInnes    Level: developer
184936851e7fSLois Curfman McInnes 
18509b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
18519b94acceSBarry Smith 
1852a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
18539b94acceSBarry Smith @*/
18547087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
18559b94acceSBarry Smith {
1856dfbe8321SBarry Smith   PetscErrorCode ierr;
18576cab3a1bSJed Brown   DM             dm;
18586cab3a1bSJed Brown   SNESDM         sdm;
18599b94acceSBarry Smith 
18603a40ed3dSBarry Smith   PetscFunctionBegin;
18610700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
18620700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
18630700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
1864c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
1865c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
18664ec14c9cSBarry Smith   VecValidValues(x,2,PETSC_TRUE);
1867184914b5SBarry Smith 
18686cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
18696cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
1870d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
18716cab3a1bSJed Brown   if (sdm->computefunction) {
1872d64ed03dSBarry Smith     PetscStackPush("SNES user function");
18736cab3a1bSJed Brown     ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
1874d64ed03dSBarry Smith     PetscStackPop;
187573250ac0SBarry Smith   } else if (snes->dm) {
1876644e2e5bSBarry Smith     ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr);
1877c90fad12SPeter Brune   } else if (snes->vec_rhs) {
1878c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
1879644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
188085385478SLisandro Dalcin   if (snes->vec_rhs) {
188185385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
18823ab0aad5SBarry Smith   }
1883ae3c334cSLois Curfman McInnes   snes->nfuncs++;
1884d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
18854ec14c9cSBarry Smith   VecValidValues(y,3,PETSC_FALSE);
18863a40ed3dSBarry Smith   PetscFunctionReturn(0);
18879b94acceSBarry Smith }
18889b94acceSBarry Smith 
18894a2ae208SSatish Balay #undef __FUNCT__
1890646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS"
1891c79ef259SPeter Brune /*@
1892c79ef259SPeter Brune    SNESComputeGS - Calls the Gauss-Seidel function that has been set with
1893c79ef259SPeter Brune                    SNESSetGS().
1894c79ef259SPeter Brune 
1895c79ef259SPeter Brune    Collective on SNES
1896c79ef259SPeter Brune 
1897c79ef259SPeter Brune    Input Parameters:
1898c79ef259SPeter Brune +  snes - the SNES context
1899c79ef259SPeter Brune .  x - input vector
1900c79ef259SPeter Brune -  b - rhs vector
1901c79ef259SPeter Brune 
1902c79ef259SPeter Brune    Output Parameter:
1903c79ef259SPeter Brune .  x - new solution vector
1904c79ef259SPeter Brune 
1905c79ef259SPeter Brune    Notes:
1906c79ef259SPeter Brune    SNESComputeGS() is typically used within composed nonlinear solver
1907c79ef259SPeter Brune    implementations, so most users would not generally call this routine
1908c79ef259SPeter Brune    themselves.
1909c79ef259SPeter Brune 
1910c79ef259SPeter Brune    Level: developer
1911c79ef259SPeter Brune 
1912c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function
1913c79ef259SPeter Brune 
1914c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction()
1915c79ef259SPeter Brune @*/
1916646217ecSPeter Brune PetscErrorCode  SNESComputeGS(SNES snes,Vec b,Vec x)
1917646217ecSPeter Brune {
1918646217ecSPeter Brune   PetscErrorCode ierr;
191989b92e6fSPeter Brune   PetscInt i;
19206cab3a1bSJed Brown   DM dm;
19216cab3a1bSJed Brown   SNESDM sdm;
1922646217ecSPeter Brune 
1923646217ecSPeter Brune   PetscFunctionBegin;
1924646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1925646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
1926646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
1927646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
1928646217ecSPeter Brune   if(b) PetscCheckSameComm(snes,1,b,3);
19294ec14c9cSBarry Smith   if (b) VecValidValues(b,2,PETSC_TRUE);
1930701cf23dSPeter Brune   ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
19316cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
19326cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
19336cab3a1bSJed Brown   if (sdm->computegs) {
193489b92e6fSPeter Brune     for (i = 0; i < snes->gssweeps; i++) {
1935646217ecSPeter Brune       PetscStackPush("SNES user GS");
19366cab3a1bSJed Brown       ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
1937646217ecSPeter Brune       PetscStackPop;
193889b92e6fSPeter Brune     }
1939646217ecSPeter Brune   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve().");
1940701cf23dSPeter Brune   ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
19414ec14c9cSBarry Smith   VecValidValues(x,3,PETSC_FALSE);
1942646217ecSPeter Brune   PetscFunctionReturn(0);
1943646217ecSPeter Brune }
1944646217ecSPeter Brune 
1945646217ecSPeter Brune 
1946646217ecSPeter Brune #undef __FUNCT__
19474a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
194862fef451SLois Curfman McInnes /*@
194962fef451SLois Curfman McInnes    SNESComputeJacobian - Computes the Jacobian matrix that has been
195062fef451SLois Curfman McInnes    set with SNESSetJacobian().
195162fef451SLois Curfman McInnes 
1952c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
1953c7afd0dbSLois Curfman McInnes 
195462fef451SLois Curfman McInnes    Input Parameters:
1955c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1956c7afd0dbSLois Curfman McInnes -  x - input vector
195762fef451SLois Curfman McInnes 
195862fef451SLois Curfman McInnes    Output Parameters:
1959c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
196062fef451SLois Curfman McInnes .  B - optional preconditioning matrix
19612b668275SBarry Smith -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1962fee21e36SBarry Smith 
1963e35cf81dSBarry Smith   Options Database Keys:
1964e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
1965693365a8SJed Brown .    -snes_lag_jacobian <lag>
1966693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
1967693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
1968693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
19694c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
1970c01495d3SJed Brown .    -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference
1971c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
1972c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
1973c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
1974c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
19754c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
1976c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
1977c01495d3SJed Brown 
1978e35cf81dSBarry Smith 
197962fef451SLois Curfman McInnes    Notes:
198062fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
198162fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
198262fef451SLois Curfman McInnes 
198394b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the
1984dc5a77f8SLois Curfman McInnes    flag parameter.
198562fef451SLois Curfman McInnes 
198636851e7fSLois Curfman McInnes    Level: developer
198736851e7fSLois Curfman McInnes 
198862fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
198962fef451SLois Curfman McInnes 
1990e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
199162fef451SLois Curfman McInnes @*/
19927087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
19939b94acceSBarry Smith {
1994dfbe8321SBarry Smith   PetscErrorCode ierr;
1995ace3abfcSBarry Smith   PetscBool      flag;
19966cab3a1bSJed Brown   DM             dm;
19976cab3a1bSJed Brown   SNESDM         sdm;
19983a40ed3dSBarry Smith 
19993a40ed3dSBarry Smith   PetscFunctionBegin;
20000700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
20010700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
20024482741eSBarry Smith   PetscValidPointer(flg,5);
2003c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
20044ec14c9cSBarry Smith   VecValidValues(X,2,PETSC_TRUE);
20056cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
20066cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
20076cab3a1bSJed Brown   if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
2008ebd3b9afSBarry Smith 
2009ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
2010ebd3b9afSBarry Smith 
2011fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
2012fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
2013fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
2014fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
2015e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
2016e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
2017251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
2018ebd3b9afSBarry Smith     if (flag) {
2019ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2020ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2021ebd3b9afSBarry Smith     }
2022e35cf81dSBarry Smith     PetscFunctionReturn(0);
2023e35cf81dSBarry Smith   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
2024e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
2025e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
2026251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
2027ebd3b9afSBarry Smith     if (flag) {
2028ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2029ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2030ebd3b9afSBarry Smith     }
2031e35cf81dSBarry Smith     PetscFunctionReturn(0);
2032e35cf81dSBarry Smith   }
2033e35cf81dSBarry Smith 
2034c4fc05e7SBarry Smith   *flg = DIFFERENT_NONZERO_PATTERN;
2035e35cf81dSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
2036d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
20376cab3a1bSJed Brown   ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr);
2038d64ed03dSBarry Smith   PetscStackPop;
2039d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
2040a8054027SBarry Smith 
20413b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
20423b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
20433b4f5425SBarry Smith     snes->lagpreconditioner = -1;
20443b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
2045a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
2046a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
2047a8054027SBarry Smith   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
2048a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
2049a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
2050a8054027SBarry Smith   }
2051a8054027SBarry Smith 
20526d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
20530700a824SBarry Smith   /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
20540700a824SBarry Smith     PetscValidHeaderSpecific(*B,MAT_CLASSID,4);   */
2055693365a8SJed Brown   {
2056693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
2057693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr);
2058693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
2059693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
2060693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr);
2061693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
2062693365a8SJed Brown       Mat Bexp_mine = PETSC_NULL,Bexp,FDexp;
2063693365a8SJed Brown       MatStructure mstruct;
2064693365a8SJed Brown       PetscViewer vdraw,vstdout;
20656b3a5b13SJed Brown       PetscBool flg;
2066693365a8SJed Brown       if (flag_operator) {
2067693365a8SJed Brown         ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr);
2068693365a8SJed Brown         Bexp = Bexp_mine;
2069693365a8SJed Brown       } else {
2070693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
2071251f4c67SDmitry Karpeev         ierr = PetscObjectTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
2072693365a8SJed Brown         if (flg) Bexp = *B;
2073693365a8SJed Brown         else {
2074693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
2075693365a8SJed Brown           ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr);
2076693365a8SJed Brown           Bexp = Bexp_mine;
2077693365a8SJed Brown         }
2078693365a8SJed Brown       }
2079693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
2080693365a8SJed Brown       ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr);
2081693365a8SJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
2082693365a8SJed Brown       if (flag_draw || flag_contour) {
2083693365a8SJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
2084693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
2085693365a8SJed Brown       } else vdraw = PETSC_NULL;
2086693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr);
2087693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
2088693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
2089693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
2090693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2091693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
2092693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2093693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
2094693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2095693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
2096693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
2097693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
2098693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
2099693365a8SJed Brown       }
2100693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
2101693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
2102693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
2103693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
2104693365a8SJed Brown     }
2105693365a8SJed Brown   }
21064c30e9fbSJed Brown   {
21076719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
21086719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
21094c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr);
21106719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr);
21114c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
21124c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
21136719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr);
21146719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr);
21156719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr);
21166719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
21174c30e9fbSJed Brown       Mat Bfd;
21184c30e9fbSJed Brown       MatStructure mstruct;
21194c30e9fbSJed Brown       PetscViewer vdraw,vstdout;
21204c30e9fbSJed Brown       ISColoring iscoloring;
21214c30e9fbSJed Brown       MatFDColoring matfdcoloring;
21224c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
21234c30e9fbSJed Brown       void *funcctx;
21246719d8e4SJed Brown       PetscReal norm1,norm2,normmax;
21254c30e9fbSJed Brown 
21264c30e9fbSJed Brown       ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
21274c30e9fbSJed Brown       ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
21284c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
21294c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
21304c30e9fbSJed Brown 
21314c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
21324c30e9fbSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr);
21334c30e9fbSJed Brown       ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr);
21344c30e9fbSJed Brown       ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
21354c30e9fbSJed Brown       ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
21364c30e9fbSJed Brown       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
21374c30e9fbSJed Brown       ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr);
21384c30e9fbSJed Brown       ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
21394c30e9fbSJed Brown 
21404c30e9fbSJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
21414c30e9fbSJed Brown       if (flag_draw || flag_contour) {
21424c30e9fbSJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
21434c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
21444c30e9fbSJed Brown       } else vdraw = PETSC_NULL;
21454c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
21466719d8e4SJed Brown       if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);}
21474c30e9fbSJed Brown       if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);}
21484c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
21496719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
21504c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
21514c30e9fbSJed Brown       ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
21524c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
21536719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
21544c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
21556719d8e4SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr);
21566719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
21574c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
21584c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
21594c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
21604c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
21614c30e9fbSJed Brown       }
21624c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
21636719d8e4SJed Brown 
21646719d8e4SJed Brown       if (flag_threshold) {
21656719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
21666719d8e4SJed Brown         ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr);
21676719d8e4SJed Brown         ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr);
21686719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
21696719d8e4SJed Brown           const PetscScalar *ba,*ca;
21706719d8e4SJed Brown           const PetscInt *bj,*cj;
21716719d8e4SJed Brown           PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
21726719d8e4SJed Brown           PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0;
21736719d8e4SJed Brown           ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
21746719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
21756719d8e4SJed Brown           if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
21766719d8e4SJed Brown           for (j=0; j<bn; j++) {
21776719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
21786719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
21796719d8e4SJed Brown               maxentrycol = bj[j];
21806719d8e4SJed Brown               maxentry = PetscRealPart(ba[j]);
21816719d8e4SJed Brown             }
21826719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
21836719d8e4SJed Brown               maxdiffcol = bj[j];
21846719d8e4SJed Brown               maxdiff = PetscRealPart(ca[j]);
21856719d8e4SJed Brown             }
21866719d8e4SJed Brown             if (rdiff > maxrdiff) {
21876719d8e4SJed Brown               maxrdiffcol = bj[j];
21886719d8e4SJed Brown               maxrdiff = rdiff;
21896719d8e4SJed Brown             }
21906719d8e4SJed Brown           }
21916719d8e4SJed Brown           if (maxrdiff > 1) {
21926719d8e4SJed 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);
21936719d8e4SJed Brown             for (j=0; j<bn; j++) {
21946719d8e4SJed Brown               PetscReal rdiff;
21956719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
21966719d8e4SJed Brown               if (rdiff > 1) {
21976719d8e4SJed Brown                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr);
21986719d8e4SJed Brown               }
21996719d8e4SJed Brown             }
22006719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
22016719d8e4SJed Brown           }
22026719d8e4SJed Brown           ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
22036719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
22046719d8e4SJed Brown         }
22056719d8e4SJed Brown       }
22064c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
22074c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
22084c30e9fbSJed Brown     }
22094c30e9fbSJed Brown   }
22103a40ed3dSBarry Smith   PetscFunctionReturn(0);
22119b94acceSBarry Smith }
22129b94acceSBarry Smith 
22134a2ae208SSatish Balay #undef __FUNCT__
22144a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
22159b94acceSBarry Smith /*@C
22169b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2217044dda88SLois Curfman McInnes    location to store the matrix.
22189b94acceSBarry Smith 
22193f9fe445SBarry Smith    Logically Collective on SNES and Mat
2220c7afd0dbSLois Curfman McInnes 
22219b94acceSBarry Smith    Input Parameters:
2222c7afd0dbSLois Curfman McInnes +  snes - the SNES context
22239b94acceSBarry Smith .  A - Jacobian matrix
22249b94acceSBarry Smith .  B - preconditioner matrix (usually same as the Jacobian)
2225efd51863SBarry Smith .  func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value)
2226c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
2227efd51863SBarry Smith          Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value)
22289b94acceSBarry Smith 
22299b94acceSBarry Smith    Calling sequence of func:
22308d76a1e5SLois Curfman McInnes $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
22319b94acceSBarry Smith 
2232c7afd0dbSLois Curfman McInnes +  x - input vector
22339b94acceSBarry Smith .  A - Jacobian matrix
22349b94acceSBarry Smith .  B - preconditioner matrix, usually the same as A
2235ac21db08SLois Curfman McInnes .  flag - flag indicating information about the preconditioner matrix
22362b668275SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
2237c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined Jacobian context
22389b94acceSBarry Smith 
22399b94acceSBarry Smith    Notes:
224094b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the flag
22412cd2dfdcSLois Curfman McInnes    output parameter in the routine func().  Be sure to read this information!
2242ac21db08SLois Curfman McInnes 
2243ac21db08SLois Curfman McInnes    The routine func() takes Mat * as the matrix arguments rather than Mat.
22449b94acceSBarry Smith    This allows the Jacobian evaluation routine to replace A and/or B with a
22459b94acceSBarry Smith    completely new new matrix structure (not just different matrix elements)
22469b94acceSBarry Smith    when appropriate, for instance, if the nonzero structure is changing
22479b94acceSBarry Smith    throughout the global iterations.
22489b94acceSBarry Smith 
224916913363SBarry Smith    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
225016913363SBarry Smith    each matrix.
225116913363SBarry Smith 
2252a8a26c1eSJed Brown    If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument
2253a8a26c1eSJed Brown    must be a MatFDColoring.
2254a8a26c1eSJed Brown 
2255c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2256c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2257c3cc8fd1SJed Brown 
225836851e7fSLois Curfman McInnes    Level: beginner
225936851e7fSLois Curfman McInnes 
22609b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
22619b94acceSBarry Smith 
22623ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
22639b94acceSBarry Smith @*/
22647087cfbeSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
22659b94acceSBarry Smith {
2266dfbe8321SBarry Smith   PetscErrorCode ierr;
22676cab3a1bSJed Brown   DM             dm;
22683a7fca6bSBarry Smith 
22693a40ed3dSBarry Smith   PetscFunctionBegin;
22700700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
22710700a824SBarry Smith   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
22720700a824SBarry Smith   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
2273c9780b6fSBarry Smith   if (A) PetscCheckSameComm(snes,1,A,2);
227406975374SJed Brown   if (B) PetscCheckSameComm(snes,1,B,3);
22756cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
22766cab3a1bSJed Brown   ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr);
22773a7fca6bSBarry Smith   if (A) {
22787dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
22796bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
22809b94acceSBarry Smith     snes->jacobian = A;
22813a7fca6bSBarry Smith   }
22823a7fca6bSBarry Smith   if (B) {
22837dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
22846bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
22859b94acceSBarry Smith     snes->jacobian_pre = B;
22863a7fca6bSBarry Smith   }
22873a40ed3dSBarry Smith   PetscFunctionReturn(0);
22889b94acceSBarry Smith }
228962fef451SLois Curfman McInnes 
22904a2ae208SSatish Balay #undef __FUNCT__
22914a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
2292c2aafc4cSSatish Balay /*@C
2293b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2294b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2295b4fd4287SBarry Smith 
2296c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2297c7afd0dbSLois Curfman McInnes 
2298b4fd4287SBarry Smith    Input Parameter:
2299b4fd4287SBarry Smith .  snes - the nonlinear solver context
2300b4fd4287SBarry Smith 
2301b4fd4287SBarry Smith    Output Parameters:
2302c7afd0dbSLois Curfman McInnes +  A - location to stash Jacobian matrix (or PETSC_NULL)
2303b4fd4287SBarry Smith .  B - location to stash preconditioner matrix (or PETSC_NULL)
230470e92668SMatthew Knepley .  func - location to put Jacobian function (or PETSC_NULL)
230570e92668SMatthew Knepley -  ctx - location to stash Jacobian ctx (or PETSC_NULL)
2306fee21e36SBarry Smith 
230736851e7fSLois Curfman McInnes    Level: advanced
230836851e7fSLois Curfman McInnes 
2309b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian()
2310b4fd4287SBarry Smith @*/
23117087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
2312b4fd4287SBarry Smith {
23136cab3a1bSJed Brown   PetscErrorCode ierr;
23146cab3a1bSJed Brown   DM             dm;
23156cab3a1bSJed Brown   SNESDM         sdm;
23166cab3a1bSJed Brown 
23173a40ed3dSBarry Smith   PetscFunctionBegin;
23180700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2319b4fd4287SBarry Smith   if (A)    *A    = snes->jacobian;
2320b4fd4287SBarry Smith   if (B)    *B    = snes->jacobian_pre;
23216cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
23226cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
23236cab3a1bSJed Brown   if (func) *func = sdm->computejacobian;
23246cab3a1bSJed Brown   if (ctx)  *ctx  = sdm->jacobianctx;
23253a40ed3dSBarry Smith   PetscFunctionReturn(0);
2326b4fd4287SBarry Smith }
2327b4fd4287SBarry Smith 
23289b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
23299b94acceSBarry Smith 
23304a2ae208SSatish Balay #undef __FUNCT__
23314a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
23329b94acceSBarry Smith /*@
23339b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
2334272ac6f2SLois Curfman McInnes    of a nonlinear solver.
23359b94acceSBarry Smith 
2336fee21e36SBarry Smith    Collective on SNES
2337fee21e36SBarry Smith 
2338c7afd0dbSLois Curfman McInnes    Input Parameters:
233970e92668SMatthew Knepley .  snes - the SNES context
2340c7afd0dbSLois Curfman McInnes 
2341272ac6f2SLois Curfman McInnes    Notes:
2342272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
2343272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
2344272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
2345272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
2346272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
2347272ac6f2SLois Curfman McInnes 
234836851e7fSLois Curfman McInnes    Level: advanced
234936851e7fSLois Curfman McInnes 
23509b94acceSBarry Smith .keywords: SNES, nonlinear, setup
23519b94acceSBarry Smith 
23529b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
23539b94acceSBarry Smith @*/
23547087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
23559b94acceSBarry Smith {
2356dfbe8321SBarry Smith   PetscErrorCode ierr;
23576cab3a1bSJed Brown   DM             dm;
23586cab3a1bSJed Brown   SNESDM         sdm;
23596e2a1849SPeter Brune   SNESLineSearch              linesearch;
23606e2a1849SPeter Brune   SNESLineSearch              pclinesearch;
23616e2a1849SPeter Brune   void                        *lsprectx,*lspostctx;
23626e2a1849SPeter Brune   SNESLineSearchPreCheckFunc  lsprefunc;
23636e2a1849SPeter Brune   SNESLineSearchPostCheckFunc lspostfunc;
23646e2a1849SPeter Brune   PetscErrorCode              (*func)(SNES,Vec,Vec,void*);
23656e2a1849SPeter Brune   Vec                         f,fpc;
23666e2a1849SPeter Brune   void                        *funcctx;
23676e2a1849SPeter Brune   PetscErrorCode              (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*);
23686e2a1849SPeter Brune   void                        *jacctx;
23696e2a1849SPeter Brune   Mat                         A,B;
23703a40ed3dSBarry Smith 
23713a40ed3dSBarry Smith   PetscFunctionBegin;
23720700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
23734dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
23749b94acceSBarry Smith 
23757adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
237685385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
237785385478SLisandro Dalcin   }
237885385478SLisandro Dalcin 
2379a63bb30eSJed Brown   ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
238017186662SBarry Smith   if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
238158c9b817SLisandro Dalcin   if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
238258c9b817SLisandro Dalcin 
238358c9b817SLisandro Dalcin   if (!snes->vec_sol_update /* && snes->vec_sol */) {
238458c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
238558c9b817SLisandro Dalcin     ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr);
238658c9b817SLisandro Dalcin   }
238758c9b817SLisandro Dalcin 
23886cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
23896cab3a1bSJed Brown   ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */
23906cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
23916cab3a1bSJed Brown   if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc");
23926cab3a1bSJed Brown   if (!snes->vec_func) {
23936cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2394214df951SJed Brown   }
2395efd51863SBarry Smith 
2396b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
2397b710008aSBarry Smith 
2398f1c6b773SPeter Brune   if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);}
23999e764e56SPeter Brune 
2400d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
2401d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
2402d25893d9SBarry Smith   }
2403d25893d9SBarry Smith 
24046e2a1849SPeter Brune   if (snes->pc) {
24056e2a1849SPeter Brune     /* copy the DM over */
24066e2a1849SPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
24076e2a1849SPeter Brune     ierr = SNESSetDM(snes->pc,dm);CHKERRQ(ierr);
24086e2a1849SPeter Brune 
24096e2a1849SPeter Brune     /* copy the legacy SNES context not related to the DM over*/
24106e2a1849SPeter Brune     ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr);
24116e2a1849SPeter Brune     ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr);
24126e2a1849SPeter Brune     ierr = SNESSetFunction(snes->pc,fpc,func,funcctx);CHKERRQ(ierr);
24136e2a1849SPeter Brune     ierr = SNESGetJacobian(snes,&A,&B,&jac,&jacctx);CHKERRQ(ierr);
24146e2a1849SPeter Brune     ierr = SNESSetJacobian(snes->pc,A,B,jac,jacctx);CHKERRQ(ierr);
24156e2a1849SPeter Brune     ierr = VecDestroy(&fpc);CHKERRQ(ierr);
24166e2a1849SPeter Brune 
24176e2a1849SPeter Brune     /* copy the function pointers over */
24186e2a1849SPeter Brune     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr);
24196e2a1849SPeter Brune 
24206e2a1849SPeter Brune      /* default to 1 iteration */
2421*140836e4SPeter Brune     ierr = SNESSetTolerances(snes->pc, 0.0, 0.0, 0.0, 1, snes->pc->max_funcs);CHKERRQ(ierr);
24226e2a1849SPeter Brune     ierr = SNESSetNormType(snes->pc, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr);
24236e2a1849SPeter Brune     ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr);
24246e2a1849SPeter Brune 
24256e2a1849SPeter Brune     /* copy the line search context over */
24266e2a1849SPeter Brune     ierr = SNESGetSNESLineSearch(snes,&linesearch);CHKERRQ(ierr);
24276e2a1849SPeter Brune     ierr = SNESGetSNESLineSearch(snes->pc,&pclinesearch);CHKERRQ(ierr);
24286e2a1849SPeter Brune     ierr = SNESLineSearchGetPreCheck(linesearch,&lsprefunc,&lsprectx);CHKERRQ(ierr);
24296e2a1849SPeter Brune     ierr = SNESLineSearchGetPostCheck(linesearch,&lspostfunc,&lspostctx);CHKERRQ(ierr);
24306e2a1849SPeter Brune     ierr = SNESLineSearchSetPreCheck(pclinesearch,lsprefunc,lsprectx);CHKERRQ(ierr);
24316e2a1849SPeter Brune     ierr = SNESLineSearchSetPostCheck(pclinesearch,lspostfunc,lspostctx);CHKERRQ(ierr);
24326e2a1849SPeter Brune     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr);
24336e2a1849SPeter Brune   }
24346e2a1849SPeter Brune 
2435410397dcSLisandro Dalcin   if (snes->ops->setup) {
2436410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2437410397dcSLisandro Dalcin   }
243858c9b817SLisandro Dalcin 
24397aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
24403a40ed3dSBarry Smith   PetscFunctionReturn(0);
24419b94acceSBarry Smith }
24429b94acceSBarry Smith 
24434a2ae208SSatish Balay #undef __FUNCT__
244437596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
244537596af1SLisandro Dalcin /*@
244637596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
244737596af1SLisandro Dalcin 
244837596af1SLisandro Dalcin    Collective on SNES
244937596af1SLisandro Dalcin 
245037596af1SLisandro Dalcin    Input Parameter:
245137596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
245237596af1SLisandro Dalcin 
2453d25893d9SBarry Smith    Level: intermediate
2454d25893d9SBarry Smith 
2455d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
245637596af1SLisandro Dalcin 
245737596af1SLisandro Dalcin .keywords: SNES, destroy
245837596af1SLisandro Dalcin 
245937596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
246037596af1SLisandro Dalcin @*/
246137596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
246237596af1SLisandro Dalcin {
246337596af1SLisandro Dalcin   PetscErrorCode ierr;
246437596af1SLisandro Dalcin 
246537596af1SLisandro Dalcin   PetscFunctionBegin;
246637596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2467d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
2468d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
2469d25893d9SBarry Smith     snes->user = PETSC_NULL;
2470d25893d9SBarry Smith   }
24718a23116dSBarry Smith   if (snes->pc) {
24728a23116dSBarry Smith     ierr = SNESReset(snes->pc);CHKERRQ(ierr);
24738a23116dSBarry Smith   }
24748a23116dSBarry Smith 
247537596af1SLisandro Dalcin   if (snes->ops->reset) {
247637596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
247737596af1SLisandro Dalcin   }
24789e764e56SPeter Brune   if (snes->ksp) {
24799e764e56SPeter Brune     ierr = KSPReset(snes->ksp);CHKERRQ(ierr);
24809e764e56SPeter Brune   }
24819e764e56SPeter Brune 
24829e764e56SPeter Brune   if (snes->linesearch) {
2483f1c6b773SPeter Brune     ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr);
24849e764e56SPeter Brune   }
24859e764e56SPeter Brune 
24866bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
24876bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
24886bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
24896bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
24906bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
24916bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2492c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
2493c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
249437596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
249537596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
249637596af1SLisandro Dalcin   PetscFunctionReturn(0);
249737596af1SLisandro Dalcin }
249837596af1SLisandro Dalcin 
249937596af1SLisandro Dalcin #undef __FUNCT__
25004a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
250152baeb72SSatish Balay /*@
25029b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
25039b94acceSBarry Smith    with SNESCreate().
25049b94acceSBarry Smith 
2505c7afd0dbSLois Curfman McInnes    Collective on SNES
2506c7afd0dbSLois Curfman McInnes 
25079b94acceSBarry Smith    Input Parameter:
25089b94acceSBarry Smith .  snes - the SNES context
25099b94acceSBarry Smith 
251036851e7fSLois Curfman McInnes    Level: beginner
251136851e7fSLois Curfman McInnes 
25129b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
25139b94acceSBarry Smith 
251463a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
25159b94acceSBarry Smith @*/
25166bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
25179b94acceSBarry Smith {
25186849ba73SBarry Smith   PetscErrorCode ierr;
25193a40ed3dSBarry Smith 
25203a40ed3dSBarry Smith   PetscFunctionBegin;
25216bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
25226bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
25236bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2524d4bb536fSBarry Smith 
25256bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
25268a23116dSBarry Smith   ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr);
25276b8b9a38SLisandro Dalcin 
2528be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
25296bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
25306bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
25316d4c513bSLisandro Dalcin 
25326bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
25336bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
2534f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr);
25356b8b9a38SLisandro Dalcin 
25366bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
25376bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
25386bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
25396b8b9a38SLisandro Dalcin   }
25406bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
25416bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
25426bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
254358c9b817SLisandro Dalcin   }
25446bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2545a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
25463a40ed3dSBarry Smith  PetscFunctionReturn(0);
25479b94acceSBarry Smith }
25489b94acceSBarry Smith 
25499b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
25509b94acceSBarry Smith 
25514a2ae208SSatish Balay #undef __FUNCT__
2552a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
2553a8054027SBarry Smith /*@
2554a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2555a8054027SBarry Smith 
25563f9fe445SBarry Smith    Logically Collective on SNES
2557a8054027SBarry Smith 
2558a8054027SBarry Smith    Input Parameters:
2559a8054027SBarry Smith +  snes - the SNES context
2560a8054027SBarry 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
25613b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2562a8054027SBarry Smith 
2563a8054027SBarry Smith    Options Database Keys:
2564a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2565a8054027SBarry Smith 
2566a8054027SBarry Smith    Notes:
2567a8054027SBarry Smith    The default is 1
2568a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2569a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2570a8054027SBarry Smith 
2571a8054027SBarry Smith    Level: intermediate
2572a8054027SBarry Smith 
2573a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2574a8054027SBarry Smith 
2575e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2576a8054027SBarry Smith 
2577a8054027SBarry Smith @*/
25787087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2579a8054027SBarry Smith {
2580a8054027SBarry Smith   PetscFunctionBegin;
25810700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2582e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2583e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2584c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2585a8054027SBarry Smith   snes->lagpreconditioner = lag;
2586a8054027SBarry Smith   PetscFunctionReturn(0);
2587a8054027SBarry Smith }
2588a8054027SBarry Smith 
2589a8054027SBarry Smith #undef __FUNCT__
2590efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
2591efd51863SBarry Smith /*@
2592efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2593efd51863SBarry Smith 
2594efd51863SBarry Smith    Logically Collective on SNES
2595efd51863SBarry Smith 
2596efd51863SBarry Smith    Input Parameters:
2597efd51863SBarry Smith +  snes - the SNES context
2598efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
2599efd51863SBarry Smith 
2600efd51863SBarry Smith    Options Database Keys:
2601efd51863SBarry Smith .    -snes_grid_sequence <steps>
2602efd51863SBarry Smith 
2603efd51863SBarry Smith    Level: intermediate
2604efd51863SBarry Smith 
2605c0df2a02SJed Brown    Notes:
2606c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2607c0df2a02SJed Brown 
2608efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2609efd51863SBarry Smith 
2610efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2611efd51863SBarry Smith 
2612efd51863SBarry Smith @*/
2613efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2614efd51863SBarry Smith {
2615efd51863SBarry Smith   PetscFunctionBegin;
2616efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2617efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
2618efd51863SBarry Smith   snes->gridsequence = steps;
2619efd51863SBarry Smith   PetscFunctionReturn(0);
2620efd51863SBarry Smith }
2621efd51863SBarry Smith 
2622efd51863SBarry Smith #undef __FUNCT__
2623a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
2624a8054027SBarry Smith /*@
2625a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
2626a8054027SBarry Smith 
26273f9fe445SBarry Smith    Not Collective
2628a8054027SBarry Smith 
2629a8054027SBarry Smith    Input Parameter:
2630a8054027SBarry Smith .  snes - the SNES context
2631a8054027SBarry Smith 
2632a8054027SBarry Smith    Output Parameter:
2633a8054027SBarry 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
26343b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2635a8054027SBarry Smith 
2636a8054027SBarry Smith    Options Database Keys:
2637a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2638a8054027SBarry Smith 
2639a8054027SBarry Smith    Notes:
2640a8054027SBarry Smith    The default is 1
2641a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2642a8054027SBarry Smith 
2643a8054027SBarry Smith    Level: intermediate
2644a8054027SBarry Smith 
2645a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2646a8054027SBarry Smith 
2647a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
2648a8054027SBarry Smith 
2649a8054027SBarry Smith @*/
26507087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
2651a8054027SBarry Smith {
2652a8054027SBarry Smith   PetscFunctionBegin;
26530700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2654a8054027SBarry Smith   *lag = snes->lagpreconditioner;
2655a8054027SBarry Smith   PetscFunctionReturn(0);
2656a8054027SBarry Smith }
2657a8054027SBarry Smith 
2658a8054027SBarry Smith #undef __FUNCT__
2659e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
2660e35cf81dSBarry Smith /*@
2661e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
2662e35cf81dSBarry Smith      often the preconditioner is rebuilt.
2663e35cf81dSBarry Smith 
26643f9fe445SBarry Smith    Logically Collective on SNES
2665e35cf81dSBarry Smith 
2666e35cf81dSBarry Smith    Input Parameters:
2667e35cf81dSBarry Smith +  snes - the SNES context
2668e35cf81dSBarry 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
2669fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
2670e35cf81dSBarry Smith 
2671e35cf81dSBarry Smith    Options Database Keys:
2672e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2673e35cf81dSBarry Smith 
2674e35cf81dSBarry Smith    Notes:
2675e35cf81dSBarry Smith    The default is 1
2676e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2677fe3ffe1eSBarry 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
2678fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
2679e35cf81dSBarry Smith 
2680e35cf81dSBarry Smith    Level: intermediate
2681e35cf81dSBarry Smith 
2682e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2683e35cf81dSBarry Smith 
2684e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
2685e35cf81dSBarry Smith 
2686e35cf81dSBarry Smith @*/
26877087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
2688e35cf81dSBarry Smith {
2689e35cf81dSBarry Smith   PetscFunctionBegin;
26900700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2691e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2692e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2693c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2694e35cf81dSBarry Smith   snes->lagjacobian = lag;
2695e35cf81dSBarry Smith   PetscFunctionReturn(0);
2696e35cf81dSBarry Smith }
2697e35cf81dSBarry Smith 
2698e35cf81dSBarry Smith #undef __FUNCT__
2699e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
2700e35cf81dSBarry Smith /*@
2701e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
2702e35cf81dSBarry Smith 
27033f9fe445SBarry Smith    Not Collective
2704e35cf81dSBarry Smith 
2705e35cf81dSBarry Smith    Input Parameter:
2706e35cf81dSBarry Smith .  snes - the SNES context
2707e35cf81dSBarry Smith 
2708e35cf81dSBarry Smith    Output Parameter:
2709e35cf81dSBarry 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
2710e35cf81dSBarry Smith          the Jacobian is built etc.
2711e35cf81dSBarry Smith 
2712e35cf81dSBarry Smith    Options Database Keys:
2713e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2714e35cf81dSBarry Smith 
2715e35cf81dSBarry Smith    Notes:
2716e35cf81dSBarry Smith    The default is 1
2717e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2718e35cf81dSBarry Smith 
2719e35cf81dSBarry Smith    Level: intermediate
2720e35cf81dSBarry Smith 
2721e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2722e35cf81dSBarry Smith 
2723e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
2724e35cf81dSBarry Smith 
2725e35cf81dSBarry Smith @*/
27267087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
2727e35cf81dSBarry Smith {
2728e35cf81dSBarry Smith   PetscFunctionBegin;
27290700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2730e35cf81dSBarry Smith   *lag = snes->lagjacobian;
2731e35cf81dSBarry Smith   PetscFunctionReturn(0);
2732e35cf81dSBarry Smith }
2733e35cf81dSBarry Smith 
2734e35cf81dSBarry Smith #undef __FUNCT__
27354a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
27369b94acceSBarry Smith /*@
2737d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
27389b94acceSBarry Smith 
27393f9fe445SBarry Smith    Logically Collective on SNES
2740c7afd0dbSLois Curfman McInnes 
27419b94acceSBarry Smith    Input Parameters:
2742c7afd0dbSLois Curfman McInnes +  snes - the SNES context
274370441072SBarry Smith .  abstol - absolute convergence tolerance
274433174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
274533174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
274633174efeSLois Curfman McInnes            of the change in the solution between steps
274733174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2748c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2749fee21e36SBarry Smith 
275033174efeSLois Curfman McInnes    Options Database Keys:
275170441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
2752c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
2753c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
2754c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
2755c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
27569b94acceSBarry Smith 
2757d7a720efSLois Curfman McInnes    Notes:
27589b94acceSBarry Smith    The default maximum number of iterations is 50.
27599b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
27609b94acceSBarry Smith 
276136851e7fSLois Curfman McInnes    Level: intermediate
276236851e7fSLois Curfman McInnes 
276333174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
27649b94acceSBarry Smith 
27652492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
27669b94acceSBarry Smith @*/
27677087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
27689b94acceSBarry Smith {
27693a40ed3dSBarry Smith   PetscFunctionBegin;
27700700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2771c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
2772c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
2773c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
2774c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
2775c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
2776c5eb9154SBarry Smith 
2777ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
2778ab54825eSJed Brown     if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol);
2779ab54825eSJed Brown     snes->abstol = abstol;
2780ab54825eSJed Brown   }
2781ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
2782ab54825eSJed 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);
2783ab54825eSJed Brown     snes->rtol = rtol;
2784ab54825eSJed Brown   }
2785ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
2786ab54825eSJed Brown     if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol);
2787c60f73f4SPeter Brune     snes->stol = stol;
2788ab54825eSJed Brown   }
2789ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
2790ab54825eSJed Brown     if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
2791ab54825eSJed Brown     snes->max_its = maxit;
2792ab54825eSJed Brown   }
2793ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
2794ab54825eSJed Brown     if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
2795ab54825eSJed Brown     snes->max_funcs = maxf;
2796ab54825eSJed Brown   }
279788976e71SPeter Brune   snes->tolerancesset = PETSC_TRUE;
27983a40ed3dSBarry Smith   PetscFunctionReturn(0);
27999b94acceSBarry Smith }
28009b94acceSBarry Smith 
28014a2ae208SSatish Balay #undef __FUNCT__
28024a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
28039b94acceSBarry Smith /*@
280433174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
280533174efeSLois Curfman McInnes 
2806c7afd0dbSLois Curfman McInnes    Not Collective
2807c7afd0dbSLois Curfman McInnes 
280833174efeSLois Curfman McInnes    Input Parameters:
2809c7afd0dbSLois Curfman McInnes +  snes - the SNES context
281085385478SLisandro Dalcin .  atol - absolute convergence tolerance
281133174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
281233174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
281333174efeSLois Curfman McInnes            of the change in the solution between steps
281433174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2815c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2816fee21e36SBarry Smith 
281733174efeSLois Curfman McInnes    Notes:
281833174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
281933174efeSLois Curfman McInnes 
282036851e7fSLois Curfman McInnes    Level: intermediate
282136851e7fSLois Curfman McInnes 
282233174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
282333174efeSLois Curfman McInnes 
282433174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
282533174efeSLois Curfman McInnes @*/
28267087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
282733174efeSLois Curfman McInnes {
28283a40ed3dSBarry Smith   PetscFunctionBegin;
28290700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
283085385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
283133174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
2832c60f73f4SPeter Brune   if (stol)  *stol  = snes->stol;
283333174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
283433174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
28353a40ed3dSBarry Smith   PetscFunctionReturn(0);
283633174efeSLois Curfman McInnes }
283733174efeSLois Curfman McInnes 
28384a2ae208SSatish Balay #undef __FUNCT__
28394a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
284033174efeSLois Curfman McInnes /*@
28419b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
28429b94acceSBarry Smith 
28433f9fe445SBarry Smith    Logically Collective on SNES
2844fee21e36SBarry Smith 
2845c7afd0dbSLois Curfman McInnes    Input Parameters:
2846c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2847c7afd0dbSLois Curfman McInnes -  tol - tolerance
2848c7afd0dbSLois Curfman McInnes 
28499b94acceSBarry Smith    Options Database Key:
2850c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
28519b94acceSBarry Smith 
285236851e7fSLois Curfman McInnes    Level: intermediate
285336851e7fSLois Curfman McInnes 
28549b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
28559b94acceSBarry Smith 
28562492ecdbSBarry Smith .seealso: SNESSetTolerances()
28579b94acceSBarry Smith @*/
28587087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
28599b94acceSBarry Smith {
28603a40ed3dSBarry Smith   PetscFunctionBegin;
28610700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2862c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
28639b94acceSBarry Smith   snes->deltatol = tol;
28643a40ed3dSBarry Smith   PetscFunctionReturn(0);
28659b94acceSBarry Smith }
28669b94acceSBarry Smith 
2867df9fa365SBarry Smith /*
2868df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
2869df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
2870df9fa365SBarry Smith    macros instead of functions
2871df9fa365SBarry Smith */
28724a2ae208SSatish Balay #undef __FUNCT__
2873a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
28747087cfbeSBarry Smith PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2875ce1608b8SBarry Smith {
2876dfbe8321SBarry Smith   PetscErrorCode ierr;
2877ce1608b8SBarry Smith 
2878ce1608b8SBarry Smith   PetscFunctionBegin;
28790700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2880a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
2881ce1608b8SBarry Smith   PetscFunctionReturn(0);
2882ce1608b8SBarry Smith }
2883ce1608b8SBarry Smith 
28844a2ae208SSatish Balay #undef __FUNCT__
2885a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
28867087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2887df9fa365SBarry Smith {
2888dfbe8321SBarry Smith   PetscErrorCode ierr;
2889df9fa365SBarry Smith 
2890df9fa365SBarry Smith   PetscFunctionBegin;
2891a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2892df9fa365SBarry Smith   PetscFunctionReturn(0);
2893df9fa365SBarry Smith }
2894df9fa365SBarry Smith 
28954a2ae208SSatish Balay #undef __FUNCT__
2896a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
28976bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
2898df9fa365SBarry Smith {
2899dfbe8321SBarry Smith   PetscErrorCode ierr;
2900df9fa365SBarry Smith 
2901df9fa365SBarry Smith   PetscFunctionBegin;
2902a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2903df9fa365SBarry Smith   PetscFunctionReturn(0);
2904df9fa365SBarry Smith }
2905df9fa365SBarry Smith 
29067087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
2907b271bb04SBarry Smith #undef __FUNCT__
2908b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
29097087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2910b271bb04SBarry Smith {
2911b271bb04SBarry Smith   PetscDrawLG      lg;
2912b271bb04SBarry Smith   PetscErrorCode   ierr;
2913b271bb04SBarry Smith   PetscReal        x,y,per;
2914b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
2915b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
2916b271bb04SBarry Smith   PetscDraw        draw;
2917b271bb04SBarry Smith   PetscFunctionBegin;
2918b271bb04SBarry Smith   if (!monctx) {
2919b271bb04SBarry Smith     MPI_Comm    comm;
2920b271bb04SBarry Smith 
2921b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2922b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
2923b271bb04SBarry Smith   }
2924b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
2925b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2926b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2927b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
2928b271bb04SBarry Smith   x = (PetscReal) n;
2929b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
2930b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2931b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2932b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2933b271bb04SBarry Smith   }
2934b271bb04SBarry Smith 
2935b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
2936b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2937b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2938b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
2939b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
2940b271bb04SBarry Smith   x = (PetscReal) n;
2941b271bb04SBarry Smith   y = 100.0*per;
2942b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2943b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2944b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2945b271bb04SBarry Smith   }
2946b271bb04SBarry Smith 
2947b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
2948b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2949b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2950b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
2951b271bb04SBarry Smith   x = (PetscReal) n;
2952b271bb04SBarry Smith   y = (prev - rnorm)/prev;
2953b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2954b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2955b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2956b271bb04SBarry Smith   }
2957b271bb04SBarry Smith 
2958b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
2959b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2960b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2961b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
2962b271bb04SBarry Smith   x = (PetscReal) n;
2963b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
2964b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
2965b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2966b271bb04SBarry Smith   }
2967b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2968b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2969b271bb04SBarry Smith   }
2970b271bb04SBarry Smith   prev = rnorm;
2971b271bb04SBarry Smith   PetscFunctionReturn(0);
2972b271bb04SBarry Smith }
2973b271bb04SBarry Smith 
2974b271bb04SBarry Smith #undef __FUNCT__
2975b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
29767087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2977b271bb04SBarry Smith {
2978b271bb04SBarry Smith   PetscErrorCode ierr;
2979b271bb04SBarry Smith 
2980b271bb04SBarry Smith   PetscFunctionBegin;
2981b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2982b271bb04SBarry Smith   PetscFunctionReturn(0);
2983b271bb04SBarry Smith }
2984b271bb04SBarry Smith 
2985b271bb04SBarry Smith #undef __FUNCT__
2986b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
29876bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG *draw)
2988b271bb04SBarry Smith {
2989b271bb04SBarry Smith   PetscErrorCode ierr;
2990b271bb04SBarry Smith 
2991b271bb04SBarry Smith   PetscFunctionBegin;
2992b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2993b271bb04SBarry Smith   PetscFunctionReturn(0);
2994b271bb04SBarry Smith }
2995b271bb04SBarry Smith 
29967a03ce2fSLisandro Dalcin #undef __FUNCT__
29977a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
2998228d79bcSJed Brown /*@
2999228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
3000228d79bcSJed Brown 
3001228d79bcSJed Brown    Collective on SNES
3002228d79bcSJed Brown 
3003228d79bcSJed Brown    Input Parameters:
3004228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
3005228d79bcSJed Brown .  iter - iteration number
3006228d79bcSJed Brown -  rnorm - relative norm of the residual
3007228d79bcSJed Brown 
3008228d79bcSJed Brown    Notes:
3009228d79bcSJed Brown    This routine is called by the SNES implementations.
3010228d79bcSJed Brown    It does not typically need to be called by the user.
3011228d79bcSJed Brown 
3012228d79bcSJed Brown    Level: developer
3013228d79bcSJed Brown 
3014228d79bcSJed Brown .seealso: SNESMonitorSet()
3015228d79bcSJed Brown @*/
30167a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
30177a03ce2fSLisandro Dalcin {
30187a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
30197a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
30207a03ce2fSLisandro Dalcin 
30217a03ce2fSLisandro Dalcin   PetscFunctionBegin;
30227a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
30237a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
30247a03ce2fSLisandro Dalcin   }
30257a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
30267a03ce2fSLisandro Dalcin }
30277a03ce2fSLisandro Dalcin 
30289b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
30299b94acceSBarry Smith 
30304a2ae208SSatish Balay #undef __FUNCT__
3031a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
30329b94acceSBarry Smith /*@C
3033a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
30349b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
30359b94acceSBarry Smith    progress.
30369b94acceSBarry Smith 
30373f9fe445SBarry Smith    Logically Collective on SNES
3038fee21e36SBarry Smith 
3039c7afd0dbSLois Curfman McInnes    Input Parameters:
3040c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3041c7afd0dbSLois Curfman McInnes .  func - monitoring routine
3042b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
3043e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
3044b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
3045b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
30469b94acceSBarry Smith 
3047c7afd0dbSLois Curfman McInnes    Calling sequence of func:
3048a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
3049c7afd0dbSLois Curfman McInnes 
3050c7afd0dbSLois Curfman McInnes +    snes - the SNES context
3051c7afd0dbSLois Curfman McInnes .    its - iteration number
3052c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
305340a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
30549b94acceSBarry Smith 
30559665c990SLois Curfman McInnes    Options Database Keys:
3056a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
3057a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
3058a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
3059cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
3060c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
3061a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
3062c7afd0dbSLois Curfman McInnes                             does not cancel those set via
3063c7afd0dbSLois Curfman McInnes                             the options database.
30649665c990SLois Curfman McInnes 
3065639f9d9dSBarry Smith    Notes:
30666bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
3067a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
30686bc08f3fSLois Curfman McInnes    order in which they were set.
3069639f9d9dSBarry Smith 
3070025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
3071025f1a04SBarry Smith 
307236851e7fSLois Curfman McInnes    Level: intermediate
307336851e7fSLois Curfman McInnes 
30749b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
30759b94acceSBarry Smith 
3076a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
30779b94acceSBarry Smith @*/
3078c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
30799b94acceSBarry Smith {
3080b90d0a6eSBarry Smith   PetscInt       i;
3081649052a6SBarry Smith   PetscErrorCode ierr;
3082b90d0a6eSBarry Smith 
30833a40ed3dSBarry Smith   PetscFunctionBegin;
30840700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
308517186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
3086b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
3087649052a6SBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
3088649052a6SBarry Smith       if (monitordestroy) {
3089c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
3090649052a6SBarry Smith       }
3091b90d0a6eSBarry Smith       PetscFunctionReturn(0);
3092b90d0a6eSBarry Smith     }
3093b90d0a6eSBarry Smith   }
3094b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
3095b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
3096639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
30973a40ed3dSBarry Smith   PetscFunctionReturn(0);
30989b94acceSBarry Smith }
30999b94acceSBarry Smith 
31004a2ae208SSatish Balay #undef __FUNCT__
3101a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
31025cd90555SBarry Smith /*@C
3103a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
31045cd90555SBarry Smith 
31053f9fe445SBarry Smith    Logically Collective on SNES
3106c7afd0dbSLois Curfman McInnes 
31075cd90555SBarry Smith    Input Parameters:
31085cd90555SBarry Smith .  snes - the SNES context
31095cd90555SBarry Smith 
31101a480d89SAdministrator    Options Database Key:
3111a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
3112a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
3113c7afd0dbSLois Curfman McInnes     set via the options database
31145cd90555SBarry Smith 
31155cd90555SBarry Smith    Notes:
31165cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
31175cd90555SBarry Smith 
311836851e7fSLois Curfman McInnes    Level: intermediate
311936851e7fSLois Curfman McInnes 
31205cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
31215cd90555SBarry Smith 
3122a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
31235cd90555SBarry Smith @*/
31247087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
31255cd90555SBarry Smith {
3126d952e501SBarry Smith   PetscErrorCode ierr;
3127d952e501SBarry Smith   PetscInt       i;
3128d952e501SBarry Smith 
31295cd90555SBarry Smith   PetscFunctionBegin;
31300700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3131d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
3132d952e501SBarry Smith     if (snes->monitordestroy[i]) {
31333c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
3134d952e501SBarry Smith     }
3135d952e501SBarry Smith   }
31365cd90555SBarry Smith   snes->numbermonitors = 0;
31375cd90555SBarry Smith   PetscFunctionReturn(0);
31385cd90555SBarry Smith }
31395cd90555SBarry Smith 
31404a2ae208SSatish Balay #undef __FUNCT__
31414a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
31429b94acceSBarry Smith /*@C
31439b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
31449b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
31459b94acceSBarry Smith 
31463f9fe445SBarry Smith    Logically Collective on SNES
3147fee21e36SBarry Smith 
3148c7afd0dbSLois Curfman McInnes    Input Parameters:
3149c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3150c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
31517f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
31527f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
31539b94acceSBarry Smith 
3154c7afd0dbSLois Curfman McInnes    Calling sequence of func:
315506ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
3156c7afd0dbSLois Curfman McInnes 
3157c7afd0dbSLois Curfman McInnes +    snes - the SNES context
315806ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
3159c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
3160184914b5SBarry Smith .    reason - reason for convergence/divergence
3161c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
31624b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
31634b27c08aSLois Curfman McInnes -    f - 2-norm of function
31649b94acceSBarry Smith 
316536851e7fSLois Curfman McInnes    Level: advanced
316636851e7fSLois Curfman McInnes 
31679b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
31689b94acceSBarry Smith 
316985385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
31709b94acceSBarry Smith @*/
31717087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
31729b94acceSBarry Smith {
31737f7931b9SBarry Smith   PetscErrorCode ierr;
31747f7931b9SBarry Smith 
31753a40ed3dSBarry Smith   PetscFunctionBegin;
31760700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
317785385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
31787f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
31797f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
31807f7931b9SBarry Smith   }
318185385478SLisandro Dalcin   snes->ops->converged        = func;
31827f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
318385385478SLisandro Dalcin   snes->cnvP                  = cctx;
31843a40ed3dSBarry Smith   PetscFunctionReturn(0);
31859b94acceSBarry Smith }
31869b94acceSBarry Smith 
31874a2ae208SSatish Balay #undef __FUNCT__
31884a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
318952baeb72SSatish Balay /*@
3190184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
3191184914b5SBarry Smith 
3192184914b5SBarry Smith    Not Collective
3193184914b5SBarry Smith 
3194184914b5SBarry Smith    Input Parameter:
3195184914b5SBarry Smith .  snes - the SNES context
3196184914b5SBarry Smith 
3197184914b5SBarry Smith    Output Parameter:
31984d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
3199184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
3200184914b5SBarry Smith 
3201184914b5SBarry Smith    Level: intermediate
3202184914b5SBarry Smith 
3203184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
3204184914b5SBarry Smith 
3205184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
3206184914b5SBarry Smith 
320785385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
3208184914b5SBarry Smith @*/
32097087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
3210184914b5SBarry Smith {
3211184914b5SBarry Smith   PetscFunctionBegin;
32120700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
32134482741eSBarry Smith   PetscValidPointer(reason,2);
3214184914b5SBarry Smith   *reason = snes->reason;
3215184914b5SBarry Smith   PetscFunctionReturn(0);
3216184914b5SBarry Smith }
3217184914b5SBarry Smith 
32184a2ae208SSatish Balay #undef __FUNCT__
32194a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
3220c9005455SLois Curfman McInnes /*@
3221c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
3222c9005455SLois Curfman McInnes 
32233f9fe445SBarry Smith    Logically Collective on SNES
3224fee21e36SBarry Smith 
3225c7afd0dbSLois Curfman McInnes    Input Parameters:
3226c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
32278c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
3228cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
3229758f92a0SBarry Smith .  na  - size of a and its
323064731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
3231758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
3232c7afd0dbSLois Curfman McInnes 
3233308dcc3eSBarry Smith    Notes:
3234308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
3235308dcc3eSBarry Smith    default array of length 10000 is allocated.
3236308dcc3eSBarry Smith 
3237c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
3238c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
3239c9005455SLois Curfman McInnes    during the section of code that is being timed.
3240c9005455SLois Curfman McInnes 
324136851e7fSLois Curfman McInnes    Level: intermediate
324236851e7fSLois Curfman McInnes 
3243c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
3244758f92a0SBarry Smith 
324508405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
3246758f92a0SBarry Smith 
3247c9005455SLois Curfman McInnes @*/
32487087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
3249c9005455SLois Curfman McInnes {
3250308dcc3eSBarry Smith   PetscErrorCode ierr;
3251308dcc3eSBarry Smith 
32523a40ed3dSBarry Smith   PetscFunctionBegin;
32530700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
32544482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
3255a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
3256308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
3257308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
3258308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
3259308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
3260308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
3261308dcc3eSBarry Smith   }
3262c9005455SLois Curfman McInnes   snes->conv_hist       = a;
3263758f92a0SBarry Smith   snes->conv_hist_its   = its;
3264758f92a0SBarry Smith   snes->conv_hist_max   = na;
3265a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
3266758f92a0SBarry Smith   snes->conv_hist_reset = reset;
3267758f92a0SBarry Smith   PetscFunctionReturn(0);
3268758f92a0SBarry Smith }
3269758f92a0SBarry Smith 
3270308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3271c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
3272c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
3273308dcc3eSBarry Smith EXTERN_C_BEGIN
3274308dcc3eSBarry Smith #undef __FUNCT__
3275308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
3276308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
3277308dcc3eSBarry Smith {
3278308dcc3eSBarry Smith   mxArray        *mat;
3279308dcc3eSBarry Smith   PetscInt       i;
3280308dcc3eSBarry Smith   PetscReal      *ar;
3281308dcc3eSBarry Smith 
3282308dcc3eSBarry Smith   PetscFunctionBegin;
3283308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
3284308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
3285308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
3286308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
3287308dcc3eSBarry Smith   }
3288308dcc3eSBarry Smith   PetscFunctionReturn(mat);
3289308dcc3eSBarry Smith }
3290308dcc3eSBarry Smith EXTERN_C_END
3291308dcc3eSBarry Smith #endif
3292308dcc3eSBarry Smith 
3293308dcc3eSBarry Smith 
32944a2ae208SSatish Balay #undef __FUNCT__
32954a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
32960c4c9dddSBarry Smith /*@C
3297758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
3298758f92a0SBarry Smith 
32993f9fe445SBarry Smith    Not Collective
3300758f92a0SBarry Smith 
3301758f92a0SBarry Smith    Input Parameter:
3302758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
3303758f92a0SBarry Smith 
3304758f92a0SBarry Smith    Output Parameters:
3305758f92a0SBarry Smith .  a   - array to hold history
3306758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
3307758f92a0SBarry Smith          negative if not converged) for each solve.
3308758f92a0SBarry Smith -  na  - size of a and its
3309758f92a0SBarry Smith 
3310758f92a0SBarry Smith    Notes:
3311758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
3312758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
3313758f92a0SBarry Smith 
3314758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
3315758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
3316758f92a0SBarry Smith    during the section of code that is being timed.
3317758f92a0SBarry Smith 
3318758f92a0SBarry Smith    Level: intermediate
3319758f92a0SBarry Smith 
3320758f92a0SBarry Smith .keywords: SNES, get, convergence, history
3321758f92a0SBarry Smith 
3322758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
3323758f92a0SBarry Smith 
3324758f92a0SBarry Smith @*/
33257087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3326758f92a0SBarry Smith {
3327758f92a0SBarry Smith   PetscFunctionBegin;
33280700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3329758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
3330758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
3331758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
33323a40ed3dSBarry Smith   PetscFunctionReturn(0);
3333c9005455SLois Curfman McInnes }
3334c9005455SLois Curfman McInnes 
3335e74ef692SMatthew Knepley #undef __FUNCT__
3336e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
3337ac226902SBarry Smith /*@C
333876b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
3339eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
33407e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
334176b2cf59SMatthew Knepley 
33423f9fe445SBarry Smith   Logically Collective on SNES
334376b2cf59SMatthew Knepley 
334476b2cf59SMatthew Knepley   Input Parameters:
334576b2cf59SMatthew Knepley . snes - The nonlinear solver context
334676b2cf59SMatthew Knepley . func - The function
334776b2cf59SMatthew Knepley 
334876b2cf59SMatthew Knepley   Calling sequence of func:
3349b5d30489SBarry Smith . func (SNES snes, PetscInt step);
335076b2cf59SMatthew Knepley 
335176b2cf59SMatthew Knepley . step - The current step of the iteration
335276b2cf59SMatthew Knepley 
3353fe97e370SBarry Smith   Level: advanced
3354fe97e370SBarry Smith 
3355fe97e370SBarry 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()
3356fe97e370SBarry Smith         This is not used by most users.
335776b2cf59SMatthew Knepley 
335876b2cf59SMatthew Knepley .keywords: SNES, update
3359b5d30489SBarry Smith 
336085385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
336176b2cf59SMatthew Knepley @*/
33627087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
336376b2cf59SMatthew Knepley {
336476b2cf59SMatthew Knepley   PetscFunctionBegin;
33650700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
3366e7788613SBarry Smith   snes->ops->update = func;
336776b2cf59SMatthew Knepley   PetscFunctionReturn(0);
336876b2cf59SMatthew Knepley }
336976b2cf59SMatthew Knepley 
3370e74ef692SMatthew Knepley #undef __FUNCT__
3371e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
337276b2cf59SMatthew Knepley /*@
337376b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
337476b2cf59SMatthew Knepley 
337576b2cf59SMatthew Knepley   Not collective
337676b2cf59SMatthew Knepley 
337776b2cf59SMatthew Knepley   Input Parameters:
337876b2cf59SMatthew Knepley . snes - The nonlinear solver context
337976b2cf59SMatthew Knepley . step - The current step of the iteration
338076b2cf59SMatthew Knepley 
3381205452f4SMatthew Knepley   Level: intermediate
3382205452f4SMatthew Knepley 
338376b2cf59SMatthew Knepley .keywords: SNES, update
3384a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
338576b2cf59SMatthew Knepley @*/
33867087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
338776b2cf59SMatthew Knepley {
338876b2cf59SMatthew Knepley   PetscFunctionBegin;
338976b2cf59SMatthew Knepley   PetscFunctionReturn(0);
339076b2cf59SMatthew Knepley }
339176b2cf59SMatthew Knepley 
33924a2ae208SSatish Balay #undef __FUNCT__
33934a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
33949b94acceSBarry Smith /*
33959b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
33969b94acceSBarry Smith    positive parameter delta.
33979b94acceSBarry Smith 
33989b94acceSBarry Smith     Input Parameters:
3399c7afd0dbSLois Curfman McInnes +   snes - the SNES context
34009b94acceSBarry Smith .   y - approximate solution of linear system
34019b94acceSBarry Smith .   fnorm - 2-norm of current function
3402c7afd0dbSLois Curfman McInnes -   delta - trust region size
34039b94acceSBarry Smith 
34049b94acceSBarry Smith     Output Parameters:
3405c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
34069b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
34079b94acceSBarry Smith     region, and exceeds zero otherwise.
3408c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
34099b94acceSBarry Smith 
34109b94acceSBarry Smith     Note:
34114b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
34129b94acceSBarry Smith     is set to be the maximum allowable step size.
34139b94acceSBarry Smith 
34149b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
34159b94acceSBarry Smith */
3416dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
34179b94acceSBarry Smith {
3418064f8208SBarry Smith   PetscReal      nrm;
3419ea709b57SSatish Balay   PetscScalar    cnorm;
3420dfbe8321SBarry Smith   PetscErrorCode ierr;
34213a40ed3dSBarry Smith 
34223a40ed3dSBarry Smith   PetscFunctionBegin;
34230700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
34240700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3425c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
3426184914b5SBarry Smith 
3427064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
3428064f8208SBarry Smith   if (nrm > *delta) {
3429064f8208SBarry Smith      nrm = *delta/nrm;
3430064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
3431064f8208SBarry Smith      cnorm = nrm;
34322dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
34339b94acceSBarry Smith      *ynorm = *delta;
34349b94acceSBarry Smith   } else {
34359b94acceSBarry Smith      *gpnorm = 0.0;
3436064f8208SBarry Smith      *ynorm = nrm;
34379b94acceSBarry Smith   }
34383a40ed3dSBarry Smith   PetscFunctionReturn(0);
34399b94acceSBarry Smith }
34409b94acceSBarry Smith 
34414a2ae208SSatish Balay #undef __FUNCT__
34424a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
34436ce558aeSBarry Smith /*@C
3444f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
3445f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
34469b94acceSBarry Smith 
3447c7afd0dbSLois Curfman McInnes    Collective on SNES
3448c7afd0dbSLois Curfman McInnes 
3449b2002411SLois Curfman McInnes    Input Parameters:
3450c7afd0dbSLois Curfman McInnes +  snes - the SNES context
34513cebf274SJed Brown .  b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero.
345285385478SLisandro Dalcin -  x - the solution vector.
34539b94acceSBarry Smith 
3454b2002411SLois Curfman McInnes    Notes:
34558ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
34568ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
34578ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
34588ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
34598ddd3da0SLois Curfman McInnes 
346036851e7fSLois Curfman McInnes    Level: beginner
346136851e7fSLois Curfman McInnes 
34629b94acceSBarry Smith .keywords: SNES, nonlinear, solve
34639b94acceSBarry Smith 
3464c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
34659b94acceSBarry Smith @*/
34667087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
34679b94acceSBarry Smith {
3468dfbe8321SBarry Smith   PetscErrorCode ierr;
3469ace3abfcSBarry Smith   PetscBool      flg;
3470eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
3471eabae89aSBarry Smith   PetscViewer    viewer;
3472efd51863SBarry Smith   PetscInt       grid;
3473a69afd8bSBarry Smith   Vec            xcreated = PETSC_NULL;
3474caa4e7f2SJed Brown   DM             dm;
3475052efed2SBarry Smith 
34763a40ed3dSBarry Smith   PetscFunctionBegin;
34770700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3478a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3479a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
34800700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
348185385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
348285385478SLisandro Dalcin 
3483caa4e7f2SJed Brown   if (!x) {
3484caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3485caa4e7f2SJed Brown     ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr);
3486a69afd8bSBarry Smith     x    = xcreated;
3487a69afd8bSBarry Smith   }
3488a69afd8bSBarry Smith 
3489a8248277SBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);}
3490efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
3491efd51863SBarry Smith 
349285385478SLisandro Dalcin     /* set solution vector */
3493efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
34946bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
349585385478SLisandro Dalcin     snes->vec_sol = x;
3496caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3497caa4e7f2SJed Brown 
3498caa4e7f2SJed Brown     /* set affine vector if provided */
349985385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
35006bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
350185385478SLisandro Dalcin     snes->vec_rhs = b;
350285385478SLisandro Dalcin 
350370e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
35043f149594SLisandro Dalcin 
35057eee914bSBarry Smith     if (!grid) {
35067eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
3507d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
3508dd568438SSatish Balay       } else if (snes->dm) {
3509dd568438SSatish Balay         PetscBool ig;
3510dd568438SSatish Balay         ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr);
3511dd568438SSatish Balay         if (ig) {
35127eee914bSBarry Smith           ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr);
35137eee914bSBarry Smith         }
3514d25893d9SBarry Smith       }
3515dd568438SSatish Balay     }
3516d25893d9SBarry Smith 
3517abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
351850ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
3519d5e45103SBarry Smith 
35203f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
35214936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
352285385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
35234936397dSBarry Smith     if (snes->domainerror){
35244936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
35254936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
35264936397dSBarry Smith     }
352717186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
35283f149594SLisandro Dalcin 
352990d69ab7SBarry Smith     flg  = PETSC_FALSE;
3530acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
3531da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
35325968eb51SBarry Smith     if (snes->printreason) {
3533a8248277SBarry Smith       ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
35345968eb51SBarry Smith       if (snes->reason > 0) {
3535c7e7b494SJed 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);
35365968eb51SBarry Smith       } else {
3537c7e7b494SJed 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);
35385968eb51SBarry Smith       }
3539a8248277SBarry Smith       ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
35405968eb51SBarry Smith     }
35415968eb51SBarry Smith 
3542e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
3543efd51863SBarry Smith     if (grid <  snes->gridsequence) {
3544efd51863SBarry Smith       DM  fine;
3545efd51863SBarry Smith       Vec xnew;
3546efd51863SBarry Smith       Mat interp;
3547efd51863SBarry Smith 
3548efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
3549c5c77316SJed Brown       if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
3550e727c939SJed Brown       ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
3551efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
3552efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
3553c833c3b5SJed Brown       ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr);
3554efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
3555efd51863SBarry Smith       x    = xnew;
3556efd51863SBarry Smith 
3557efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
3558efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
3559efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
3560a8248277SBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);
3561efd51863SBarry Smith     }
3562efd51863SBarry Smith   }
35633f7e2da0SPeter Brune   /* monitoring and viewing */
35643f7e2da0SPeter Brune   flg = PETSC_FALSE;
35653f7e2da0SPeter Brune   ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
35663f7e2da0SPeter Brune   if (flg && !PetscPreLoadingOn) {
35673f7e2da0SPeter Brune     ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
35683f7e2da0SPeter Brune     ierr = SNESView(snes,viewer);CHKERRQ(ierr);
35693f7e2da0SPeter Brune     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
35703f7e2da0SPeter Brune   }
35713f7e2da0SPeter Brune 
35723f7e2da0SPeter Brune   flg = PETSC_FALSE;
35733f7e2da0SPeter Brune   ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
35743f7e2da0SPeter Brune   if (flg) {
35753f7e2da0SPeter Brune     PetscViewer viewer;
35763f7e2da0SPeter Brune     ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
35773f7e2da0SPeter Brune     ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr);
35783f7e2da0SPeter Brune     ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr);
35793f7e2da0SPeter Brune     ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr);
35803f7e2da0SPeter Brune     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
35813f7e2da0SPeter Brune   }
35823f7e2da0SPeter Brune 
3583a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
35843a40ed3dSBarry Smith   PetscFunctionReturn(0);
35859b94acceSBarry Smith }
35869b94acceSBarry Smith 
35879b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
35889b94acceSBarry Smith 
35894a2ae208SSatish Balay #undef __FUNCT__
35904a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
359182bf6240SBarry Smith /*@C
35924b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
35939b94acceSBarry Smith 
3594fee21e36SBarry Smith    Collective on SNES
3595fee21e36SBarry Smith 
3596c7afd0dbSLois Curfman McInnes    Input Parameters:
3597c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3598454a90a3SBarry Smith -  type - a known method
3599c7afd0dbSLois Curfman McInnes 
3600c7afd0dbSLois Curfman McInnes    Options Database Key:
3601454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
3602c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
3603ae12b187SLois Curfman McInnes 
36049b94acceSBarry Smith    Notes:
3605e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
36064b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
3607c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
36084b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
3609c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
36109b94acceSBarry Smith 
3611ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
3612ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
3613ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
3614ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
3615ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
3616ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
3617ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
3618ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
3619ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
3620b0a32e0cSBarry Smith   appropriate method.
362136851e7fSLois Curfman McInnes 
362236851e7fSLois Curfman McInnes   Level: intermediate
3623a703fe33SLois Curfman McInnes 
3624454a90a3SBarry Smith .keywords: SNES, set, type
3625435da068SBarry Smith 
3626435da068SBarry Smith .seealso: SNESType, SNESCreate()
3627435da068SBarry Smith 
36289b94acceSBarry Smith @*/
36297087cfbeSBarry Smith PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
36309b94acceSBarry Smith {
3631dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
3632ace3abfcSBarry Smith   PetscBool      match;
36333a40ed3dSBarry Smith 
36343a40ed3dSBarry Smith   PetscFunctionBegin;
36350700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36364482741eSBarry Smith   PetscValidCharPointer(type,2);
363782bf6240SBarry Smith 
3638251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
36390f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
364092ff6ae8SBarry Smith 
36414b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
3642e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
364375396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
3644b5c23020SJed Brown   if (snes->ops->destroy) {
3645b5c23020SJed Brown     ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
3646b5c23020SJed Brown     snes->ops->destroy = PETSC_NULL;
3647b5c23020SJed Brown   }
364875396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
364975396ef9SLisandro Dalcin   snes->ops->setup          = 0;
365075396ef9SLisandro Dalcin   snes->ops->solve          = 0;
365175396ef9SLisandro Dalcin   snes->ops->view           = 0;
365275396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
365375396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
365475396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
365575396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
3656454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
365703bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
36589fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
36599fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
36609fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
36619fb22e1aSBarry Smith   }
36629fb22e1aSBarry Smith #endif
36633a40ed3dSBarry Smith   PetscFunctionReturn(0);
36649b94acceSBarry Smith }
36659b94acceSBarry Smith 
3666a847f771SSatish Balay 
36679b94acceSBarry Smith /* --------------------------------------------------------------------- */
36684a2ae208SSatish Balay #undef __FUNCT__
36694a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
367052baeb72SSatish Balay /*@
36719b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
3672f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
36739b94acceSBarry Smith 
3674fee21e36SBarry Smith    Not Collective
3675fee21e36SBarry Smith 
367636851e7fSLois Curfman McInnes    Level: advanced
367736851e7fSLois Curfman McInnes 
36789b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
36799b94acceSBarry Smith 
36809b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
36819b94acceSBarry Smith @*/
36827087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
36839b94acceSBarry Smith {
3684dfbe8321SBarry Smith   PetscErrorCode ierr;
368582bf6240SBarry Smith 
36863a40ed3dSBarry Smith   PetscFunctionBegin;
36871441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
36884c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
36893a40ed3dSBarry Smith   PetscFunctionReturn(0);
36909b94acceSBarry Smith }
36919b94acceSBarry Smith 
36924a2ae208SSatish Balay #undef __FUNCT__
36934a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
36949b94acceSBarry Smith /*@C
36959a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
36969b94acceSBarry Smith 
3697c7afd0dbSLois Curfman McInnes    Not Collective
3698c7afd0dbSLois Curfman McInnes 
36999b94acceSBarry Smith    Input Parameter:
37004b0e389bSBarry Smith .  snes - nonlinear solver context
37019b94acceSBarry Smith 
37029b94acceSBarry Smith    Output Parameter:
37033a7fca6bSBarry Smith .  type - SNES method (a character string)
37049b94acceSBarry Smith 
370536851e7fSLois Curfman McInnes    Level: intermediate
370636851e7fSLois Curfman McInnes 
3707454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
37089b94acceSBarry Smith @*/
37097087cfbeSBarry Smith PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
37109b94acceSBarry Smith {
37113a40ed3dSBarry Smith   PetscFunctionBegin;
37120700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37134482741eSBarry Smith   PetscValidPointer(type,2);
37147adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
37153a40ed3dSBarry Smith   PetscFunctionReturn(0);
37169b94acceSBarry Smith }
37179b94acceSBarry Smith 
37184a2ae208SSatish Balay #undef __FUNCT__
37194a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
372052baeb72SSatish Balay /*@
37219b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
3722c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
37239b94acceSBarry Smith 
3724c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3725c7afd0dbSLois Curfman McInnes 
37269b94acceSBarry Smith    Input Parameter:
37279b94acceSBarry Smith .  snes - the SNES context
37289b94acceSBarry Smith 
37299b94acceSBarry Smith    Output Parameter:
37309b94acceSBarry Smith .  x - the solution
37319b94acceSBarry Smith 
373270e92668SMatthew Knepley    Level: intermediate
373336851e7fSLois Curfman McInnes 
37349b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
37359b94acceSBarry Smith 
373685385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
37379b94acceSBarry Smith @*/
37387087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
37399b94acceSBarry Smith {
37403a40ed3dSBarry Smith   PetscFunctionBegin;
37410700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37424482741eSBarry Smith   PetscValidPointer(x,2);
374385385478SLisandro Dalcin   *x = snes->vec_sol;
374470e92668SMatthew Knepley   PetscFunctionReturn(0);
374570e92668SMatthew Knepley }
374670e92668SMatthew Knepley 
374770e92668SMatthew Knepley #undef __FUNCT__
37484a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
374952baeb72SSatish Balay /*@
37509b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
37519b94acceSBarry Smith    stored.
37529b94acceSBarry Smith 
3753c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3754c7afd0dbSLois Curfman McInnes 
37559b94acceSBarry Smith    Input Parameter:
37569b94acceSBarry Smith .  snes - the SNES context
37579b94acceSBarry Smith 
37589b94acceSBarry Smith    Output Parameter:
37599b94acceSBarry Smith .  x - the solution update
37609b94acceSBarry Smith 
376136851e7fSLois Curfman McInnes    Level: advanced
376236851e7fSLois Curfman McInnes 
37639b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
37649b94acceSBarry Smith 
376585385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
37669b94acceSBarry Smith @*/
37677087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
37689b94acceSBarry Smith {
37693a40ed3dSBarry Smith   PetscFunctionBegin;
37700700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37714482741eSBarry Smith   PetscValidPointer(x,2);
377285385478SLisandro Dalcin   *x = snes->vec_sol_update;
37733a40ed3dSBarry Smith   PetscFunctionReturn(0);
37749b94acceSBarry Smith }
37759b94acceSBarry Smith 
37764a2ae208SSatish Balay #undef __FUNCT__
37774a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
37789b94acceSBarry Smith /*@C
37793638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
37809b94acceSBarry Smith 
3781a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
3782c7afd0dbSLois Curfman McInnes 
37839b94acceSBarry Smith    Input Parameter:
37849b94acceSBarry Smith .  snes - the SNES context
37859b94acceSBarry Smith 
37869b94acceSBarry Smith    Output Parameter:
37877bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
378870e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
378970e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
37909b94acceSBarry Smith 
379136851e7fSLois Curfman McInnes    Level: advanced
379236851e7fSLois Curfman McInnes 
3793a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
37949b94acceSBarry Smith 
37954b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
37969b94acceSBarry Smith @*/
37977087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
37989b94acceSBarry Smith {
3799a63bb30eSJed Brown   PetscErrorCode ierr;
38006cab3a1bSJed Brown   DM             dm;
3801a63bb30eSJed Brown 
38023a40ed3dSBarry Smith   PetscFunctionBegin;
38030700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3804a63bb30eSJed Brown   if (r) {
3805a63bb30eSJed Brown     if (!snes->vec_func) {
3806a63bb30eSJed Brown       if (snes->vec_rhs) {
3807a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
3808a63bb30eSJed Brown       } else if (snes->vec_sol) {
3809a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
3810a63bb30eSJed Brown       } else if (snes->dm) {
3811a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
3812a63bb30eSJed Brown       }
3813a63bb30eSJed Brown     }
3814a63bb30eSJed Brown     *r = snes->vec_func;
3815a63bb30eSJed Brown   }
38166cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
38176cab3a1bSJed Brown   ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr);
38183a40ed3dSBarry Smith   PetscFunctionReturn(0);
38199b94acceSBarry Smith }
38209b94acceSBarry Smith 
3821c79ef259SPeter Brune /*@C
3822c79ef259SPeter Brune    SNESGetGS - Returns the GS function and context.
3823c79ef259SPeter Brune 
3824c79ef259SPeter Brune    Input Parameter:
3825c79ef259SPeter Brune .  snes - the SNES context
3826c79ef259SPeter Brune 
3827c79ef259SPeter Brune    Output Parameter:
3828c79ef259SPeter Brune +  gsfunc - the function (or PETSC_NULL)
3829c79ef259SPeter Brune -  ctx    - the function context (or PETSC_NULL)
3830c79ef259SPeter Brune 
3831c79ef259SPeter Brune    Level: advanced
3832c79ef259SPeter Brune 
3833c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
3834c79ef259SPeter Brune 
3835c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction()
3836c79ef259SPeter Brune @*/
3837c79ef259SPeter Brune 
38384a2ae208SSatish Balay #undef __FUNCT__
3839646217ecSPeter Brune #define __FUNCT__ "SNESGetGS"
3840646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx)
3841646217ecSPeter Brune {
38426cab3a1bSJed Brown   PetscErrorCode ierr;
38436cab3a1bSJed Brown   DM             dm;
38446cab3a1bSJed Brown 
3845646217ecSPeter Brune   PetscFunctionBegin;
3846646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
38476cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
38486cab3a1bSJed Brown   ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr);
3849646217ecSPeter Brune   PetscFunctionReturn(0);
3850646217ecSPeter Brune }
3851646217ecSPeter Brune 
38524a2ae208SSatish Balay #undef __FUNCT__
38534a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
38543c7409f5SSatish Balay /*@C
38553c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
3856d850072dSLois Curfman McInnes    SNES options in the database.
38573c7409f5SSatish Balay 
38583f9fe445SBarry Smith    Logically Collective on SNES
3859fee21e36SBarry Smith 
3860c7afd0dbSLois Curfman McInnes    Input Parameter:
3861c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3862c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3863c7afd0dbSLois Curfman McInnes 
3864d850072dSLois Curfman McInnes    Notes:
3865a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3866c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3867d850072dSLois Curfman McInnes 
386836851e7fSLois Curfman McInnes    Level: advanced
386936851e7fSLois Curfman McInnes 
38703c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
3871a86d99e1SLois Curfman McInnes 
3872a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
38733c7409f5SSatish Balay @*/
38747087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
38753c7409f5SSatish Balay {
3876dfbe8321SBarry Smith   PetscErrorCode ierr;
38773c7409f5SSatish Balay 
38783a40ed3dSBarry Smith   PetscFunctionBegin;
38790700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3880639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
38811cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
388294b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
38833a40ed3dSBarry Smith   PetscFunctionReturn(0);
38843c7409f5SSatish Balay }
38853c7409f5SSatish Balay 
38864a2ae208SSatish Balay #undef __FUNCT__
38874a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
38883c7409f5SSatish Balay /*@C
3889f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
3890d850072dSLois Curfman McInnes    SNES options in the database.
38913c7409f5SSatish Balay 
38923f9fe445SBarry Smith    Logically Collective on SNES
3893fee21e36SBarry Smith 
3894c7afd0dbSLois Curfman McInnes    Input Parameters:
3895c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3896c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3897c7afd0dbSLois Curfman McInnes 
3898d850072dSLois Curfman McInnes    Notes:
3899a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3900c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3901d850072dSLois Curfman McInnes 
390236851e7fSLois Curfman McInnes    Level: advanced
390336851e7fSLois Curfman McInnes 
39043c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
3905a86d99e1SLois Curfman McInnes 
3906a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
39073c7409f5SSatish Balay @*/
39087087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
39093c7409f5SSatish Balay {
3910dfbe8321SBarry Smith   PetscErrorCode ierr;
39113c7409f5SSatish Balay 
39123a40ed3dSBarry Smith   PetscFunctionBegin;
39130700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3914639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
39151cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
391694b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
39173a40ed3dSBarry Smith   PetscFunctionReturn(0);
39183c7409f5SSatish Balay }
39193c7409f5SSatish Balay 
39204a2ae208SSatish Balay #undef __FUNCT__
39214a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
39229ab63eb5SSatish Balay /*@C
39233c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
39243c7409f5SSatish Balay    SNES options in the database.
39253c7409f5SSatish Balay 
3926c7afd0dbSLois Curfman McInnes    Not Collective
3927c7afd0dbSLois Curfman McInnes 
39283c7409f5SSatish Balay    Input Parameter:
39293c7409f5SSatish Balay .  snes - the SNES context
39303c7409f5SSatish Balay 
39313c7409f5SSatish Balay    Output Parameter:
39323c7409f5SSatish Balay .  prefix - pointer to the prefix string used
39333c7409f5SSatish Balay 
39344ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
39359ab63eb5SSatish Balay    sufficient length to hold the prefix.
39369ab63eb5SSatish Balay 
393736851e7fSLois Curfman McInnes    Level: advanced
393836851e7fSLois Curfman McInnes 
39393c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
3940a86d99e1SLois Curfman McInnes 
3941a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
39423c7409f5SSatish Balay @*/
39437087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
39443c7409f5SSatish Balay {
3945dfbe8321SBarry Smith   PetscErrorCode ierr;
39463c7409f5SSatish Balay 
39473a40ed3dSBarry Smith   PetscFunctionBegin;
39480700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3949639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
39503a40ed3dSBarry Smith   PetscFunctionReturn(0);
39513c7409f5SSatish Balay }
39523c7409f5SSatish Balay 
3953b2002411SLois Curfman McInnes 
39544a2ae208SSatish Balay #undef __FUNCT__
39554a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
39563cea93caSBarry Smith /*@C
39573cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
39583cea93caSBarry Smith 
39597f6c08e0SMatthew Knepley   Level: advanced
39603cea93caSBarry Smith @*/
39617087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
3962b2002411SLois Curfman McInnes {
3963e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
3964dfbe8321SBarry Smith   PetscErrorCode ierr;
3965b2002411SLois Curfman McInnes 
3966b2002411SLois Curfman McInnes   PetscFunctionBegin;
3967b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3968c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3969b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
3970b2002411SLois Curfman McInnes }
3971da9b6338SBarry Smith 
3972da9b6338SBarry Smith #undef __FUNCT__
3973da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
39747087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
3975da9b6338SBarry Smith {
3976dfbe8321SBarry Smith   PetscErrorCode ierr;
397777431f27SBarry Smith   PetscInt       N,i,j;
3978da9b6338SBarry Smith   Vec            u,uh,fh;
3979da9b6338SBarry Smith   PetscScalar    value;
3980da9b6338SBarry Smith   PetscReal      norm;
3981da9b6338SBarry Smith 
3982da9b6338SBarry Smith   PetscFunctionBegin;
3983da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
3984da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
3985da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
3986da9b6338SBarry Smith 
3987da9b6338SBarry Smith   /* currently only works for sequential */
3988da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
3989da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
3990da9b6338SBarry Smith   for (i=0; i<N; i++) {
3991da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
399277431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
3993da9b6338SBarry Smith     for (j=-10; j<11; j++) {
3994ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
3995da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
39963ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
3997da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
399877431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
3999da9b6338SBarry Smith       value = -value;
4000da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
4001da9b6338SBarry Smith     }
4002da9b6338SBarry Smith   }
40036bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
40046bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
4005da9b6338SBarry Smith   PetscFunctionReturn(0);
4006da9b6338SBarry Smith }
400771f87433Sdalcinl 
400871f87433Sdalcinl #undef __FUNCT__
4009fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
401071f87433Sdalcinl /*@
4011fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
401271f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
401371f87433Sdalcinl    Newton method.
401471f87433Sdalcinl 
40153f9fe445SBarry Smith    Logically Collective on SNES
401671f87433Sdalcinl 
401771f87433Sdalcinl    Input Parameters:
401871f87433Sdalcinl +  snes - SNES context
401971f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
402071f87433Sdalcinl 
402164ba62caSBarry Smith     Options Database:
402264ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
402364ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
402464ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
402564ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
402664ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
402764ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
402864ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
402964ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
403064ba62caSBarry Smith 
403171f87433Sdalcinl    Notes:
403271f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
403371f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
403471f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
403571f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
403671f87433Sdalcinl    solver.
403771f87433Sdalcinl 
403871f87433Sdalcinl    Level: advanced
403971f87433Sdalcinl 
404071f87433Sdalcinl    Reference:
404171f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
404271f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
404371f87433Sdalcinl 
404471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
404571f87433Sdalcinl 
4046fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
404771f87433Sdalcinl @*/
40487087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
404971f87433Sdalcinl {
405071f87433Sdalcinl   PetscFunctionBegin;
40510700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4052acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
405371f87433Sdalcinl   snes->ksp_ewconv = flag;
405471f87433Sdalcinl   PetscFunctionReturn(0);
405571f87433Sdalcinl }
405671f87433Sdalcinl 
405771f87433Sdalcinl #undef __FUNCT__
4058fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
405971f87433Sdalcinl /*@
4060fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
406171f87433Sdalcinl    for computing relative tolerance for linear solvers within an
406271f87433Sdalcinl    inexact Newton method.
406371f87433Sdalcinl 
406471f87433Sdalcinl    Not Collective
406571f87433Sdalcinl 
406671f87433Sdalcinl    Input Parameter:
406771f87433Sdalcinl .  snes - SNES context
406871f87433Sdalcinl 
406971f87433Sdalcinl    Output Parameter:
407071f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
407171f87433Sdalcinl 
407271f87433Sdalcinl    Notes:
407371f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
407471f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
407571f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
407671f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
407771f87433Sdalcinl    solver.
407871f87433Sdalcinl 
407971f87433Sdalcinl    Level: advanced
408071f87433Sdalcinl 
408171f87433Sdalcinl    Reference:
408271f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
408371f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
408471f87433Sdalcinl 
408571f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
408671f87433Sdalcinl 
4087fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
408871f87433Sdalcinl @*/
40897087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
409071f87433Sdalcinl {
409171f87433Sdalcinl   PetscFunctionBegin;
40920700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
409371f87433Sdalcinl   PetscValidPointer(flag,2);
409471f87433Sdalcinl   *flag = snes->ksp_ewconv;
409571f87433Sdalcinl   PetscFunctionReturn(0);
409671f87433Sdalcinl }
409771f87433Sdalcinl 
409871f87433Sdalcinl #undef __FUNCT__
4099fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
410071f87433Sdalcinl /*@
4101fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
410271f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
410371f87433Sdalcinl    Newton method.
410471f87433Sdalcinl 
41053f9fe445SBarry Smith    Logically Collective on SNES
410671f87433Sdalcinl 
410771f87433Sdalcinl    Input Parameters:
410871f87433Sdalcinl +    snes - SNES context
410971f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
411071f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
411171f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
411271f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
411371f87433Sdalcinl              (0 <= gamma2 <= 1)
411471f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
411571f87433Sdalcinl .    alpha2 - power for safeguard
411671f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
411771f87433Sdalcinl 
411871f87433Sdalcinl    Note:
411971f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
412071f87433Sdalcinl 
412171f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
412271f87433Sdalcinl 
412371f87433Sdalcinl    Level: advanced
412471f87433Sdalcinl 
412571f87433Sdalcinl    Reference:
412671f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
412771f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
412871f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
412971f87433Sdalcinl 
413071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
413171f87433Sdalcinl 
4132fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
413371f87433Sdalcinl @*/
41347087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
413571f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
413671f87433Sdalcinl {
4137fa9f3622SBarry Smith   SNESKSPEW *kctx;
413871f87433Sdalcinl   PetscFunctionBegin;
41390700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4140fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4141e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
4142c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
4143c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
4144c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
4145c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
4146c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
4147c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
4148c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
414971f87433Sdalcinl 
415071f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
415171f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
415271f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
415371f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
415471f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
415571f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
415671f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
415771f87433Sdalcinl 
415871f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
4159e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
416071f87433Sdalcinl   }
416171f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
4162e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
416371f87433Sdalcinl   }
416471f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
4165e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
416671f87433Sdalcinl   }
416771f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
4168e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
416971f87433Sdalcinl   }
417071f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
4171e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
417271f87433Sdalcinl   }
417371f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
4174e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
417571f87433Sdalcinl   }
417671f87433Sdalcinl   PetscFunctionReturn(0);
417771f87433Sdalcinl }
417871f87433Sdalcinl 
417971f87433Sdalcinl #undef __FUNCT__
4180fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
418171f87433Sdalcinl /*@
4182fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
418371f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
418471f87433Sdalcinl    Newton method.
418571f87433Sdalcinl 
418671f87433Sdalcinl    Not Collective
418771f87433Sdalcinl 
418871f87433Sdalcinl    Input Parameters:
418971f87433Sdalcinl      snes - SNES context
419071f87433Sdalcinl 
419171f87433Sdalcinl    Output Parameters:
419271f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
419371f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
419471f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
419571f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
419671f87433Sdalcinl              (0 <= gamma2 <= 1)
419771f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
419871f87433Sdalcinl .    alpha2 - power for safeguard
419971f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
420071f87433Sdalcinl 
420171f87433Sdalcinl    Level: advanced
420271f87433Sdalcinl 
420371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
420471f87433Sdalcinl 
4205fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
420671f87433Sdalcinl @*/
42077087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
420871f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
420971f87433Sdalcinl {
4210fa9f3622SBarry Smith   SNESKSPEW *kctx;
421171f87433Sdalcinl   PetscFunctionBegin;
42120700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4213fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4214e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
421571f87433Sdalcinl   if(version)   *version   = kctx->version;
421671f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
421771f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
421871f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
421971f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
422071f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
422171f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
422271f87433Sdalcinl   PetscFunctionReturn(0);
422371f87433Sdalcinl }
422471f87433Sdalcinl 
422571f87433Sdalcinl #undef __FUNCT__
4226fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
4227fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
422871f87433Sdalcinl {
422971f87433Sdalcinl   PetscErrorCode ierr;
4230fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
423171f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
423271f87433Sdalcinl 
423371f87433Sdalcinl   PetscFunctionBegin;
4234e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
423571f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
423671f87433Sdalcinl     rtol = kctx->rtol_0;
423771f87433Sdalcinl   } else {
423871f87433Sdalcinl     if (kctx->version == 1) {
423971f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
424071f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
424171f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
424271f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
424371f87433Sdalcinl     } else if (kctx->version == 2) {
424471f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
424571f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
424671f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
424771f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
424871f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
424971f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
425071f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
425171f87433Sdalcinl       stol = PetscMax(rtol,stol);
425271f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
425371f87433Sdalcinl       /* safeguard: avoid oversolving */
425471f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
425571f87433Sdalcinl       stol = PetscMax(rtol,stol);
425671f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
4257e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
425871f87433Sdalcinl   }
425971f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
426071f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
426171f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
426271f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
426371f87433Sdalcinl   PetscFunctionReturn(0);
426471f87433Sdalcinl }
426571f87433Sdalcinl 
426671f87433Sdalcinl #undef __FUNCT__
4267fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
4268fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
426971f87433Sdalcinl {
427071f87433Sdalcinl   PetscErrorCode ierr;
4271fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
427271f87433Sdalcinl   PCSide         pcside;
427371f87433Sdalcinl   Vec            lres;
427471f87433Sdalcinl 
427571f87433Sdalcinl   PetscFunctionBegin;
4276e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
427771f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
427871f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
427971f87433Sdalcinl   if (kctx->version == 1) {
4280b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
428171f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
428271f87433Sdalcinl       /* KSP residual is true linear residual */
428371f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
428471f87433Sdalcinl     } else {
428571f87433Sdalcinl       /* KSP residual is preconditioned residual */
428671f87433Sdalcinl       /* compute true linear residual norm */
428771f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
428871f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
428971f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
429071f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
42916bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
429271f87433Sdalcinl     }
429371f87433Sdalcinl   }
429471f87433Sdalcinl   PetscFunctionReturn(0);
429571f87433Sdalcinl }
429671f87433Sdalcinl 
429771f87433Sdalcinl #undef __FUNCT__
429871f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
429971f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
430071f87433Sdalcinl {
430171f87433Sdalcinl   PetscErrorCode ierr;
430271f87433Sdalcinl 
430371f87433Sdalcinl   PetscFunctionBegin;
4304fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
430571f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
4306fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
430771f87433Sdalcinl   PetscFunctionReturn(0);
430871f87433Sdalcinl }
43096c699258SBarry Smith 
43106c699258SBarry Smith #undef __FUNCT__
43116c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
43126c699258SBarry Smith /*@
43136c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
43146c699258SBarry Smith 
43153f9fe445SBarry Smith    Logically Collective on SNES
43166c699258SBarry Smith 
43176c699258SBarry Smith    Input Parameters:
43186c699258SBarry Smith +  snes - the preconditioner context
43196c699258SBarry Smith -  dm - the dm
43206c699258SBarry Smith 
43216c699258SBarry Smith    Level: intermediate
43226c699258SBarry Smith 
43236c699258SBarry Smith 
43246c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
43256c699258SBarry Smith @*/
43267087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
43276c699258SBarry Smith {
43286c699258SBarry Smith   PetscErrorCode ierr;
4329345fed2cSBarry Smith   KSP            ksp;
43306cab3a1bSJed Brown   SNESDM         sdm;
43316c699258SBarry Smith 
43326c699258SBarry Smith   PetscFunctionBegin;
43330700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4334d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
43356cab3a1bSJed Brown   if (snes->dm) {               /* Move the SNESDM context over to the new DM unless the new DM already has one */
43366cab3a1bSJed Brown     PetscContainer oldcontainer,container;
43376cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr);
43386cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr);
43396cab3a1bSJed Brown     if (oldcontainer && !container) {
43406cab3a1bSJed Brown       ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr);
43416cab3a1bSJed Brown       ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr);
43426cab3a1bSJed Brown       if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */
43436cab3a1bSJed Brown         sdm->originaldm = dm;
43446cab3a1bSJed Brown       }
43456cab3a1bSJed Brown     }
43466bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
43476cab3a1bSJed Brown   }
43486c699258SBarry Smith   snes->dm = dm;
4349345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4350345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4351f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
43522c155ee1SBarry Smith   if (snes->pc) {
43532c155ee1SBarry Smith     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
43542c155ee1SBarry Smith   }
43556c699258SBarry Smith   PetscFunctionReturn(0);
43566c699258SBarry Smith }
43576c699258SBarry Smith 
43586c699258SBarry Smith #undef __FUNCT__
43596c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
43606c699258SBarry Smith /*@
43616c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
43626c699258SBarry Smith 
43633f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
43646c699258SBarry Smith 
43656c699258SBarry Smith    Input Parameter:
43666c699258SBarry Smith . snes - the preconditioner context
43676c699258SBarry Smith 
43686c699258SBarry Smith    Output Parameter:
43696c699258SBarry Smith .  dm - the dm
43706c699258SBarry Smith 
43716c699258SBarry Smith    Level: intermediate
43726c699258SBarry Smith 
43736c699258SBarry Smith 
43746c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
43756c699258SBarry Smith @*/
43767087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
43776c699258SBarry Smith {
43786cab3a1bSJed Brown   PetscErrorCode ierr;
43796cab3a1bSJed Brown 
43806c699258SBarry Smith   PetscFunctionBegin;
43810700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
43826cab3a1bSJed Brown   if (!snes->dm) {
43836cab3a1bSJed Brown     ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr);
43846cab3a1bSJed Brown   }
43856c699258SBarry Smith   *dm = snes->dm;
43866c699258SBarry Smith   PetscFunctionReturn(0);
43876c699258SBarry Smith }
43880807856dSBarry Smith 
438931823bd8SMatthew G Knepley #undef __FUNCT__
439031823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
439131823bd8SMatthew G Knepley /*@
4392fd4b34e9SJed Brown   SNESSetPC - Sets the nonlinear preconditioner to be used.
439331823bd8SMatthew G Knepley 
439431823bd8SMatthew G Knepley   Collective on SNES
439531823bd8SMatthew G Knepley 
439631823bd8SMatthew G Knepley   Input Parameters:
439731823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
439831823bd8SMatthew G Knepley - pc   - the preconditioner object
439931823bd8SMatthew G Knepley 
440031823bd8SMatthew G Knepley   Notes:
440131823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
440231823bd8SMatthew G Knepley   to configure it using the API).
440331823bd8SMatthew G Knepley 
440431823bd8SMatthew G Knepley   Level: developer
440531823bd8SMatthew G Knepley 
440631823bd8SMatthew G Knepley .keywords: SNES, set, precondition
440731823bd8SMatthew G Knepley .seealso: SNESGetPC()
440831823bd8SMatthew G Knepley @*/
440931823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
441031823bd8SMatthew G Knepley {
441131823bd8SMatthew G Knepley   PetscErrorCode ierr;
441231823bd8SMatthew G Knepley 
441331823bd8SMatthew G Knepley   PetscFunctionBegin;
441431823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
441531823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
441631823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
441731823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4418bf11d3b6SBarry Smith   ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr);
441931823bd8SMatthew G Knepley   snes->pc = pc;
442031823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
442131823bd8SMatthew G Knepley   PetscFunctionReturn(0);
442231823bd8SMatthew G Knepley }
442331823bd8SMatthew G Knepley 
442431823bd8SMatthew G Knepley #undef __FUNCT__
442531823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
442631823bd8SMatthew G Knepley /*@
4427fd4b34e9SJed Brown   SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().
442831823bd8SMatthew G Knepley 
442931823bd8SMatthew G Knepley   Not Collective
443031823bd8SMatthew G Knepley 
443131823bd8SMatthew G Knepley   Input Parameter:
443231823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
443331823bd8SMatthew G Knepley 
443431823bd8SMatthew G Knepley   Output Parameter:
443531823bd8SMatthew G Knepley . pc - preconditioner context
443631823bd8SMatthew G Knepley 
443731823bd8SMatthew G Knepley   Level: developer
443831823bd8SMatthew G Knepley 
443931823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
444031823bd8SMatthew G Knepley .seealso: SNESSetPC()
444131823bd8SMatthew G Knepley @*/
444231823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
444331823bd8SMatthew G Knepley {
444431823bd8SMatthew G Knepley   PetscErrorCode              ierr;
4445a64e098fSPeter Brune   const char                  *optionsprefix;
444631823bd8SMatthew G Knepley 
444731823bd8SMatthew G Knepley   PetscFunctionBegin;
444831823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
444931823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
445031823bd8SMatthew G Knepley   if (!snes->pc) {
445131823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm,&snes->pc);CHKERRQ(ierr);
44524a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);CHKERRQ(ierr);
445331823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes,snes->pc);CHKERRQ(ierr);
4454a64e098fSPeter Brune     ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr);
4455a64e098fSPeter Brune     ierr = SNESSetOptionsPrefix(snes->pc,optionsprefix);CHKERRQ(ierr);
4456a64e098fSPeter Brune     ierr = SNESAppendOptionsPrefix(snes->pc,"npc_");CHKERRQ(ierr);
445731823bd8SMatthew G Knepley   }
445831823bd8SMatthew G Knepley   *pc = snes->pc;
445931823bd8SMatthew G Knepley   PetscFunctionReturn(0);
446031823bd8SMatthew G Knepley }
446131823bd8SMatthew G Knepley 
44629e764e56SPeter Brune #undef __FUNCT__
4463f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch"
44649e764e56SPeter Brune /*@
44658141a3b9SPeter Brune   SNESSetSNESLineSearch - Sets the linesearch on the SNES instance.
44669e764e56SPeter Brune 
44679e764e56SPeter Brune   Collective on SNES
44689e764e56SPeter Brune 
44699e764e56SPeter Brune   Input Parameters:
44709e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
44719e764e56SPeter Brune - linesearch   - the linesearch object
44729e764e56SPeter Brune 
44739e764e56SPeter Brune   Notes:
4474f1c6b773SPeter Brune   Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example,
44759e764e56SPeter Brune   to configure it using the API).
44769e764e56SPeter Brune 
44779e764e56SPeter Brune   Level: developer
44789e764e56SPeter Brune 
44799e764e56SPeter Brune .keywords: SNES, set, linesearch
4480f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch()
44819e764e56SPeter Brune @*/
4482f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch)
44839e764e56SPeter Brune {
44849e764e56SPeter Brune   PetscErrorCode ierr;
44859e764e56SPeter Brune 
44869e764e56SPeter Brune   PetscFunctionBegin;
44879e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4488f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
44899e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
44909e764e56SPeter Brune   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
4491f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
44929e764e56SPeter Brune   snes->linesearch = linesearch;
44939e764e56SPeter Brune   ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
44949e764e56SPeter Brune   PetscFunctionReturn(0);
44959e764e56SPeter Brune }
44969e764e56SPeter Brune 
44979e764e56SPeter Brune #undef __FUNCT__
4498f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch"
4499ea5d4fccSPeter Brune /*@C
45008141a3b9SPeter Brune   SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch()
45018141a3b9SPeter Brune   or creates a default line search instance associated with the SNES and returns it.
45029e764e56SPeter Brune 
45039e764e56SPeter Brune   Not Collective
45049e764e56SPeter Brune 
45059e764e56SPeter Brune   Input Parameter:
45069e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
45079e764e56SPeter Brune 
45089e764e56SPeter Brune   Output Parameter:
45099e764e56SPeter Brune . linesearch - linesearch context
45109e764e56SPeter Brune 
45119e764e56SPeter Brune   Level: developer
45129e764e56SPeter Brune 
45139e764e56SPeter Brune .keywords: SNES, get, linesearch
4514f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch()
45159e764e56SPeter Brune @*/
4516f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch)
45179e764e56SPeter Brune {
45189e764e56SPeter Brune   PetscErrorCode ierr;
45199e764e56SPeter Brune   const char     *optionsprefix;
45209e764e56SPeter Brune 
45219e764e56SPeter Brune   PetscFunctionBegin;
45229e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
45239e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
45249e764e56SPeter Brune   if (!snes->linesearch) {
45259e764e56SPeter Brune     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
4526f1c6b773SPeter Brune     ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr);
4527f1c6b773SPeter Brune     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
4528b1dca40bSPeter Brune     ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr);
45299e764e56SPeter Brune     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
45309e764e56SPeter Brune     ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
45319e764e56SPeter Brune   }
45329e764e56SPeter Brune   *linesearch = snes->linesearch;
45339e764e56SPeter Brune   PetscFunctionReturn(0);
45349e764e56SPeter Brune }
45359e764e56SPeter Brune 
453669b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4537c6db04a5SJed Brown #include <mex.h>
453869b4f73cSBarry Smith 
45398f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
45408f6e6473SBarry Smith 
45410807856dSBarry Smith #undef __FUNCT__
45420807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
45430807856dSBarry Smith /*
45440807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
45450807856dSBarry Smith                          SNESSetFunctionMatlab().
45460807856dSBarry Smith 
45470807856dSBarry Smith    Collective on SNES
45480807856dSBarry Smith 
45490807856dSBarry Smith    Input Parameters:
45500807856dSBarry Smith +  snes - the SNES context
45510807856dSBarry Smith -  x - input vector
45520807856dSBarry Smith 
45530807856dSBarry Smith    Output Parameter:
45540807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
45550807856dSBarry Smith 
45560807856dSBarry Smith    Notes:
45570807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
45580807856dSBarry Smith    implementations, so most users would not generally call this routine
45590807856dSBarry Smith    themselves.
45600807856dSBarry Smith 
45610807856dSBarry Smith    Level: developer
45620807856dSBarry Smith 
45630807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
45640807856dSBarry Smith 
45650807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
456661b2408cSBarry Smith */
45677087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
45680807856dSBarry Smith {
4569e650e774SBarry Smith   PetscErrorCode    ierr;
45708f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
45718f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
45728f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
457391621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
4574e650e774SBarry Smith 
45750807856dSBarry Smith   PetscFunctionBegin;
45760807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
45770807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
45780807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
45790807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
45800807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
45810807856dSBarry Smith 
45820807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
4583e650e774SBarry Smith 
458491621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4585e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4586e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
458791621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
458891621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
458991621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
45908f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
45918f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
4592b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
4593e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4594e650e774SBarry Smith   mxDestroyArray(prhs[0]);
4595e650e774SBarry Smith   mxDestroyArray(prhs[1]);
4596e650e774SBarry Smith   mxDestroyArray(prhs[2]);
45978f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
4598e650e774SBarry Smith   mxDestroyArray(plhs[0]);
45990807856dSBarry Smith   PetscFunctionReturn(0);
46000807856dSBarry Smith }
46010807856dSBarry Smith 
46020807856dSBarry Smith 
46030807856dSBarry Smith #undef __FUNCT__
46040807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
460561b2408cSBarry Smith /*
46060807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
46070807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4608e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
46090807856dSBarry Smith 
46100807856dSBarry Smith    Logically Collective on SNES
46110807856dSBarry Smith 
46120807856dSBarry Smith    Input Parameters:
46130807856dSBarry Smith +  snes - the SNES context
46140807856dSBarry Smith .  r - vector to store function value
46150807856dSBarry Smith -  func - function evaluation routine
46160807856dSBarry Smith 
46170807856dSBarry Smith    Calling sequence of func:
461861b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
46190807856dSBarry Smith 
46200807856dSBarry Smith 
46210807856dSBarry Smith    Notes:
46220807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
46230807856dSBarry Smith $      f'(x) x = -f(x),
46240807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
46250807856dSBarry Smith 
46260807856dSBarry Smith    Level: beginner
46270807856dSBarry Smith 
46280807856dSBarry Smith .keywords: SNES, nonlinear, set, function
46290807856dSBarry Smith 
46300807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
463161b2408cSBarry Smith */
46327087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
46330807856dSBarry Smith {
46340807856dSBarry Smith   PetscErrorCode    ierr;
46358f6e6473SBarry Smith   SNESMatlabContext *sctx;
46360807856dSBarry Smith 
46370807856dSBarry Smith   PetscFunctionBegin;
46388f6e6473SBarry Smith   /* currently sctx is memory bleed */
46398f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
46408f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
46418f6e6473SBarry Smith   /*
46428f6e6473SBarry Smith      This should work, but it doesn't
46438f6e6473SBarry Smith   sctx->ctx = ctx;
46448f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
46458f6e6473SBarry Smith   */
46468f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
46478f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
46480807856dSBarry Smith   PetscFunctionReturn(0);
46490807856dSBarry Smith }
465069b4f73cSBarry Smith 
465161b2408cSBarry Smith #undef __FUNCT__
465261b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
465361b2408cSBarry Smith /*
465461b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
465561b2408cSBarry Smith                          SNESSetJacobianMatlab().
465661b2408cSBarry Smith 
465761b2408cSBarry Smith    Collective on SNES
465861b2408cSBarry Smith 
465961b2408cSBarry Smith    Input Parameters:
466061b2408cSBarry Smith +  snes - the SNES context
466161b2408cSBarry Smith .  x - input vector
466261b2408cSBarry Smith .  A, B - the matrices
466361b2408cSBarry Smith -  ctx - user context
466461b2408cSBarry Smith 
466561b2408cSBarry Smith    Output Parameter:
466661b2408cSBarry Smith .  flag - structure of the matrix
466761b2408cSBarry Smith 
466861b2408cSBarry Smith    Level: developer
466961b2408cSBarry Smith 
467061b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
467161b2408cSBarry Smith 
467261b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
467361b2408cSBarry Smith @*/
46747087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
467561b2408cSBarry Smith {
467661b2408cSBarry Smith   PetscErrorCode    ierr;
467761b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
467861b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
467961b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
468061b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
468161b2408cSBarry Smith 
468261b2408cSBarry Smith   PetscFunctionBegin;
468361b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
468461b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
468561b2408cSBarry Smith 
468661b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
468761b2408cSBarry Smith 
468861b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
468961b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
469061b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
469161b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
469261b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
469361b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
469461b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
469561b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
469661b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
469761b2408cSBarry Smith   prhs[5] =  sctx->ctx;
4698b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
469961b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
470061b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
470161b2408cSBarry Smith   mxDestroyArray(prhs[0]);
470261b2408cSBarry Smith   mxDestroyArray(prhs[1]);
470361b2408cSBarry Smith   mxDestroyArray(prhs[2]);
470461b2408cSBarry Smith   mxDestroyArray(prhs[3]);
470561b2408cSBarry Smith   mxDestroyArray(prhs[4]);
470661b2408cSBarry Smith   mxDestroyArray(plhs[0]);
470761b2408cSBarry Smith   mxDestroyArray(plhs[1]);
470861b2408cSBarry Smith   PetscFunctionReturn(0);
470961b2408cSBarry Smith }
471061b2408cSBarry Smith 
471161b2408cSBarry Smith 
471261b2408cSBarry Smith #undef __FUNCT__
471361b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
471461b2408cSBarry Smith /*
471561b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
471661b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4717e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
471861b2408cSBarry Smith 
471961b2408cSBarry Smith    Logically Collective on SNES
472061b2408cSBarry Smith 
472161b2408cSBarry Smith    Input Parameters:
472261b2408cSBarry Smith +  snes - the SNES context
472361b2408cSBarry Smith .  A,B - Jacobian matrices
472461b2408cSBarry Smith .  func - function evaluation routine
472561b2408cSBarry Smith -  ctx - user context
472661b2408cSBarry Smith 
472761b2408cSBarry Smith    Calling sequence of func:
472861b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
472961b2408cSBarry Smith 
473061b2408cSBarry Smith 
473161b2408cSBarry Smith    Level: developer
473261b2408cSBarry Smith 
473361b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
473461b2408cSBarry Smith 
473561b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
473661b2408cSBarry Smith */
47377087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
473861b2408cSBarry Smith {
473961b2408cSBarry Smith   PetscErrorCode    ierr;
474061b2408cSBarry Smith   SNESMatlabContext *sctx;
474161b2408cSBarry Smith 
474261b2408cSBarry Smith   PetscFunctionBegin;
474361b2408cSBarry Smith   /* currently sctx is memory bleed */
474461b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
474561b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
474661b2408cSBarry Smith   /*
474761b2408cSBarry Smith      This should work, but it doesn't
474861b2408cSBarry Smith   sctx->ctx = ctx;
474961b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
475061b2408cSBarry Smith   */
475161b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
475261b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
475361b2408cSBarry Smith   PetscFunctionReturn(0);
475461b2408cSBarry Smith }
475569b4f73cSBarry Smith 
4756f9eb7ae2SShri Abhyankar #undef __FUNCT__
4757f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
4758f9eb7ae2SShri Abhyankar /*
4759f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
4760f9eb7ae2SShri Abhyankar 
4761f9eb7ae2SShri Abhyankar    Collective on SNES
4762f9eb7ae2SShri Abhyankar 
4763f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
4764f9eb7ae2SShri Abhyankar @*/
47657087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
4766f9eb7ae2SShri Abhyankar {
4767f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
476848f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
4769f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
4770f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
4771f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
4772f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
4773f9eb7ae2SShri Abhyankar 
4774f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4775f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4776f9eb7ae2SShri Abhyankar 
4777f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4778f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4779f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
4780f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
4781f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
4782f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
4783f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
4784f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
4785f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
4786f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4787f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
4788f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
4789f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
4790f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
4791f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
4792f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
4793f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4794f9eb7ae2SShri Abhyankar }
4795f9eb7ae2SShri Abhyankar 
4796f9eb7ae2SShri Abhyankar 
4797f9eb7ae2SShri Abhyankar #undef __FUNCT__
4798f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
4799f9eb7ae2SShri Abhyankar /*
4800e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
4801f9eb7ae2SShri Abhyankar 
4802f9eb7ae2SShri Abhyankar    Level: developer
4803f9eb7ae2SShri Abhyankar 
4804f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
4805f9eb7ae2SShri Abhyankar 
4806f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
4807f9eb7ae2SShri Abhyankar */
48087087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
4809f9eb7ae2SShri Abhyankar {
4810f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
4811f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
4812f9eb7ae2SShri Abhyankar 
4813f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4814f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
4815f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
4816f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4817f9eb7ae2SShri Abhyankar   /*
4818f9eb7ae2SShri Abhyankar      This should work, but it doesn't
4819f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
4820f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
4821f9eb7ae2SShri Abhyankar   */
4822f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
4823f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4824f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4825f9eb7ae2SShri Abhyankar }
4826f9eb7ae2SShri Abhyankar 
482769b4f73cSBarry Smith #endif
4828