xref: /petsc/src/snes/interface/snes.c (revision 459f5d124ab7f8fa1b4f4f31103fe163f4a12e0f)
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) {
3043232da50SPeter Brune 
305aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
306aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
307aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
308aa3661deSLisandro Dalcin   } else {
309aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
3103232da50SPeter Brune      provided preconditioner Jacobian with the default matrix free version. */
3113232da50SPeter Brune 
3123232da50SPeter Brune     ierr = SNESSetJacobian(snes,J,J,0,0);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;
33516ebb321SJed Brown   if (PetscLogPrintInfo) {
33616ebb321SJed Brown     PetscInt finelevel,coarselevel,fineclevel,coarseclevel;
33716ebb321SJed Brown     ierr = DMGetRefineLevel(dmfine,&finelevel);CHKERRQ(ierr);
33816ebb321SJed Brown     ierr = DMGetCoarsenLevel(dmfine,&fineclevel);CHKERRQ(ierr);
33916ebb321SJed Brown     ierr = DMGetRefineLevel(dmcoarse,&coarselevel);CHKERRQ(ierr);
34016ebb321SJed Brown     ierr = DMGetCoarsenLevel(dmcoarse,&coarseclevel);CHKERRQ(ierr);
34116ebb321SJed Brown     ierr = PetscInfo4(dmfine,"Restricting SNES solution vector from level %D-%D to level %D-%D\n",finelevel,fineclevel,coarselevel,coarseclevel);CHKERRQ(ierr);
34216ebb321SJed Brown   }
343dfe15315SJed Brown   if (dmfine == snes->dm) Xfine = snes->vec_sol;
344dfe15315SJed Brown   else {
345dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);
346dfe15315SJed Brown     Xfine = Xfine_named;
347dfe15315SJed Brown   }
348dfe15315SJed Brown   ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
349dfe15315SJed Brown   ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr);
350dfe15315SJed Brown   ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr);
351dfe15315SJed Brown   ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
352dfe15315SJed Brown   if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);}
353dfe15315SJed Brown   PetscFunctionReturn(0);
354dfe15315SJed Brown }
355dfe15315SJed Brown 
356dfe15315SJed Brown #undef __FUNCT__
35716ebb321SJed Brown #define __FUNCT__ "DMCoarsenHook_SNESVecSol"
35816ebb321SJed Brown static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm,DM dmc,void *ctx)
35916ebb321SJed Brown {
36016ebb321SJed Brown   PetscErrorCode ierr;
36116ebb321SJed Brown 
36216ebb321SJed Brown   PetscFunctionBegin;
36316ebb321SJed Brown   ierr = DMCoarsenHookAdd(dmc,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,ctx);CHKERRQ(ierr);
36416ebb321SJed Brown   PetscFunctionReturn(0);
36516ebb321SJed Brown }
36616ebb321SJed Brown 
36716ebb321SJed Brown #undef __FUNCT__
368caa4e7f2SJed Brown #define __FUNCT__ "KSPComputeOperators_SNES"
369a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can
370a6950cb2SJed Brown  * safely call SNESGetDM() in their residual evaluation routine. */
371caa4e7f2SJed Brown static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,MatStructure *mstruct,void *ctx)
372caa4e7f2SJed Brown {
373caa4e7f2SJed Brown   SNES                        snes = (SNES)ctx;
374caa4e7f2SJed Brown   PetscErrorCode              ierr;
375caa4e7f2SJed Brown   Mat                         Asave = A,Bsave = B;
376dfe15315SJed Brown   Vec                         X,Xnamed = PETSC_NULL;
377dfe15315SJed Brown   DM                          dmsave;
3784e269d77SPeter Brune   void                        *ctxsave;
3794e269d77SPeter Brune   PetscErrorCode              (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*);
380caa4e7f2SJed Brown 
381caa4e7f2SJed Brown   PetscFunctionBegin;
382dfe15315SJed Brown   dmsave = snes->dm;
383dfe15315SJed Brown   ierr = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr);
384dfe15315SJed Brown   if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */
385dfe15315SJed Brown   else {                                     /* We are on a coarser level, this vec was initialized using a DM restrict hook */
386dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
387dfe15315SJed Brown     X = Xnamed;
3884e269d77SPeter Brune     ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,&jac,&ctxsave);CHKERRQ(ierr);
3894e269d77SPeter Brune     /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */
3904e269d77SPeter Brune     if (jac == SNESDefaultComputeJacobianColor) {
3914e269d77SPeter Brune       ierr = SNESSetJacobian(snes,PETSC_NULL,PETSC_NULL,SNESDefaultComputeJacobianColor,0);CHKERRQ(ierr);
392dfe15315SJed Brown     }
3934e269d77SPeter Brune   }
3944e269d77SPeter Brune   /* put the previous context back */
3954e269d77SPeter Brune 
396dfe15315SJed Brown   ierr = SNESComputeJacobian(snes,X,&A,&B,mstruct);CHKERRQ(ierr);
3974e269d77SPeter Brune   if (snes->dm != dmsave && jac == SNESDefaultComputeJacobianColor) {
3984e269d77SPeter Brune     ierr = SNESSetJacobian(snes,PETSC_NULL,PETSC_NULL,jac,ctxsave);CHKERRQ(ierr);
3994e269d77SPeter Brune   }
4004e269d77SPeter Brune 
401caa4e7f2SJed Brown   if (A != Asave || B != Bsave) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_SUP,"No support for changing matrices at this time");
402dfe15315SJed Brown   if (Xnamed) {
403dfe15315SJed Brown     ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
404dfe15315SJed Brown   }
405dfe15315SJed Brown   snes->dm = dmsave;
406caa4e7f2SJed Brown   PetscFunctionReturn(0);
407caa4e7f2SJed Brown }
408caa4e7f2SJed Brown 
409caa4e7f2SJed Brown #undef __FUNCT__
4106cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices"
4116cab3a1bSJed Brown /*@
4126cab3a1bSJed Brown    SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX()
4136cab3a1bSJed Brown 
4146cab3a1bSJed Brown    Collective
4156cab3a1bSJed Brown 
4166cab3a1bSJed Brown    Input Arguments:
4176cab3a1bSJed Brown .  snes - snes to configure
4186cab3a1bSJed Brown 
4196cab3a1bSJed Brown    Level: developer
4206cab3a1bSJed Brown 
4216cab3a1bSJed Brown .seealso: SNESSetUp()
4226cab3a1bSJed Brown @*/
4236cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes)
4246cab3a1bSJed Brown {
4256cab3a1bSJed Brown   PetscErrorCode ierr;
4266cab3a1bSJed Brown   DM             dm;
4276cab3a1bSJed Brown   SNESDM         sdm;
4286cab3a1bSJed Brown 
4296cab3a1bSJed Brown   PetscFunctionBegin;
4306cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4316cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
432caa4e7f2SJed Brown   if (!sdm->computejacobian) {
433a33a0d9fSJed Brown     SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_PLIB,"SNESDM not properly configured");
4343232da50SPeter Brune   } else if (!snes->jacobian && snes->mf) {
4356cab3a1bSJed Brown     Mat J;
4366cab3a1bSJed Brown     void *functx;
4376cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4386cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4396cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4406cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
4413232da50SPeter Brune     ierr = SNESSetJacobian(snes,J,J,0,0);CHKERRQ(ierr);
4426cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
443caa4e7f2SJed Brown   } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
4446cab3a1bSJed Brown     Mat J,B;
4456cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4466cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4476cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4486cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
44906f20277SJed Brown     /* sdm->computejacobian was already set to reach here */
45006f20277SJed Brown     ierr = SNESSetJacobian(snes,J,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
4516cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
4526cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
453caa4e7f2SJed Brown   } else if (!snes->jacobian_pre) {
4546cab3a1bSJed Brown     Mat J,B;
4556cab3a1bSJed Brown     J = snes->jacobian;
4566cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4576cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
4586cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
4596cab3a1bSJed Brown   }
460caa4e7f2SJed Brown   {
461caa4e7f2SJed Brown     KSP ksp;
462caa4e7f2SJed Brown     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
463caa4e7f2SJed Brown     ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr);
46416ebb321SJed Brown     ierr = DMCoarsenHookAdd(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr);
465caa4e7f2SJed Brown   }
4666cab3a1bSJed Brown   PetscFunctionReturn(0);
4676cab3a1bSJed Brown }
4686cab3a1bSJed Brown 
4696cab3a1bSJed Brown #undef __FUNCT__
4704a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions"
4719b94acceSBarry Smith /*@
47294b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
4739b94acceSBarry Smith 
474c7afd0dbSLois Curfman McInnes    Collective on SNES
475c7afd0dbSLois Curfman McInnes 
4769b94acceSBarry Smith    Input Parameter:
4779b94acceSBarry Smith .  snes - the SNES context
4789b94acceSBarry Smith 
47936851e7fSLois Curfman McInnes    Options Database Keys:
480ea630c6eSPeter Brune +  -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas
48182738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
48282738288SBarry Smith                 of the change in the solution between steps
48370441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
484b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
485b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
486b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
4874839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
488ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
489a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
490e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
491b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
4922492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
49382738288SBarry Smith                                solver; hence iterations will continue until max_it
4941fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
49582738288SBarry Smith                                of convergence test
496e8105e01SRichard Katz .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
497e8105e01SRichard Katz                                        filename given prints to stdout
498a6570f20SBarry Smith .  -snes_monitor_solution - plots solution at each iteration
499a6570f20SBarry Smith .  -snes_monitor_residual - plots residual (not its norm) at each iteration
500a6570f20SBarry Smith .  -snes_monitor_solution_update - plots update to solution at each iteration
5014619e776SBarry Smith .  -snes_monitor_lg_residualnorm - plots residual norm at each iteration
502*459f5d12SBarry Smith .  -snes_monitor_lg_range - plots residual norm at each iteration
503e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
504e2e60de9SPeter Brune .  -snes_fd_color - use finite differences with coloring to compute Jacobian
5055968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
506fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
50782738288SBarry Smith 
50882738288SBarry Smith     Options Database for Eisenstat-Walker method:
509fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
5104b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
51136851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
51236851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
51336851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
51436851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
51536851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
51636851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
51782738288SBarry Smith 
51811ca99fdSLois Curfman McInnes    Notes:
51911ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
5200598bfebSBarry Smith    the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>.
52183e2fdc7SBarry Smith 
52236851e7fSLois Curfman McInnes    Level: beginner
52336851e7fSLois Curfman McInnes 
5249b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
5259b94acceSBarry Smith 
52669ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
5279b94acceSBarry Smith @*/
5287087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
5299b94acceSBarry Smith {
530d8f46077SPeter Brune   PetscBool               flg,pcset;
531d8f46077SPeter Brune   PetscInt                i,indx,lag,grids;
532aa3661deSLisandro Dalcin   MatStructure            matflag;
53385385478SLisandro Dalcin   const char              *deft = SNESLS;
53485385478SLisandro Dalcin   const char              *convtests[] = {"default","skip"};
53585385478SLisandro Dalcin   SNESKSPEW               *kctx = NULL;
536e8105e01SRichard Katz   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
537649052a6SBarry Smith   PetscViewer             monviewer;
53885385478SLisandro Dalcin   PetscErrorCode          ierr;
539c40d0f55SPeter Brune   PCSide                  pcside;
540a64e098fSPeter Brune   const char              *optionsprefix;
5419b94acceSBarry Smith 
5423a40ed3dSBarry Smith   PetscFunctionBegin;
5430700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
544ca161407SBarry Smith 
545186905e3SBarry Smith   if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
5463194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
5477adad957SLisandro Dalcin     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
548b0a32e0cSBarry Smith     ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
549d64ed03dSBarry Smith     if (flg) {
550186905e3SBarry Smith       ierr = SNESSetType(snes,type);CHKERRQ(ierr);
5517adad957SLisandro Dalcin     } else if (!((PetscObject)snes)->type_name) {
552186905e3SBarry Smith       ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
553d64ed03dSBarry Smith     }
55490d69ab7SBarry Smith     /* not used here, but called so will go into help messaage */
555909c8a9fSBarry Smith     ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr);
55693c39befSBarry Smith 
557c60f73f4SPeter Brune     ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);CHKERRQ(ierr);
55857034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr);
559186905e3SBarry Smith 
56057034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr);
561b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr);
562b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr);
56324254dc1SJed Brown     ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr);
564ddf469c8SBarry Smith     ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr);
565acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr);
56685385478SLisandro Dalcin 
567a8054027SBarry Smith     ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
568a8054027SBarry Smith     if (flg) {
569a8054027SBarry Smith       ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
570a8054027SBarry Smith     }
571e35cf81dSBarry Smith     ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
572e35cf81dSBarry Smith     if (flg) {
573e35cf81dSBarry Smith       ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
574e35cf81dSBarry Smith     }
575efd51863SBarry Smith     ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
576efd51863SBarry Smith     if (flg) {
577efd51863SBarry Smith       ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
578efd51863SBarry Smith     }
579a8054027SBarry Smith 
58085385478SLisandro Dalcin     ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
58185385478SLisandro Dalcin     if (flg) {
58285385478SLisandro Dalcin       switch (indx) {
5837f7931b9SBarry Smith       case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break;
5847f7931b9SBarry Smith       case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);    break;
58585385478SLisandro Dalcin       }
58685385478SLisandro Dalcin     }
58785385478SLisandro Dalcin 
588acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr);
589186905e3SBarry Smith 
590fdacfa88SPeter Brune     ierr = PetscOptionsEList("-snes_norm_type","SNES Norm type","SNESSetNormType",SNESNormTypes,5,"function",&indx,&flg);CHKERRQ(ierr);
591fdacfa88SPeter Brune     if (flg) { ierr = SNESSetNormType(snes,(SNESNormType)indx);CHKERRQ(ierr); }
592fdacfa88SPeter Brune 
59385385478SLisandro Dalcin     kctx = (SNESKSPEW *)snes->kspconvctx;
59485385478SLisandro Dalcin 
595acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr);
596186905e3SBarry Smith 
597fa9f3622SBarry Smith     ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr);
598fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr);
599fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr);
600fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr);
601fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr);
602fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr);
603fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr);
604186905e3SBarry Smith 
60590d69ab7SBarry Smith     flg  = PETSC_FALSE;
606acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
607a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
608eabae89aSBarry Smith 
609a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
610e8105e01SRichard Katz     if (flg) {
611649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
612649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
613e8105e01SRichard Katz     }
614eabae89aSBarry Smith 
615b271bb04SBarry Smith     ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
616b271bb04SBarry Smith     if (flg) {
617b271bb04SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr);
618b271bb04SBarry Smith     }
619b271bb04SBarry Smith 
620a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
621eabae89aSBarry Smith     if (flg) {
622649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
623f1bef1bcSMatthew Knepley       ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr);
624e8105e01SRichard Katz     }
625eabae89aSBarry Smith 
626a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
627eabae89aSBarry Smith     if (flg) {
628649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
629649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
630eabae89aSBarry Smith     }
631eabae89aSBarry Smith 
6325180491cSLisandro Dalcin     ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
6335180491cSLisandro Dalcin     if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);}
6345180491cSLisandro Dalcin 
63590d69ab7SBarry Smith     flg  = PETSC_FALSE;
636acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
637a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
63890d69ab7SBarry Smith     flg  = PETSC_FALSE;
639acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
640a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
64190d69ab7SBarry Smith     flg  = PETSC_FALSE;
642acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
643a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
64490d69ab7SBarry Smith     flg  = PETSC_FALSE;
6454619e776SBarry Smith     ierr = PetscOptionsBool("-snes_monitor_lg_residualnorm","Plot function norm at each iteration","SNESMonitorLGResidualNorm",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
646*459f5d12SBarry Smith     if (flg) {
647*459f5d12SBarry Smith       PetscDrawLG ctx;
648*459f5d12SBarry Smith 
649*459f5d12SBarry Smith       ierr = SNESMonitorLGCreate(0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&ctx);CHKERRQ(ierr);
650*459f5d12SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))SNESMonitorLGDestroy);CHKERRQ(ierr);
651*459f5d12SBarry Smith     }
65290d69ab7SBarry Smith     flg  = PETSC_FALSE;
6534619e776SBarry Smith     ierr = PetscOptionsBool("-snes_monitor_lg_range","Plot function range at each iteration","SNESMonitorLGRange",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
654*459f5d12SBarry Smith     if (flg) {
655*459f5d12SBarry Smith       PetscViewer ctx;
656e24b481bSBarry Smith 
657*459f5d12SBarry Smith       ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&ctx);CHKERRQ(ierr);
658*459f5d12SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
659*459f5d12SBarry Smith     }
6602e7541e6SPeter Brune 
6612e7541e6SPeter Brune     flg  = PETSC_FALSE;
6622e7541e6SPeter Brune     ierr = PetscOptionsBool("-snes_monitor_jacupdate_spectrum","Print the change in the spectrum of the Jacobian","SNESMonitorJacUpdateSpectrum",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
6632e7541e6SPeter Brune     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorJacUpdateSpectrum,0,0);CHKERRQ(ierr);}
6642e7541e6SPeter Brune 
66590d69ab7SBarry Smith     flg  = PETSC_FALSE;
666acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
6674b27c08aSLois Curfman McInnes     if (flg) {
6686cab3a1bSJed Brown       void *functx;
6696cab3a1bSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
6706cab3a1bSJed Brown       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr);
671ae15b995SBarry Smith       ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
6729b94acceSBarry Smith     }
673639f9d9dSBarry Smith 
67444848bc4SPeter Brune     flg  = PETSC_FALSE;
67544848bc4SPeter Brune     ierr = PetscOptionsBool("-snes_fd_color","Use finite differences with coloring to compute Jacobian","SNESDefaultComputeJacobianColor",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
67644848bc4SPeter Brune     if (flg) {
67744848bc4SPeter Brune       void *functx;
67844848bc4SPeter Brune       ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
6790171d955SPeter Brune       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobianColor,0);CHKERRQ(ierr);
68044848bc4SPeter Brune       ierr = PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n");CHKERRQ(ierr);
68144848bc4SPeter Brune     }
68244848bc4SPeter Brune 
683aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
684d8f46077SPeter Brune     ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&snes->mf_operator,&flg);CHKERRQ(ierr);
685d8f46077SPeter Brune     if (flg && snes->mf_operator) {
686a8248277SBarry Smith       snes->mf_operator = PETSC_TRUE;
687d8f46077SPeter Brune       snes->mf = PETSC_TRUE;
688a8248277SBarry Smith     }
689aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
690d8f46077SPeter Brune     ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&snes->mf,&flg);CHKERRQ(ierr);
691d8f46077SPeter Brune     if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE;
692d8f46077SPeter Brune     ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",snes->mf_version,&snes->mf_version,0);CHKERRQ(ierr);
693d28543b3SPeter Brune 
694c40d0f55SPeter Brune     flg = PETSC_FALSE;
695c40d0f55SPeter Brune     ierr = SNESGetPCSide(snes,&pcside);
696c40d0f55SPeter Brune     ierr = PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);CHKERRQ(ierr);
697c40d0f55SPeter Brune     if (flg) {ierr = SNESSetPCSide(snes,pcside);CHKERRQ(ierr);}
698c40d0f55SPeter Brune 
69989b92e6fSPeter Brune     /* GS Options */
70089b92e6fSPeter Brune     ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr);
70189b92e6fSPeter Brune 
70276b2cf59SMatthew Knepley     for (i = 0; i < numberofsetfromoptions; i++) {
70376b2cf59SMatthew Knepley       ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
70476b2cf59SMatthew Knepley     }
70576b2cf59SMatthew Knepley 
706e7788613SBarry Smith     if (snes->ops->setfromoptions) {
707e7788613SBarry Smith       ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr);
708639f9d9dSBarry Smith     }
7095d973c19SBarry Smith 
7105d973c19SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
7115d973c19SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr);
712b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
7134bbc92c1SBarry Smith 
7141cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
715aa3661deSLisandro Dalcin   ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
716aa3661deSLisandro Dalcin   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr);
71785385478SLisandro Dalcin   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
71893993e2dSLois Curfman McInnes 
7199e764e56SPeter Brune   if (!snes->linesearch) {
720f1c6b773SPeter Brune     ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
7219e764e56SPeter Brune   }
722f1c6b773SPeter Brune   ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr);
7239e764e56SPeter Brune 
72451e86f29SPeter Brune   /* if someone has set the SNES PC type, create it. */
72551e86f29SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
72651e86f29SPeter Brune   ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr);
72751e86f29SPeter Brune   if (pcset && (!snes->pc)) {
72851e86f29SPeter Brune     ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr);
72951e86f29SPeter Brune   }
7303a40ed3dSBarry Smith   PetscFunctionReturn(0);
7319b94acceSBarry Smith }
7329b94acceSBarry Smith 
733d25893d9SBarry Smith #undef __FUNCT__
734d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext"
735d25893d9SBarry Smith /*@
736d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
737d25893d9SBarry Smith    the nonlinear solvers.
738d25893d9SBarry Smith 
739d25893d9SBarry Smith    Logically Collective on SNES
740d25893d9SBarry Smith 
741d25893d9SBarry Smith    Input Parameters:
742d25893d9SBarry Smith +  snes - the SNES context
743d25893d9SBarry Smith .  compute - function to compute the context
744d25893d9SBarry Smith -  destroy - function to destroy the context
745d25893d9SBarry Smith 
746d25893d9SBarry Smith    Level: intermediate
747d25893d9SBarry Smith 
748d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
749d25893d9SBarry Smith 
750d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
751d25893d9SBarry Smith @*/
752d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
753d25893d9SBarry Smith {
754d25893d9SBarry Smith   PetscFunctionBegin;
755d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
756d25893d9SBarry Smith   snes->ops->usercompute = compute;
757d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
758d25893d9SBarry Smith   PetscFunctionReturn(0);
759d25893d9SBarry Smith }
760a847f771SSatish Balay 
7614a2ae208SSatish Balay #undef __FUNCT__
7624a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
763b07ff414SBarry Smith /*@
7649b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
7659b94acceSBarry Smith    the nonlinear solvers.
7669b94acceSBarry Smith 
7673f9fe445SBarry Smith    Logically Collective on SNES
768fee21e36SBarry Smith 
769c7afd0dbSLois Curfman McInnes    Input Parameters:
770c7afd0dbSLois Curfman McInnes +  snes - the SNES context
771c7afd0dbSLois Curfman McInnes -  usrP - optional user context
772c7afd0dbSLois Curfman McInnes 
77336851e7fSLois Curfman McInnes    Level: intermediate
77436851e7fSLois Curfman McInnes 
7759b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
7769b94acceSBarry Smith 
777ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext()
7789b94acceSBarry Smith @*/
7797087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
7809b94acceSBarry Smith {
7811b2093e4SBarry Smith   PetscErrorCode ierr;
782b07ff414SBarry Smith   KSP            ksp;
7831b2093e4SBarry Smith 
7843a40ed3dSBarry Smith   PetscFunctionBegin;
7850700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
786b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
787b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
7889b94acceSBarry Smith   snes->user = usrP;
7893a40ed3dSBarry Smith   PetscFunctionReturn(0);
7909b94acceSBarry Smith }
79174679c65SBarry Smith 
7924a2ae208SSatish Balay #undef __FUNCT__
7934a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
794b07ff414SBarry Smith /*@
7959b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
7969b94acceSBarry Smith    nonlinear solvers.
7979b94acceSBarry Smith 
798c7afd0dbSLois Curfman McInnes    Not Collective
799c7afd0dbSLois Curfman McInnes 
8009b94acceSBarry Smith    Input Parameter:
8019b94acceSBarry Smith .  snes - SNES context
8029b94acceSBarry Smith 
8039b94acceSBarry Smith    Output Parameter:
8049b94acceSBarry Smith .  usrP - user context
8059b94acceSBarry Smith 
80636851e7fSLois Curfman McInnes    Level: intermediate
80736851e7fSLois Curfman McInnes 
8089b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
8099b94acceSBarry Smith 
8109b94acceSBarry Smith .seealso: SNESSetApplicationContext()
8119b94acceSBarry Smith @*/
812e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
8139b94acceSBarry Smith {
8143a40ed3dSBarry Smith   PetscFunctionBegin;
8150700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
816e71120c6SJed Brown   *(void**)usrP = snes->user;
8173a40ed3dSBarry Smith   PetscFunctionReturn(0);
8189b94acceSBarry Smith }
81974679c65SBarry Smith 
8204a2ae208SSatish Balay #undef __FUNCT__
8214a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
8229b94acceSBarry Smith /*@
823c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
824c8228a4eSBarry Smith    at this time.
8259b94acceSBarry Smith 
826c7afd0dbSLois Curfman McInnes    Not Collective
827c7afd0dbSLois Curfman McInnes 
8289b94acceSBarry Smith    Input Parameter:
8299b94acceSBarry Smith .  snes - SNES context
8309b94acceSBarry Smith 
8319b94acceSBarry Smith    Output Parameter:
8329b94acceSBarry Smith .  iter - iteration number
8339b94acceSBarry Smith 
834c8228a4eSBarry Smith    Notes:
835c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
836c8228a4eSBarry Smith 
837c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
83808405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
83908405cd6SLois Curfman McInnes .vb
84008405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
84108405cd6SLois Curfman McInnes       if (!(it % 2)) {
84208405cd6SLois Curfman McInnes         [compute Jacobian here]
84308405cd6SLois Curfman McInnes       }
84408405cd6SLois Curfman McInnes .ve
845c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
84608405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
847c8228a4eSBarry Smith 
84836851e7fSLois Curfman McInnes    Level: intermediate
84936851e7fSLois Curfman McInnes 
8502b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
8512b668275SBarry Smith 
852b850b91aSLisandro Dalcin .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
8539b94acceSBarry Smith @*/
8547087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
8559b94acceSBarry Smith {
8563a40ed3dSBarry Smith   PetscFunctionBegin;
8570700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8584482741eSBarry Smith   PetscValidIntPointer(iter,2);
8599b94acceSBarry Smith   *iter = snes->iter;
8603a40ed3dSBarry Smith   PetscFunctionReturn(0);
8619b94acceSBarry Smith }
86274679c65SBarry Smith 
8634a2ae208SSatish Balay #undef __FUNCT__
864360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber"
865360c497dSPeter Brune /*@
866360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
867360c497dSPeter Brune 
868360c497dSPeter Brune    Not Collective
869360c497dSPeter Brune 
870360c497dSPeter Brune    Input Parameter:
871360c497dSPeter Brune .  snes - SNES context
872360c497dSPeter Brune .  iter - iteration number
873360c497dSPeter Brune 
874360c497dSPeter Brune    Level: developer
875360c497dSPeter Brune 
876360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number,
877360c497dSPeter Brune 
878360c497dSPeter Brune .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
879360c497dSPeter Brune @*/
880360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
881360c497dSPeter Brune {
882360c497dSPeter Brune   PetscErrorCode ierr;
883360c497dSPeter Brune 
884360c497dSPeter Brune   PetscFunctionBegin;
885360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
886360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
887360c497dSPeter Brune   snes->iter = iter;
888360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
889360c497dSPeter Brune   PetscFunctionReturn(0);
890360c497dSPeter Brune }
891360c497dSPeter Brune 
892360c497dSPeter Brune #undef __FUNCT__
8934a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm"
8949b94acceSBarry Smith /*@
8959b94acceSBarry Smith    SNESGetFunctionNorm - Gets the norm of the current function that was set
8969b94acceSBarry Smith    with SNESSSetFunction().
8979b94acceSBarry Smith 
898c7afd0dbSLois Curfman McInnes    Collective on SNES
899c7afd0dbSLois Curfman McInnes 
9009b94acceSBarry Smith    Input Parameter:
9019b94acceSBarry Smith .  snes - SNES context
9029b94acceSBarry Smith 
9039b94acceSBarry Smith    Output Parameter:
9049b94acceSBarry Smith .  fnorm - 2-norm of function
9059b94acceSBarry Smith 
90636851e7fSLois Curfman McInnes    Level: intermediate
90736851e7fSLois Curfman McInnes 
9089b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm
909a86d99e1SLois Curfman McInnes 
910b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
9119b94acceSBarry Smith @*/
9127087cfbeSBarry Smith PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
9139b94acceSBarry Smith {
9143a40ed3dSBarry Smith   PetscFunctionBegin;
9150700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9164482741eSBarry Smith   PetscValidScalarPointer(fnorm,2);
9179b94acceSBarry Smith   *fnorm = snes->norm;
9183a40ed3dSBarry Smith   PetscFunctionReturn(0);
9199b94acceSBarry Smith }
92074679c65SBarry Smith 
921360c497dSPeter Brune 
922360c497dSPeter Brune #undef __FUNCT__
923360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm"
924360c497dSPeter Brune /*@
925360c497dSPeter Brune    SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm().
926360c497dSPeter Brune 
927360c497dSPeter Brune    Collective on SNES
928360c497dSPeter Brune 
929360c497dSPeter Brune    Input Parameter:
930360c497dSPeter Brune .  snes - SNES context
931360c497dSPeter Brune .  fnorm - 2-norm of function
932360c497dSPeter Brune 
933360c497dSPeter Brune    Level: developer
934360c497dSPeter Brune 
935360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm
936360c497dSPeter Brune 
937360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm().
938360c497dSPeter Brune @*/
939360c497dSPeter Brune PetscErrorCode  SNESSetFunctionNorm(SNES snes,PetscReal fnorm)
940360c497dSPeter Brune {
941360c497dSPeter Brune 
942360c497dSPeter Brune   PetscErrorCode ierr;
943360c497dSPeter Brune 
944360c497dSPeter Brune   PetscFunctionBegin;
945360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
946360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
947360c497dSPeter Brune   snes->norm = fnorm;
948360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
949360c497dSPeter Brune   PetscFunctionReturn(0);
950360c497dSPeter Brune }
951360c497dSPeter Brune 
9524a2ae208SSatish Balay #undef __FUNCT__
953b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
9549b94acceSBarry Smith /*@
955b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
9569b94acceSBarry Smith    attempted by the nonlinear solver.
9579b94acceSBarry Smith 
958c7afd0dbSLois Curfman McInnes    Not Collective
959c7afd0dbSLois Curfman McInnes 
9609b94acceSBarry Smith    Input Parameter:
9619b94acceSBarry Smith .  snes - SNES context
9629b94acceSBarry Smith 
9639b94acceSBarry Smith    Output Parameter:
9649b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
9659b94acceSBarry Smith 
966c96a6f78SLois Curfman McInnes    Notes:
967c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
968c96a6f78SLois Curfman McInnes 
96936851e7fSLois Curfman McInnes    Level: intermediate
97036851e7fSLois Curfman McInnes 
9719b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
97258ebbce7SBarry Smith 
973e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
97458ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
9759b94acceSBarry Smith @*/
9767087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
9779b94acceSBarry Smith {
9783a40ed3dSBarry Smith   PetscFunctionBegin;
9790700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9804482741eSBarry Smith   PetscValidIntPointer(nfails,2);
98150ffb88aSMatthew Knepley   *nfails = snes->numFailures;
98250ffb88aSMatthew Knepley   PetscFunctionReturn(0);
98350ffb88aSMatthew Knepley }
98450ffb88aSMatthew Knepley 
98550ffb88aSMatthew Knepley #undef __FUNCT__
986b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
98750ffb88aSMatthew Knepley /*@
988b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
98950ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
99050ffb88aSMatthew Knepley 
99150ffb88aSMatthew Knepley    Not Collective
99250ffb88aSMatthew Knepley 
99350ffb88aSMatthew Knepley    Input Parameters:
99450ffb88aSMatthew Knepley +  snes     - SNES context
99550ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
99650ffb88aSMatthew Knepley 
99750ffb88aSMatthew Knepley    Level: intermediate
99850ffb88aSMatthew Knepley 
99950ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
100058ebbce7SBarry Smith 
1001e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
100258ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
100350ffb88aSMatthew Knepley @*/
10047087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
100550ffb88aSMatthew Knepley {
100650ffb88aSMatthew Knepley   PetscFunctionBegin;
10070700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
100850ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
100950ffb88aSMatthew Knepley   PetscFunctionReturn(0);
101050ffb88aSMatthew Knepley }
101150ffb88aSMatthew Knepley 
101250ffb88aSMatthew Knepley #undef __FUNCT__
1013b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
101450ffb88aSMatthew Knepley /*@
1015b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
101650ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
101750ffb88aSMatthew Knepley 
101850ffb88aSMatthew Knepley    Not Collective
101950ffb88aSMatthew Knepley 
102050ffb88aSMatthew Knepley    Input Parameter:
102150ffb88aSMatthew Knepley .  snes     - SNES context
102250ffb88aSMatthew Knepley 
102350ffb88aSMatthew Knepley    Output Parameter:
102450ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
102550ffb88aSMatthew Knepley 
102650ffb88aSMatthew Knepley    Level: intermediate
102750ffb88aSMatthew Knepley 
102850ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
102958ebbce7SBarry Smith 
1030e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
103158ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
103258ebbce7SBarry Smith 
103350ffb88aSMatthew Knepley @*/
10347087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
103550ffb88aSMatthew Knepley {
103650ffb88aSMatthew Knepley   PetscFunctionBegin;
10370700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10384482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
103950ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
10403a40ed3dSBarry Smith   PetscFunctionReturn(0);
10419b94acceSBarry Smith }
1042a847f771SSatish Balay 
10434a2ae208SSatish Balay #undef __FUNCT__
10442541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
10452541af92SBarry Smith /*@
10462541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
10472541af92SBarry Smith      done by SNES.
10482541af92SBarry Smith 
10492541af92SBarry Smith    Not Collective
10502541af92SBarry Smith 
10512541af92SBarry Smith    Input Parameter:
10522541af92SBarry Smith .  snes     - SNES context
10532541af92SBarry Smith 
10542541af92SBarry Smith    Output Parameter:
10552541af92SBarry Smith .  nfuncs - number of evaluations
10562541af92SBarry Smith 
10572541af92SBarry Smith    Level: intermediate
10582541af92SBarry Smith 
10592541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
106058ebbce7SBarry Smith 
1061e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
10622541af92SBarry Smith @*/
10637087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
10642541af92SBarry Smith {
10652541af92SBarry Smith   PetscFunctionBegin;
10660700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10672541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
10682541af92SBarry Smith   *nfuncs = snes->nfuncs;
10692541af92SBarry Smith   PetscFunctionReturn(0);
10702541af92SBarry Smith }
10712541af92SBarry Smith 
10722541af92SBarry Smith #undef __FUNCT__
10733d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
10743d4c4710SBarry Smith /*@
10753d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
10763d4c4710SBarry Smith    linear solvers.
10773d4c4710SBarry Smith 
10783d4c4710SBarry Smith    Not Collective
10793d4c4710SBarry Smith 
10803d4c4710SBarry Smith    Input Parameter:
10813d4c4710SBarry Smith .  snes - SNES context
10823d4c4710SBarry Smith 
10833d4c4710SBarry Smith    Output Parameter:
10843d4c4710SBarry Smith .  nfails - number of failed solves
10853d4c4710SBarry Smith 
10863d4c4710SBarry Smith    Notes:
10873d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
10883d4c4710SBarry Smith 
10893d4c4710SBarry Smith    Level: intermediate
10903d4c4710SBarry Smith 
10913d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
109258ebbce7SBarry Smith 
1093e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
10943d4c4710SBarry Smith @*/
10957087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
10963d4c4710SBarry Smith {
10973d4c4710SBarry Smith   PetscFunctionBegin;
10980700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10993d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
11003d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
11013d4c4710SBarry Smith   PetscFunctionReturn(0);
11023d4c4710SBarry Smith }
11033d4c4710SBarry Smith 
11043d4c4710SBarry Smith #undef __FUNCT__
11053d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
11063d4c4710SBarry Smith /*@
11073d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
11083d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
11093d4c4710SBarry Smith 
11103f9fe445SBarry Smith    Logically Collective on SNES
11113d4c4710SBarry Smith 
11123d4c4710SBarry Smith    Input Parameters:
11133d4c4710SBarry Smith +  snes     - SNES context
11143d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
11153d4c4710SBarry Smith 
11163d4c4710SBarry Smith    Level: intermediate
11173d4c4710SBarry Smith 
1118a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
11193d4c4710SBarry Smith 
11203d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
11213d4c4710SBarry Smith 
112258ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
11233d4c4710SBarry Smith @*/
11247087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
11253d4c4710SBarry Smith {
11263d4c4710SBarry Smith   PetscFunctionBegin;
11270700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1128c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
11293d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
11303d4c4710SBarry Smith   PetscFunctionReturn(0);
11313d4c4710SBarry Smith }
11323d4c4710SBarry Smith 
11333d4c4710SBarry Smith #undef __FUNCT__
11343d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
11353d4c4710SBarry Smith /*@
11363d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
11373d4c4710SBarry Smith      are allowed before SNES terminates
11383d4c4710SBarry Smith 
11393d4c4710SBarry Smith    Not Collective
11403d4c4710SBarry Smith 
11413d4c4710SBarry Smith    Input Parameter:
11423d4c4710SBarry Smith .  snes     - SNES context
11433d4c4710SBarry Smith 
11443d4c4710SBarry Smith    Output Parameter:
11453d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
11463d4c4710SBarry Smith 
11473d4c4710SBarry Smith    Level: intermediate
11483d4c4710SBarry Smith 
11493d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
11503d4c4710SBarry Smith 
11513d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
11523d4c4710SBarry Smith 
1153e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
11543d4c4710SBarry Smith @*/
11557087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
11563d4c4710SBarry Smith {
11573d4c4710SBarry Smith   PetscFunctionBegin;
11580700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11593d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
11603d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
11613d4c4710SBarry Smith   PetscFunctionReturn(0);
11623d4c4710SBarry Smith }
11633d4c4710SBarry Smith 
11643d4c4710SBarry Smith #undef __FUNCT__
1165b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
1166c96a6f78SLois Curfman McInnes /*@
1167b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1168c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1169c96a6f78SLois Curfman McInnes 
1170c7afd0dbSLois Curfman McInnes    Not Collective
1171c7afd0dbSLois Curfman McInnes 
1172c96a6f78SLois Curfman McInnes    Input Parameter:
1173c96a6f78SLois Curfman McInnes .  snes - SNES context
1174c96a6f78SLois Curfman McInnes 
1175c96a6f78SLois Curfman McInnes    Output Parameter:
1176c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1177c96a6f78SLois Curfman McInnes 
1178c96a6f78SLois Curfman McInnes    Notes:
1179c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1180c96a6f78SLois Curfman McInnes 
118136851e7fSLois Curfman McInnes    Level: intermediate
118236851e7fSLois Curfman McInnes 
1183c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
11842b668275SBarry Smith 
11858c7482ecSBarry Smith .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
1186c96a6f78SLois Curfman McInnes @*/
11877087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
1188c96a6f78SLois Curfman McInnes {
11893a40ed3dSBarry Smith   PetscFunctionBegin;
11900700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11914482741eSBarry Smith   PetscValidIntPointer(lits,2);
1192c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
11933a40ed3dSBarry Smith   PetscFunctionReturn(0);
1194c96a6f78SLois Curfman McInnes }
1195c96a6f78SLois Curfman McInnes 
11964a2ae208SSatish Balay #undef __FUNCT__
119794b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP"
119852baeb72SSatish Balay /*@
119994b7f48cSBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
12009b94acceSBarry Smith 
120194b7f48cSBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
1202c7afd0dbSLois Curfman McInnes 
12039b94acceSBarry Smith    Input Parameter:
12049b94acceSBarry Smith .  snes - the SNES context
12059b94acceSBarry Smith 
12069b94acceSBarry Smith    Output Parameter:
120794b7f48cSBarry Smith .  ksp - the KSP context
12089b94acceSBarry Smith 
12099b94acceSBarry Smith    Notes:
121094b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
12119b94acceSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
12122999313aSBarry Smith    PC contexts as well.
12139b94acceSBarry Smith 
121436851e7fSLois Curfman McInnes    Level: beginner
121536851e7fSLois Curfman McInnes 
121694b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
12179b94acceSBarry Smith 
12182999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
12199b94acceSBarry Smith @*/
12207087cfbeSBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
12219b94acceSBarry Smith {
12221cee3971SBarry Smith   PetscErrorCode ierr;
12231cee3971SBarry Smith 
12243a40ed3dSBarry Smith   PetscFunctionBegin;
12250700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12264482741eSBarry Smith   PetscValidPointer(ksp,2);
12271cee3971SBarry Smith 
12281cee3971SBarry Smith   if (!snes->ksp) {
12291cee3971SBarry Smith     ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr);
12301cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
12311cee3971SBarry Smith     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
12321cee3971SBarry Smith   }
123394b7f48cSBarry Smith   *ksp = snes->ksp;
12343a40ed3dSBarry Smith   PetscFunctionReturn(0);
12359b94acceSBarry Smith }
123682bf6240SBarry Smith 
12374a2ae208SSatish Balay #undef __FUNCT__
12382999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
12392999313aSBarry Smith /*@
12402999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
12412999313aSBarry Smith 
12422999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
12432999313aSBarry Smith 
12442999313aSBarry Smith    Input Parameters:
12452999313aSBarry Smith +  snes - the SNES context
12462999313aSBarry Smith -  ksp - the KSP context
12472999313aSBarry Smith 
12482999313aSBarry Smith    Notes:
12492999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
12502999313aSBarry Smith    so this routine is rarely needed.
12512999313aSBarry Smith 
12522999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
12532999313aSBarry Smith    decreased by one.
12542999313aSBarry Smith 
12552999313aSBarry Smith    Level: developer
12562999313aSBarry Smith 
12572999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
12582999313aSBarry Smith 
12592999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
12602999313aSBarry Smith @*/
12617087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
12622999313aSBarry Smith {
12632999313aSBarry Smith   PetscErrorCode ierr;
12642999313aSBarry Smith 
12652999313aSBarry Smith   PetscFunctionBegin;
12660700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12670700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
12682999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
12697dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1270906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
12712999313aSBarry Smith   snes->ksp = ksp;
12722999313aSBarry Smith   PetscFunctionReturn(0);
12732999313aSBarry Smith }
12742999313aSBarry Smith 
12757adad957SLisandro Dalcin #if 0
12762999313aSBarry Smith #undef __FUNCT__
12774a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc"
12786849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
1279e24b481bSBarry Smith {
1280e24b481bSBarry Smith   PetscFunctionBegin;
1281e24b481bSBarry Smith   PetscFunctionReturn(0);
1282e24b481bSBarry Smith }
12837adad957SLisandro Dalcin #endif
1284e24b481bSBarry Smith 
12859b94acceSBarry Smith /* -----------------------------------------------------------*/
12864a2ae208SSatish Balay #undef __FUNCT__
12874a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
128852baeb72SSatish Balay /*@
12899b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
12909b94acceSBarry Smith 
1291c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1292c7afd0dbSLois Curfman McInnes 
1293c7afd0dbSLois Curfman McInnes    Input Parameters:
1294906ed7ccSBarry Smith .  comm - MPI communicator
12959b94acceSBarry Smith 
12969b94acceSBarry Smith    Output Parameter:
12979b94acceSBarry Smith .  outsnes - the new SNES context
12989b94acceSBarry Smith 
1299c7afd0dbSLois Curfman McInnes    Options Database Keys:
1300c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1301c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1302c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1303c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1304c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1305c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1306c1f60f51SBarry Smith 
130736851e7fSLois Curfman McInnes    Level: beginner
130836851e7fSLois Curfman McInnes 
13099b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
13109b94acceSBarry Smith 
1311a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1312a8054027SBarry Smith 
13139b94acceSBarry Smith @*/
13147087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
13159b94acceSBarry Smith {
1316dfbe8321SBarry Smith   PetscErrorCode      ierr;
13179b94acceSBarry Smith   SNES                snes;
1318fa9f3622SBarry Smith   SNESKSPEW           *kctx;
131937fcc0dbSBarry Smith 
13203a40ed3dSBarry Smith   PetscFunctionBegin;
1321ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
13228ba1e511SMatthew Knepley   *outsnes = PETSC_NULL;
13238ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
13248ba1e511SMatthew Knepley   ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr);
13258ba1e511SMatthew Knepley #endif
13268ba1e511SMatthew Knepley 
13273194b578SJed Brown   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
13287adad957SLisandro Dalcin 
132985385478SLisandro Dalcin   snes->ops->converged    = SNESDefaultConverged;
13302c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
133188976e71SPeter Brune   snes->tolerancesset     = PETSC_FALSE;
13329b94acceSBarry Smith   snes->max_its           = 50;
13339750a799SBarry Smith   snes->max_funcs         = 10000;
13349b94acceSBarry Smith   snes->norm              = 0.0;
1335fdacfa88SPeter Brune   snes->normtype          = SNES_NORM_FUNCTION;
1336b4874afaSBarry Smith   snes->rtol              = 1.e-8;
1337b4874afaSBarry Smith   snes->ttol              = 0.0;
133870441072SBarry Smith   snes->abstol            = 1.e-50;
1339c60f73f4SPeter Brune   snes->stol              = 1.e-8;
13404b27c08aSLois Curfman McInnes   snes->deltatol          = 1.e-12;
13419b94acceSBarry Smith   snes->nfuncs            = 0;
134250ffb88aSMatthew Knepley   snes->numFailures       = 0;
134350ffb88aSMatthew Knepley   snes->maxFailures       = 1;
13447a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1345e35cf81dSBarry Smith   snes->lagjacobian       = 1;
1346a8054027SBarry Smith   snes->lagpreconditioner = 1;
1347639f9d9dSBarry Smith   snes->numbermonitors    = 0;
13489b94acceSBarry Smith   snes->data              = 0;
13494dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1350186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
13516f24a144SLois Curfman McInnes   snes->nwork             = 0;
135258c9b817SLisandro Dalcin   snes->work              = 0;
135358c9b817SLisandro Dalcin   snes->nvwork            = 0;
135458c9b817SLisandro Dalcin   snes->vwork             = 0;
1355758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1356758f92a0SBarry Smith   snes->conv_hist_max     = 0;
1357758f92a0SBarry Smith   snes->conv_hist         = PETSC_NULL;
1358758f92a0SBarry Smith   snes->conv_hist_its     = PETSC_NULL;
1359758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1360e4ed7901SPeter Brune   snes->vec_func_init_set = PETSC_FALSE;
1361e4ed7901SPeter Brune   snes->norm_init         = 0.;
1362e4ed7901SPeter Brune   snes->norm_init_set     = PETSC_FALSE;
1363184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
136489b92e6fSPeter Brune   snes->gssweeps          = 1;
13659b94acceSBarry Smith 
1366c40d0f55SPeter Brune   snes->pcside            = PC_RIGHT;
1367c40d0f55SPeter Brune 
1368d8f46077SPeter Brune   snes->mf                = PETSC_FALSE;
1369d8f46077SPeter Brune   snes->mf_operator       = PETSC_FALSE;
1370d8f46077SPeter Brune   snes->mf_version        = 1;
1371d8f46077SPeter Brune 
13723d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
13733d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
13743d4c4710SBarry Smith 
13759b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
137638f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr);
13779b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
13789b94acceSBarry Smith   kctx->version     = 2;
13799b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
13809b94acceSBarry Smith                              this was too large for some test cases */
138175567043SBarry Smith   kctx->rtol_last   = 0.0;
13829b94acceSBarry Smith   kctx->rtol_max    = .9;
13839b94acceSBarry Smith   kctx->gamma       = 1.0;
138462d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
138571f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
13869b94acceSBarry Smith   kctx->threshold   = .1;
138775567043SBarry Smith   kctx->lresid_last = 0.0;
138875567043SBarry Smith   kctx->norm_last   = 0.0;
13899b94acceSBarry Smith 
13909b94acceSBarry Smith   *outsnes = snes;
13913a40ed3dSBarry Smith   PetscFunctionReturn(0);
13929b94acceSBarry Smith }
13939b94acceSBarry Smith 
13944a2ae208SSatish Balay #undef __FUNCT__
13954a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
13969b94acceSBarry Smith /*@C
13979b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
13989b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
13999b94acceSBarry Smith    equations.
14009b94acceSBarry Smith 
14013f9fe445SBarry Smith    Logically Collective on SNES
1402fee21e36SBarry Smith 
1403c7afd0dbSLois Curfman McInnes    Input Parameters:
1404c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1405c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1406de044059SHong Zhang .  func - function evaluation routine
1407c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1408c7afd0dbSLois Curfman McInnes          function evaluation routine (may be PETSC_NULL)
14099b94acceSBarry Smith 
1410c7afd0dbSLois Curfman McInnes    Calling sequence of func:
14118d76a1e5SLois Curfman McInnes $    func (SNES snes,Vec x,Vec f,void *ctx);
1412c7afd0dbSLois Curfman McInnes 
1413c586c404SJed Brown +  snes - the SNES context
1414c586c404SJed Brown .  x - state at which to evaluate residual
1415c586c404SJed Brown .  f - vector to put residual
1416c7afd0dbSLois Curfman McInnes -  ctx - optional user-defined function context
14179b94acceSBarry Smith 
14189b94acceSBarry Smith    Notes:
14199b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
14209b94acceSBarry Smith $      f'(x) x = -f(x),
1421c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
14229b94acceSBarry Smith 
142336851e7fSLois Curfman McInnes    Level: beginner
142436851e7fSLois Curfman McInnes 
14259b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
14269b94acceSBarry Smith 
14278b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard()
14289b94acceSBarry Smith @*/
14297087cfbeSBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
14309b94acceSBarry Smith {
143185385478SLisandro Dalcin   PetscErrorCode ierr;
14326cab3a1bSJed Brown   DM             dm;
14336cab3a1bSJed Brown 
14343a40ed3dSBarry Smith   PetscFunctionBegin;
14350700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1436d2a683ecSLisandro Dalcin   if (r) {
1437d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1438d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
143985385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
14406bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
144185385478SLisandro Dalcin     snes->vec_func = r;
1442d2a683ecSLisandro Dalcin   }
14436cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
14446cab3a1bSJed Brown   ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr);
14453a40ed3dSBarry Smith   PetscFunctionReturn(0);
14469b94acceSBarry Smith }
14479b94acceSBarry Smith 
1448646217ecSPeter Brune 
1449646217ecSPeter Brune #undef __FUNCT__
1450e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction"
1451e4ed7901SPeter Brune /*@C
1452e4ed7901SPeter Brune    SNESSetInitialFunction - Sets the function vector to be used as the
1453e4ed7901SPeter Brune    function norm at the initialization of the method.  In some
1454e4ed7901SPeter Brune    instances, the user has precomputed the function before calling
1455e4ed7901SPeter Brune    SNESSolve.  This function allows one to avoid a redundant call
1456e4ed7901SPeter Brune    to SNESComputeFunction in that case.
1457e4ed7901SPeter Brune 
1458e4ed7901SPeter Brune    Logically Collective on SNES
1459e4ed7901SPeter Brune 
1460e4ed7901SPeter Brune    Input Parameters:
1461e4ed7901SPeter Brune +  snes - the SNES context
1462e4ed7901SPeter Brune -  f - vector to store function value
1463e4ed7901SPeter Brune 
1464e4ed7901SPeter Brune    Notes:
1465e4ed7901SPeter Brune    This should not be modified during the solution procedure.
1466e4ed7901SPeter Brune 
1467e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1468e4ed7901SPeter Brune 
1469e4ed7901SPeter Brune    Level: developer
1470e4ed7901SPeter Brune 
1471e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function
1472e4ed7901SPeter Brune 
1473e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm()
1474e4ed7901SPeter Brune @*/
1475e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunction(SNES snes, Vec f)
1476e4ed7901SPeter Brune {
1477e4ed7901SPeter Brune   PetscErrorCode ierr;
1478e4ed7901SPeter Brune   Vec            vec_func;
1479e4ed7901SPeter Brune 
1480e4ed7901SPeter Brune   PetscFunctionBegin;
1481e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1482e4ed7901SPeter Brune   PetscValidHeaderSpecific(f,VEC_CLASSID,2);
1483e4ed7901SPeter Brune   PetscCheckSameComm(snes,1,f,2);
1484e4ed7901SPeter Brune   ierr = SNESGetFunction(snes,&vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
1485e4ed7901SPeter Brune   ierr = VecCopy(f, vec_func);CHKERRQ(ierr);
1486217b9c2eSPeter Brune   snes->vec_func_init_set = PETSC_TRUE;
1487e4ed7901SPeter Brune   PetscFunctionReturn(0);
1488e4ed7901SPeter Brune }
1489e4ed7901SPeter Brune 
1490e4ed7901SPeter Brune 
1491e4ed7901SPeter Brune #undef __FUNCT__
1492e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunctionNorm"
1493e4ed7901SPeter Brune /*@C
1494e4ed7901SPeter Brune    SNESSetInitialFunctionNorm - Sets the function norm to be used as the function norm
1495e4ed7901SPeter Brune    at the initialization of the  method.  In some instances, the user has precomputed
1496e4ed7901SPeter Brune    the function and its norm before calling SNESSolve.  This function allows one to
1497e4ed7901SPeter Brune    avoid a redundant call to SNESComputeFunction() and VecNorm() in that case.
1498e4ed7901SPeter Brune 
1499e4ed7901SPeter Brune    Logically Collective on SNES
1500e4ed7901SPeter Brune 
1501e4ed7901SPeter Brune    Input Parameters:
1502e4ed7901SPeter Brune +  snes - the SNES context
1503e4ed7901SPeter Brune -  fnorm - the norm of F as set by SNESSetInitialFunction()
1504e4ed7901SPeter Brune 
1505e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1506e4ed7901SPeter Brune 
1507e4ed7901SPeter Brune    Level: developer
1508e4ed7901SPeter Brune 
1509e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function, norm
1510e4ed7901SPeter Brune 
1511e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction()
1512e4ed7901SPeter Brune @*/
1513e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm)
1514e4ed7901SPeter Brune {
1515e4ed7901SPeter Brune   PetscFunctionBegin;
1516e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1517e4ed7901SPeter Brune   snes->norm_init = fnorm;
1518e4ed7901SPeter Brune   snes->norm_init_set = PETSC_TRUE;
1519e4ed7901SPeter Brune   PetscFunctionReturn(0);
1520e4ed7901SPeter Brune }
1521e4ed7901SPeter Brune 
1522e4ed7901SPeter Brune #undef __FUNCT__
1523534ebe21SPeter Brune #define __FUNCT__ "SNESSetNormType"
1524534ebe21SPeter Brune /*@
1525534ebe21SPeter Brune    SNESSetNormType - Sets the SNESNormType used in covergence and monitoring
1526534ebe21SPeter Brune    of the SNES method.
1527534ebe21SPeter Brune 
1528534ebe21SPeter Brune    Logically Collective on SNES
1529534ebe21SPeter Brune 
1530534ebe21SPeter Brune    Input Parameters:
1531534ebe21SPeter Brune +  snes - the SNES context
1532534ebe21SPeter Brune -  normtype - the type of the norm used
1533534ebe21SPeter Brune 
1534534ebe21SPeter Brune    Notes:
1535534ebe21SPeter Brune    Only certain SNES methods support certain SNESNormTypes.  Most require evaluation
1536534ebe21SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
1537534ebe21SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1538534ebe21SPeter Brune    (SNESGS) and the like do not require the norm of the function to be computed, and therfore
1539534ebe21SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
1540534ebe21SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
1541534ebe21SPeter Brune    their solution.
1542534ebe21SPeter Brune 
1543534ebe21SPeter Brune    Level: developer
1544534ebe21SPeter Brune 
1545534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1546534ebe21SPeter Brune 
1547534ebe21SPeter Brune .seealso: SNESGetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType
1548534ebe21SPeter Brune @*/
1549534ebe21SPeter Brune PetscErrorCode  SNESSetNormType(SNES snes, SNESNormType normtype)
1550534ebe21SPeter Brune {
1551534ebe21SPeter Brune   PetscFunctionBegin;
1552534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1553534ebe21SPeter Brune   snes->normtype = normtype;
1554534ebe21SPeter Brune   PetscFunctionReturn(0);
1555534ebe21SPeter Brune }
1556534ebe21SPeter Brune 
1557534ebe21SPeter Brune 
1558534ebe21SPeter Brune #undef __FUNCT__
1559534ebe21SPeter Brune #define __FUNCT__ "SNESGetNormType"
1560534ebe21SPeter Brune /*@
1561534ebe21SPeter Brune    SNESGetNormType - Gets the SNESNormType used in covergence and monitoring
1562534ebe21SPeter Brune    of the SNES method.
1563534ebe21SPeter Brune 
1564534ebe21SPeter Brune    Logically Collective on SNES
1565534ebe21SPeter Brune 
1566534ebe21SPeter Brune    Input Parameters:
1567534ebe21SPeter Brune +  snes - the SNES context
1568534ebe21SPeter Brune -  normtype - the type of the norm used
1569534ebe21SPeter Brune 
1570534ebe21SPeter Brune    Level: advanced
1571534ebe21SPeter Brune 
1572534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1573534ebe21SPeter Brune 
1574534ebe21SPeter Brune .seealso: SNESSetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType
1575534ebe21SPeter Brune @*/
1576534ebe21SPeter Brune PetscErrorCode  SNESGetNormType(SNES snes, SNESNormType *normtype)
1577534ebe21SPeter Brune {
1578534ebe21SPeter Brune   PetscFunctionBegin;
1579534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1580534ebe21SPeter Brune   *normtype = snes->normtype;
1581534ebe21SPeter Brune   PetscFunctionReturn(0);
1582534ebe21SPeter Brune }
1583534ebe21SPeter Brune 
1584534ebe21SPeter Brune #undef __FUNCT__
1585646217ecSPeter Brune #define __FUNCT__ "SNESSetGS"
1586c79ef259SPeter Brune /*@C
1587c79ef259SPeter Brune    SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for
1588c79ef259SPeter Brune    use with composed nonlinear solvers.
1589c79ef259SPeter Brune 
1590c79ef259SPeter Brune    Input Parameters:
1591c79ef259SPeter Brune +  snes   - the SNES context
1592c79ef259SPeter Brune .  gsfunc - function evaluation routine
1593c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
1594c79ef259SPeter Brune             smoother evaluation routine (may be PETSC_NULL)
1595c79ef259SPeter Brune 
1596c79ef259SPeter Brune    Calling sequence of func:
1597c79ef259SPeter Brune $    func (SNES snes,Vec x,Vec b,void *ctx);
1598c79ef259SPeter Brune 
1599c79ef259SPeter Brune +  X   - solution vector
1600c79ef259SPeter Brune .  B   - RHS vector
1601d28543b3SPeter Brune -  ctx - optional user-defined Gauss-Seidel context
1602c79ef259SPeter Brune 
1603c79ef259SPeter Brune    Notes:
1604c79ef259SPeter Brune    The GS routines are used by the composed nonlinear solver to generate
1605c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
1606c79ef259SPeter Brune 
1607d28543b3SPeter Brune    Level: intermediate
1608c79ef259SPeter Brune 
1609d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel
1610c79ef259SPeter Brune 
1611c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS()
1612c79ef259SPeter Brune @*/
16136cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx)
16146cab3a1bSJed Brown {
16156cab3a1bSJed Brown   PetscErrorCode ierr;
16166cab3a1bSJed Brown   DM             dm;
16176cab3a1bSJed Brown 
1618646217ecSPeter Brune   PetscFunctionBegin;
16196cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
16206cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
16216cab3a1bSJed Brown   ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr);
1622646217ecSPeter Brune   PetscFunctionReturn(0);
1623646217ecSPeter Brune }
1624646217ecSPeter Brune 
1625d25893d9SBarry Smith #undef __FUNCT__
162689b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps"
162789b92e6fSPeter Brune /*@
162889b92e6fSPeter Brune    SNESSetGSSweeps - Sets the number of sweeps of GS to use.
162989b92e6fSPeter Brune 
163089b92e6fSPeter Brune    Input Parameters:
163189b92e6fSPeter Brune +  snes   - the SNES context
163289b92e6fSPeter Brune -  sweeps  - the number of sweeps of GS to perform.
163389b92e6fSPeter Brune 
163489b92e6fSPeter Brune    Level: intermediate
163589b92e6fSPeter Brune 
163689b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
163789b92e6fSPeter Brune 
163889b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps()
163989b92e6fSPeter Brune @*/
164089b92e6fSPeter Brune 
1641c35f09e5SBarry Smith PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps)
1642c35f09e5SBarry Smith {
164389b92e6fSPeter Brune   PetscFunctionBegin;
164489b92e6fSPeter Brune   snes->gssweeps = sweeps;
164589b92e6fSPeter Brune   PetscFunctionReturn(0);
164689b92e6fSPeter Brune }
164789b92e6fSPeter Brune 
164889b92e6fSPeter Brune 
164989b92e6fSPeter Brune #undef __FUNCT__
165089b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps"
165189b92e6fSPeter Brune /*@
165289b92e6fSPeter Brune    SNESGetGSSweeps - Gets the number of sweeps GS will use.
165389b92e6fSPeter Brune 
165489b92e6fSPeter Brune    Input Parameters:
165589b92e6fSPeter Brune .  snes   - the SNES context
165689b92e6fSPeter Brune 
165789b92e6fSPeter Brune    Output Parameters:
165889b92e6fSPeter Brune .  sweeps  - the number of sweeps of GS to perform.
165989b92e6fSPeter Brune 
166089b92e6fSPeter Brune    Level: intermediate
166189b92e6fSPeter Brune 
166289b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
166389b92e6fSPeter Brune 
166489b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps()
166589b92e6fSPeter Brune @*/
1666c35f09e5SBarry Smith PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps)
1667c35f09e5SBarry Smith {
166889b92e6fSPeter Brune   PetscFunctionBegin;
166989b92e6fSPeter Brune   *sweeps = snes->gssweeps;
167089b92e6fSPeter Brune   PetscFunctionReturn(0);
167189b92e6fSPeter Brune }
167289b92e6fSPeter Brune 
167389b92e6fSPeter Brune #undef __FUNCT__
16748b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction"
16758b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
16768b0a5094SBarry Smith {
16778b0a5094SBarry Smith   PetscErrorCode ierr;
1678e03ab78fSPeter Brune   DM             dm;
1679e03ab78fSPeter Brune   SNESDM         sdm;
16806cab3a1bSJed Brown 
16818b0a5094SBarry Smith   PetscFunctionBegin;
1682e03ab78fSPeter Brune   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1683e03ab78fSPeter Brune   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
16848b0a5094SBarry Smith   /*  A(x)*x - b(x) */
1685e03ab78fSPeter Brune   if (sdm->computepfunction) {
1686e03ab78fSPeter Brune     ierr = (*sdm->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr);
1687e03ab78fSPeter Brune   } else if (snes->dm) {
1688e03ab78fSPeter Brune     ierr = DMComputeFunction(snes->dm,x,f);CHKERRQ(ierr);
1689e03ab78fSPeter Brune   } else {
1690e03ab78fSPeter Brune     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() or SNESSetDM() before SNESPicardComputeFunction to provide Picard function.");
1691e03ab78fSPeter Brune   }
1692e03ab78fSPeter Brune 
1693e03ab78fSPeter Brune   if (sdm->computepjacobian) {
1694e03ab78fSPeter Brune     ierr = (*sdm->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,sdm->pctx);CHKERRQ(ierr);
1695e03ab78fSPeter Brune   } else if (snes->dm) {
1696e03ab78fSPeter Brune     ierr = DMComputeJacobian(snes->dm,x,snes->jacobian,snes->jacobian_pre,&snes->matstruct);CHKERRQ(ierr);
1697e03ab78fSPeter Brune   } else {
1698e03ab78fSPeter Brune     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() or SNESSetDM() before SNESPicardComputeFunction to provide Picard matrix.");
1699e03ab78fSPeter Brune   }
1700e03ab78fSPeter Brune 
17018b0a5094SBarry Smith   ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
17028b0a5094SBarry Smith   ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
17038b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
17048b0a5094SBarry Smith   ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr);
17058b0a5094SBarry Smith   PetscFunctionReturn(0);
17068b0a5094SBarry Smith }
17078b0a5094SBarry Smith 
17088b0a5094SBarry Smith #undef __FUNCT__
17098b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian"
17108b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
17118b0a5094SBarry Smith {
17128b0a5094SBarry Smith   PetscFunctionBegin;
1713e03ab78fSPeter Brune   /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */
17148b0a5094SBarry Smith   *flag = snes->matstruct;
17158b0a5094SBarry Smith   PetscFunctionReturn(0);
17168b0a5094SBarry Smith }
17178b0a5094SBarry Smith 
17188b0a5094SBarry Smith #undef __FUNCT__
17198b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard"
17208b0a5094SBarry Smith /*@C
17210d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
17228b0a5094SBarry Smith 
17238b0a5094SBarry Smith    Logically Collective on SNES
17248b0a5094SBarry Smith 
17258b0a5094SBarry Smith    Input Parameters:
17268b0a5094SBarry Smith +  snes - the SNES context
17278b0a5094SBarry Smith .  r - vector to store function value
17288b0a5094SBarry Smith .  func - function evaluation routine
17298b0a5094SBarry 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)
17308b0a5094SBarry Smith .  mat - matrix to store A
17318b0a5094SBarry Smith .  mfunc  - function to compute matrix value
17328b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
17338b0a5094SBarry Smith          function evaluation routine (may be PETSC_NULL)
17348b0a5094SBarry Smith 
17358b0a5094SBarry Smith    Calling sequence of func:
17368b0a5094SBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
17378b0a5094SBarry Smith 
17388b0a5094SBarry Smith +  f - function vector
17398b0a5094SBarry Smith -  ctx - optional user-defined function context
17408b0a5094SBarry Smith 
17418b0a5094SBarry Smith    Calling sequence of mfunc:
17428b0a5094SBarry Smith $     mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx);
17438b0a5094SBarry Smith 
17448b0a5094SBarry Smith +  x - input vector
17458b0a5094SBarry 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(),
17468b0a5094SBarry Smith           normally just pass mat in this location
17478b0a5094SBarry Smith .  mat - form A(x) matrix
17488b0a5094SBarry Smith .  flag - flag indicating information about the preconditioner matrix
17498b0a5094SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
17508b0a5094SBarry Smith -  ctx - [optional] user-defined Jacobian context
17518b0a5094SBarry Smith 
17528b0a5094SBarry Smith    Notes:
17538b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
17548b0a5094SBarry Smith 
17558b0a5094SBarry 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}
17568b0a5094SBarry 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.
17578b0a5094SBarry Smith 
17588b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
17598b0a5094SBarry Smith 
17600d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
17610d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
17628b0a5094SBarry Smith 
17638b0a5094SBarry 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
17648b0a5094SBarry 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
17658b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
17668b0a5094SBarry Smith 
17678b0a5094SBarry Smith    Level: beginner
17688b0a5094SBarry Smith 
17698b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function
17708b0a5094SBarry Smith 
17710d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard()
17728b0a5094SBarry Smith @*/
17738b0a5094SBarry 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)
17748b0a5094SBarry Smith {
17758b0a5094SBarry Smith   PetscErrorCode ierr;
1776e03ab78fSPeter Brune   DM             dm;
1777e03ab78fSPeter Brune 
17788b0a5094SBarry Smith   PetscFunctionBegin;
17798b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1780e03ab78fSPeter Brune   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
1781e03ab78fSPeter Brune   ierr = DMSNESSetPicard(dm,func,mfunc,ctx);CHKERRQ(ierr);
17828b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
17838b0a5094SBarry Smith   ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
17848b0a5094SBarry Smith   PetscFunctionReturn(0);
17858b0a5094SBarry Smith }
17868b0a5094SBarry Smith 
17877971a8bfSPeter Brune 
17887971a8bfSPeter Brune #undef __FUNCT__
17897971a8bfSPeter Brune #define __FUNCT__ "SNESGetPicard"
17907971a8bfSPeter Brune /*@C
17917971a8bfSPeter Brune    SNESGetPicard - Returns the context for the Picard iteration
17927971a8bfSPeter Brune 
17937971a8bfSPeter Brune    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
17947971a8bfSPeter Brune 
17957971a8bfSPeter Brune    Input Parameter:
17967971a8bfSPeter Brune .  snes - the SNES context
17977971a8bfSPeter Brune 
17987971a8bfSPeter Brune    Output Parameter:
17997971a8bfSPeter Brune +  r - the function (or PETSC_NULL)
18007971a8bfSPeter Brune .  func - the function (or PETSC_NULL)
18017971a8bfSPeter Brune .  jmat - the picard matrix (or PETSC_NULL)
18027971a8bfSPeter Brune .  mat  - the picard preconditioner matrix (or PETSC_NULL)
18037971a8bfSPeter Brune .  mfunc - the function for matrix evaluation (or PETSC_NULL)
18047971a8bfSPeter Brune -  ctx - the function context (or PETSC_NULL)
18057971a8bfSPeter Brune 
18067971a8bfSPeter Brune    Level: advanced
18077971a8bfSPeter Brune 
18087971a8bfSPeter Brune .keywords: SNES, nonlinear, get, function
18097971a8bfSPeter Brune 
18107971a8bfSPeter Brune .seealso: SNESSetPicard, SNESGetFunction, SNESGetJacobian, SNESGetDM
18117971a8bfSPeter Brune @*/
18127971a8bfSPeter 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)
18137971a8bfSPeter Brune {
18147971a8bfSPeter Brune   PetscErrorCode ierr;
18157971a8bfSPeter Brune   DM             dm;
18167971a8bfSPeter Brune 
18177971a8bfSPeter Brune   PetscFunctionBegin;
18187971a8bfSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
18197971a8bfSPeter Brune   ierr = SNESGetFunction(snes,r,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
18207971a8bfSPeter Brune   ierr = SNESGetJacobian(snes,jmat,mat,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
18217971a8bfSPeter Brune   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
18227971a8bfSPeter Brune   ierr = DMSNESGetPicard(dm,func,mfunc,ctx);CHKERRQ(ierr);
18237971a8bfSPeter Brune   PetscFunctionReturn(0);
18247971a8bfSPeter Brune }
18257971a8bfSPeter Brune 
18268b0a5094SBarry Smith #undef __FUNCT__
1827d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess"
1828d25893d9SBarry Smith /*@C
1829d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1830d25893d9SBarry Smith 
1831d25893d9SBarry Smith    Logically Collective on SNES
1832d25893d9SBarry Smith 
1833d25893d9SBarry Smith    Input Parameters:
1834d25893d9SBarry Smith +  snes - the SNES context
1835d25893d9SBarry Smith .  func - function evaluation routine
1836d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
1837d25893d9SBarry Smith          function evaluation routine (may be PETSC_NULL)
1838d25893d9SBarry Smith 
1839d25893d9SBarry Smith    Calling sequence of func:
1840d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
1841d25893d9SBarry Smith 
1842d25893d9SBarry Smith .  f - function vector
1843d25893d9SBarry Smith -  ctx - optional user-defined function context
1844d25893d9SBarry Smith 
1845d25893d9SBarry Smith    Level: intermediate
1846d25893d9SBarry Smith 
1847d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
1848d25893d9SBarry Smith 
1849d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1850d25893d9SBarry Smith @*/
1851d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1852d25893d9SBarry Smith {
1853d25893d9SBarry Smith   PetscFunctionBegin;
1854d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1855d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
1856d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
1857d25893d9SBarry Smith   PetscFunctionReturn(0);
1858d25893d9SBarry Smith }
1859d25893d9SBarry Smith 
18603ab0aad5SBarry Smith /* --------------------------------------------------------------- */
18613ab0aad5SBarry Smith #undef __FUNCT__
18621096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
18631096aae1SMatthew Knepley /*@C
18641096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
18651096aae1SMatthew Knepley    it assumes a zero right hand side.
18661096aae1SMatthew Knepley 
18673f9fe445SBarry Smith    Logically Collective on SNES
18681096aae1SMatthew Knepley 
18691096aae1SMatthew Knepley    Input Parameter:
18701096aae1SMatthew Knepley .  snes - the SNES context
18711096aae1SMatthew Knepley 
18721096aae1SMatthew Knepley    Output Parameter:
1873bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
18741096aae1SMatthew Knepley 
18751096aae1SMatthew Knepley    Level: intermediate
18761096aae1SMatthew Knepley 
18771096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
18781096aae1SMatthew Knepley 
187985385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
18801096aae1SMatthew Knepley @*/
18817087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
18821096aae1SMatthew Knepley {
18831096aae1SMatthew Knepley   PetscFunctionBegin;
18840700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
18851096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
188685385478SLisandro Dalcin   *rhs = snes->vec_rhs;
18871096aae1SMatthew Knepley   PetscFunctionReturn(0);
18881096aae1SMatthew Knepley }
18891096aae1SMatthew Knepley 
18901096aae1SMatthew Knepley #undef __FUNCT__
18914a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
18929b94acceSBarry Smith /*@
189336851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
18949b94acceSBarry Smith                          SNESSetFunction().
18959b94acceSBarry Smith 
1896c7afd0dbSLois Curfman McInnes    Collective on SNES
1897c7afd0dbSLois Curfman McInnes 
18989b94acceSBarry Smith    Input Parameters:
1899c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1900c7afd0dbSLois Curfman McInnes -  x - input vector
19019b94acceSBarry Smith 
19029b94acceSBarry Smith    Output Parameter:
19033638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
19049b94acceSBarry Smith 
19051bffabb2SLois Curfman McInnes    Notes:
190636851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
190736851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
190836851e7fSLois Curfman McInnes    themselves.
190936851e7fSLois Curfman McInnes 
191036851e7fSLois Curfman McInnes    Level: developer
191136851e7fSLois Curfman McInnes 
19129b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
19139b94acceSBarry Smith 
1914a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
19159b94acceSBarry Smith @*/
19167087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
19179b94acceSBarry Smith {
1918dfbe8321SBarry Smith   PetscErrorCode ierr;
19196cab3a1bSJed Brown   DM             dm;
19206cab3a1bSJed Brown   SNESDM         sdm;
19219b94acceSBarry Smith 
19223a40ed3dSBarry Smith   PetscFunctionBegin;
19230700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
19240700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
19250700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
1926c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
1927c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
19284ec14c9cSBarry Smith   VecValidValues(x,2,PETSC_TRUE);
1929184914b5SBarry Smith 
19306cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
19316cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
1932d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
1933c40d0f55SPeter Brune   if (snes->pc && snes->pcside == PC_LEFT) {
1934c40d0f55SPeter Brune     ierr = VecCopy(x,y);CHKERRQ(ierr);
1935c40d0f55SPeter Brune     ierr = SNESSolve(snes->pc,snes->vec_rhs,y);CHKERRQ(ierr);
1936c40d0f55SPeter Brune     ierr = VecAYPX(y,-1.0,x);CHKERRQ(ierr);
1937c40d0f55SPeter Brune   } else if (sdm->computefunction) {
1938d64ed03dSBarry Smith     PetscStackPush("SNES user function");
19396cab3a1bSJed Brown     ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
1940d64ed03dSBarry Smith     PetscStackPop;
194173250ac0SBarry Smith   } else if (snes->dm) {
1942644e2e5bSBarry Smith     ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr);
1943c90fad12SPeter Brune   } else if (snes->vec_rhs) {
1944c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
1945644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
194685385478SLisandro Dalcin   if (snes->vec_rhs) {
194785385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
19483ab0aad5SBarry Smith   }
1949ae3c334cSLois Curfman McInnes   snes->nfuncs++;
1950d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
19514ec14c9cSBarry Smith   VecValidValues(y,3,PETSC_FALSE);
19523a40ed3dSBarry Smith   PetscFunctionReturn(0);
19539b94acceSBarry Smith }
19549b94acceSBarry Smith 
19554a2ae208SSatish Balay #undef __FUNCT__
1956646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS"
1957c79ef259SPeter Brune /*@
1958c79ef259SPeter Brune    SNESComputeGS - Calls the Gauss-Seidel function that has been set with
1959c79ef259SPeter Brune                    SNESSetGS().
1960c79ef259SPeter Brune 
1961c79ef259SPeter Brune    Collective on SNES
1962c79ef259SPeter Brune 
1963c79ef259SPeter Brune    Input Parameters:
1964c79ef259SPeter Brune +  snes - the SNES context
1965c79ef259SPeter Brune .  x - input vector
1966c79ef259SPeter Brune -  b - rhs vector
1967c79ef259SPeter Brune 
1968c79ef259SPeter Brune    Output Parameter:
1969c79ef259SPeter Brune .  x - new solution vector
1970c79ef259SPeter Brune 
1971c79ef259SPeter Brune    Notes:
1972c79ef259SPeter Brune    SNESComputeGS() is typically used within composed nonlinear solver
1973c79ef259SPeter Brune    implementations, so most users would not generally call this routine
1974c79ef259SPeter Brune    themselves.
1975c79ef259SPeter Brune 
1976c79ef259SPeter Brune    Level: developer
1977c79ef259SPeter Brune 
1978c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function
1979c79ef259SPeter Brune 
1980c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction()
1981c79ef259SPeter Brune @*/
1982646217ecSPeter Brune PetscErrorCode  SNESComputeGS(SNES snes,Vec b,Vec x)
1983646217ecSPeter Brune {
1984646217ecSPeter Brune   PetscErrorCode ierr;
198589b92e6fSPeter Brune   PetscInt       i;
19866cab3a1bSJed Brown   DM             dm;
19876cab3a1bSJed Brown   SNESDM         sdm;
1988646217ecSPeter Brune 
1989646217ecSPeter Brune   PetscFunctionBegin;
1990646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1991646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
1992646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
1993646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
1994646217ecSPeter Brune   if (b) PetscCheckSameComm(snes,1,b,3);
19954ec14c9cSBarry Smith   if (b) VecValidValues(b,2,PETSC_TRUE);
1996701cf23dSPeter Brune   ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
19976cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
19986cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
19996cab3a1bSJed Brown   if (sdm->computegs) {
200089b92e6fSPeter Brune     for (i = 0; i < snes->gssweeps; i++) {
2001646217ecSPeter Brune       PetscStackPush("SNES user GS");
20026cab3a1bSJed Brown       ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
2003646217ecSPeter Brune       PetscStackPop;
200489b92e6fSPeter Brune     }
2005646217ecSPeter Brune   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve().");
2006701cf23dSPeter Brune   ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
20074ec14c9cSBarry Smith   VecValidValues(x,3,PETSC_FALSE);
2008646217ecSPeter Brune   PetscFunctionReturn(0);
2009646217ecSPeter Brune }
2010646217ecSPeter Brune 
2011646217ecSPeter Brune 
2012646217ecSPeter Brune #undef __FUNCT__
20134a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
201462fef451SLois Curfman McInnes /*@
201562fef451SLois Curfman McInnes    SNESComputeJacobian - Computes the Jacobian matrix that has been
201662fef451SLois Curfman McInnes    set with SNESSetJacobian().
201762fef451SLois Curfman McInnes 
2018c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
2019c7afd0dbSLois Curfman McInnes 
202062fef451SLois Curfman McInnes    Input Parameters:
2021c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2022c7afd0dbSLois Curfman McInnes -  x - input vector
202362fef451SLois Curfman McInnes 
202462fef451SLois Curfman McInnes    Output Parameters:
2025c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
202662fef451SLois Curfman McInnes .  B - optional preconditioning matrix
20272b668275SBarry Smith -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
2028fee21e36SBarry Smith 
2029e35cf81dSBarry Smith   Options Database Keys:
2030e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
2031693365a8SJed Brown .    -snes_lag_jacobian <lag>
2032693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
2033693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
2034693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
20354c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
2036c01495d3SJed Brown .    -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference
2037c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
2038c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
2039c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
2040c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
20414c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
2042c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
2043c01495d3SJed Brown 
2044e35cf81dSBarry Smith 
204562fef451SLois Curfman McInnes    Notes:
204662fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
204762fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
204862fef451SLois Curfman McInnes 
204994b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the
2050dc5a77f8SLois Curfman McInnes    flag parameter.
205162fef451SLois Curfman McInnes 
205236851e7fSLois Curfman McInnes    Level: developer
205336851e7fSLois Curfman McInnes 
205462fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
205562fef451SLois Curfman McInnes 
2056e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
205762fef451SLois Curfman McInnes @*/
20587087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
20599b94acceSBarry Smith {
2060dfbe8321SBarry Smith   PetscErrorCode ierr;
2061ace3abfcSBarry Smith   PetscBool      flag;
20626cab3a1bSJed Brown   DM             dm;
20636cab3a1bSJed Brown   SNESDM         sdm;
20643a40ed3dSBarry Smith 
20653a40ed3dSBarry Smith   PetscFunctionBegin;
20660700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
20670700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
20684482741eSBarry Smith   PetscValidPointer(flg,5);
2069c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
20704ec14c9cSBarry Smith   VecValidValues(X,2,PETSC_TRUE);
20716cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
20726cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
20733232da50SPeter Brune 
20746cab3a1bSJed Brown   if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
2075ebd3b9afSBarry Smith 
2076ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
2077ebd3b9afSBarry Smith 
2078fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
2079fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
2080fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
2081fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
2082e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
2083e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
2084251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
2085ebd3b9afSBarry Smith     if (flag) {
2086ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2087ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2088ebd3b9afSBarry Smith     }
2089e35cf81dSBarry Smith     PetscFunctionReturn(0);
2090e35cf81dSBarry Smith   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
2091e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
2092e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
2093251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
2094ebd3b9afSBarry Smith     if (flag) {
2095ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2096ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2097ebd3b9afSBarry Smith     }
2098e35cf81dSBarry Smith     PetscFunctionReturn(0);
2099e35cf81dSBarry Smith   }
2100e35cf81dSBarry Smith 
2101c4fc05e7SBarry Smith   *flg = DIFFERENT_NONZERO_PATTERN;
2102e35cf81dSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
21033232da50SPeter Brune 
2104d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
21053232da50SPeter Brune   if (snes->mf && !snes->mf_operator) {
21063232da50SPeter Brune     ierr = MatMFFDComputeJacobian(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr);
21073232da50SPeter Brune   } else {
21086cab3a1bSJed Brown     ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr);
21093232da50SPeter Brune   }
2110d64ed03dSBarry Smith   PetscStackPop;
21113232da50SPeter Brune 
2112d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
2113a8054027SBarry Smith 
21143b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
21153b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
21163b4f5425SBarry Smith     snes->lagpreconditioner = -1;
21173b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
2118a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
2119a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
2120a8054027SBarry Smith   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
2121a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
2122a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
2123a8054027SBarry Smith   }
2124a8054027SBarry Smith 
21256d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
21260700a824SBarry Smith   /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
21270700a824SBarry Smith     PetscValidHeaderSpecific(*B,MAT_CLASSID,4);   */
2128693365a8SJed Brown   {
2129693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
2130693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr);
2131693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
2132693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
2133693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr);
2134693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
2135693365a8SJed Brown       Mat Bexp_mine = PETSC_NULL,Bexp,FDexp;
2136693365a8SJed Brown       MatStructure mstruct;
2137693365a8SJed Brown       PetscViewer vdraw,vstdout;
21386b3a5b13SJed Brown       PetscBool flg;
2139693365a8SJed Brown       if (flag_operator) {
2140693365a8SJed Brown         ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr);
2141693365a8SJed Brown         Bexp = Bexp_mine;
2142693365a8SJed Brown       } else {
2143693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
2144251f4c67SDmitry Karpeev         ierr = PetscObjectTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
2145693365a8SJed Brown         if (flg) Bexp = *B;
2146693365a8SJed Brown         else {
2147693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
2148693365a8SJed Brown           ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr);
2149693365a8SJed Brown           Bexp = Bexp_mine;
2150693365a8SJed Brown         }
2151693365a8SJed Brown       }
2152693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
2153693365a8SJed Brown       ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr);
2154693365a8SJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
2155693365a8SJed Brown       if (flag_draw || flag_contour) {
2156693365a8SJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
2157693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
2158693365a8SJed Brown       } else vdraw = PETSC_NULL;
2159693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr);
2160693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
2161693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
2162693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
2163693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2164693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
2165693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2166693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
2167693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2168693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
2169693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
2170693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
2171693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
2172693365a8SJed Brown       }
2173693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
2174693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
2175693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
2176693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
2177693365a8SJed Brown     }
2178693365a8SJed Brown   }
21794c30e9fbSJed Brown   {
21806719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
21816719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
21824c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr);
21836719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr);
21844c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
21854c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
21866719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr);
21876719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr);
21886719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr);
21896719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
21904c30e9fbSJed Brown       Mat            Bfd;
21914c30e9fbSJed Brown       MatStructure   mstruct;
21924c30e9fbSJed Brown       PetscViewer    vdraw,vstdout;
21934c30e9fbSJed Brown       ISColoring     iscoloring;
21944c30e9fbSJed Brown       MatFDColoring  matfdcoloring;
21954c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
21964c30e9fbSJed Brown       void           *funcctx;
21976719d8e4SJed Brown       PetscReal      norm1,norm2,normmax;
21984c30e9fbSJed Brown 
21994c30e9fbSJed Brown       ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
22004c30e9fbSJed Brown       ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
22014c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
22024c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
22034c30e9fbSJed Brown 
22044c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
22054c30e9fbSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr);
22064c30e9fbSJed Brown         ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr);
22074c30e9fbSJed Brown         ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
22084c30e9fbSJed Brown         ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
22094c30e9fbSJed Brown         ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
22104c30e9fbSJed Brown         ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr);
22114c30e9fbSJed Brown         ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
22124c30e9fbSJed Brown 
22134c30e9fbSJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
22144c30e9fbSJed Brown       if (flag_draw || flag_contour) {
22154c30e9fbSJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
22164c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
22174c30e9fbSJed Brown       } else vdraw = PETSC_NULL;
22184c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
22196719d8e4SJed Brown       if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);}
22204c30e9fbSJed Brown       if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);}
22214c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
22226719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
22234c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
22244c30e9fbSJed Brown       ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
22254c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
22266719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
22274c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
22286719d8e4SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr);
22296719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
22304c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
22314c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
22324c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
22334c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
22344c30e9fbSJed Brown       }
22354c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
22366719d8e4SJed Brown 
22376719d8e4SJed Brown       if (flag_threshold) {
22386719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
22396719d8e4SJed Brown         ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr);
22406719d8e4SJed Brown         ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr);
22416719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
22426719d8e4SJed Brown           const PetscScalar *ba,*ca;
22436719d8e4SJed Brown           const PetscInt    *bj,*cj;
22446719d8e4SJed Brown           PetscInt          bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
22456719d8e4SJed Brown           PetscReal         maxentry = 0,maxdiff = 0,maxrdiff = 0;
22466719d8e4SJed Brown           ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
22476719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
22486719d8e4SJed Brown           if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
22496719d8e4SJed Brown           for (j=0; j<bn; j++) {
22506719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
22516719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
22526719d8e4SJed Brown               maxentrycol = bj[j];
22536719d8e4SJed Brown               maxentry = PetscRealPart(ba[j]);
22546719d8e4SJed Brown             }
22556719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
22566719d8e4SJed Brown               maxdiffcol = bj[j];
22576719d8e4SJed Brown               maxdiff = PetscRealPart(ca[j]);
22586719d8e4SJed Brown             }
22596719d8e4SJed Brown             if (rdiff > maxrdiff) {
22606719d8e4SJed Brown               maxrdiffcol = bj[j];
22616719d8e4SJed Brown               maxrdiff = rdiff;
22626719d8e4SJed Brown             }
22636719d8e4SJed Brown           }
22646719d8e4SJed Brown           if (maxrdiff > 1) {
22656719d8e4SJed 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);
22666719d8e4SJed Brown             for (j=0; j<bn; j++) {
22676719d8e4SJed Brown               PetscReal rdiff;
22686719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
22696719d8e4SJed Brown               if (rdiff > 1) {
22706719d8e4SJed Brown                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr);
22716719d8e4SJed Brown               }
22726719d8e4SJed Brown             }
22736719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
22746719d8e4SJed Brown           }
22756719d8e4SJed Brown           ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
22766719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
22776719d8e4SJed Brown         }
22786719d8e4SJed Brown       }
22794c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
22804c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
22814c30e9fbSJed Brown     }
22824c30e9fbSJed Brown   }
22833a40ed3dSBarry Smith   PetscFunctionReturn(0);
22849b94acceSBarry Smith }
22859b94acceSBarry Smith 
22864a2ae208SSatish Balay #undef __FUNCT__
22874a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
22889b94acceSBarry Smith /*@C
22899b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2290044dda88SLois Curfman McInnes    location to store the matrix.
22919b94acceSBarry Smith 
22923f9fe445SBarry Smith    Logically Collective on SNES and Mat
2293c7afd0dbSLois Curfman McInnes 
22949b94acceSBarry Smith    Input Parameters:
2295c7afd0dbSLois Curfman McInnes +  snes - the SNES context
22969b94acceSBarry Smith .  A - Jacobian matrix
22979b94acceSBarry Smith .  B - preconditioner matrix (usually same as the Jacobian)
2298efd51863SBarry Smith .  func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value)
2299c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
2300efd51863SBarry Smith          Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value)
23019b94acceSBarry Smith 
23029b94acceSBarry Smith    Calling sequence of func:
23038d76a1e5SLois Curfman McInnes $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
23049b94acceSBarry Smith 
2305c7afd0dbSLois Curfman McInnes +  x - input vector
23069b94acceSBarry Smith .  A - Jacobian matrix
23079b94acceSBarry Smith .  B - preconditioner matrix, usually the same as A
2308ac21db08SLois Curfman McInnes .  flag - flag indicating information about the preconditioner matrix
23092b668275SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
2310c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined Jacobian context
23119b94acceSBarry Smith 
23129b94acceSBarry Smith    Notes:
231394b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the flag
23142cd2dfdcSLois Curfman McInnes    output parameter in the routine func().  Be sure to read this information!
2315ac21db08SLois Curfman McInnes 
2316ac21db08SLois Curfman McInnes    The routine func() takes Mat * as the matrix arguments rather than Mat.
23179b94acceSBarry Smith    This allows the Jacobian evaluation routine to replace A and/or B with a
23189b94acceSBarry Smith    completely new new matrix structure (not just different matrix elements)
23199b94acceSBarry Smith    when appropriate, for instance, if the nonzero structure is changing
23209b94acceSBarry Smith    throughout the global iterations.
23219b94acceSBarry Smith 
232216913363SBarry Smith    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
232316913363SBarry Smith    each matrix.
232416913363SBarry Smith 
2325a8a26c1eSJed Brown    If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument
2326a8a26c1eSJed Brown    must be a MatFDColoring.
2327a8a26c1eSJed Brown 
2328c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2329c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2330c3cc8fd1SJed Brown 
233136851e7fSLois Curfman McInnes    Level: beginner
233236851e7fSLois Curfman McInnes 
23339b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
23349b94acceSBarry Smith 
23353ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
23369b94acceSBarry Smith @*/
23377087cfbeSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
23389b94acceSBarry Smith {
2339dfbe8321SBarry Smith   PetscErrorCode ierr;
23406cab3a1bSJed Brown   DM             dm;
23413a7fca6bSBarry Smith 
23423a40ed3dSBarry Smith   PetscFunctionBegin;
23430700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
23440700a824SBarry Smith   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
23450700a824SBarry Smith   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
2346c9780b6fSBarry Smith   if (A) PetscCheckSameComm(snes,1,A,2);
234706975374SJed Brown   if (B) PetscCheckSameComm(snes,1,B,3);
23486cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
23496cab3a1bSJed Brown   ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr);
23503a7fca6bSBarry Smith   if (A) {
23517dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
23526bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
23539b94acceSBarry Smith     snes->jacobian = A;
23543a7fca6bSBarry Smith   }
23553a7fca6bSBarry Smith   if (B) {
23567dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
23576bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
23589b94acceSBarry Smith     snes->jacobian_pre = B;
23593a7fca6bSBarry Smith   }
23603a40ed3dSBarry Smith   PetscFunctionReturn(0);
23619b94acceSBarry Smith }
236262fef451SLois Curfman McInnes 
23634a2ae208SSatish Balay #undef __FUNCT__
23644a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
2365c2aafc4cSSatish Balay /*@C
2366b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2367b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2368b4fd4287SBarry Smith 
2369c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2370c7afd0dbSLois Curfman McInnes 
2371b4fd4287SBarry Smith    Input Parameter:
2372b4fd4287SBarry Smith .  snes - the nonlinear solver context
2373b4fd4287SBarry Smith 
2374b4fd4287SBarry Smith    Output Parameters:
2375c7afd0dbSLois Curfman McInnes +  A - location to stash Jacobian matrix (or PETSC_NULL)
2376b4fd4287SBarry Smith .  B - location to stash preconditioner matrix (or PETSC_NULL)
237770e92668SMatthew Knepley .  func - location to put Jacobian function (or PETSC_NULL)
237870e92668SMatthew Knepley -  ctx - location to stash Jacobian ctx (or PETSC_NULL)
2379fee21e36SBarry Smith 
238036851e7fSLois Curfman McInnes    Level: advanced
238136851e7fSLois Curfman McInnes 
2382b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian()
2383b4fd4287SBarry Smith @*/
23847087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
2385b4fd4287SBarry Smith {
23866cab3a1bSJed Brown   PetscErrorCode ierr;
23876cab3a1bSJed Brown   DM             dm;
23886cab3a1bSJed Brown   SNESDM         sdm;
23896cab3a1bSJed Brown 
23903a40ed3dSBarry Smith   PetscFunctionBegin;
23910700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2392b4fd4287SBarry Smith   if (A)    *A    = snes->jacobian;
2393b4fd4287SBarry Smith   if (B)    *B    = snes->jacobian_pre;
23946cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
23956cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
23966cab3a1bSJed Brown   if (func) *func = sdm->computejacobian;
23976cab3a1bSJed Brown   if (ctx)  *ctx  = sdm->jacobianctx;
23983a40ed3dSBarry Smith   PetscFunctionReturn(0);
2399b4fd4287SBarry Smith }
2400b4fd4287SBarry Smith 
24019b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
24029b94acceSBarry Smith 
24034a2ae208SSatish Balay #undef __FUNCT__
24044a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
24059b94acceSBarry Smith /*@
24069b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
2407272ac6f2SLois Curfman McInnes    of a nonlinear solver.
24089b94acceSBarry Smith 
2409fee21e36SBarry Smith    Collective on SNES
2410fee21e36SBarry Smith 
2411c7afd0dbSLois Curfman McInnes    Input Parameters:
241270e92668SMatthew Knepley .  snes - the SNES context
2413c7afd0dbSLois Curfman McInnes 
2414272ac6f2SLois Curfman McInnes    Notes:
2415272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
2416272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
2417272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
2418272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
2419272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
2420272ac6f2SLois Curfman McInnes 
242136851e7fSLois Curfman McInnes    Level: advanced
242236851e7fSLois Curfman McInnes 
24239b94acceSBarry Smith .keywords: SNES, nonlinear, setup
24249b94acceSBarry Smith 
24259b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
24269b94acceSBarry Smith @*/
24277087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
24289b94acceSBarry Smith {
2429dfbe8321SBarry Smith   PetscErrorCode              ierr;
24306cab3a1bSJed Brown   DM                          dm;
24316cab3a1bSJed Brown   SNESDM                      sdm;
2432c35f09e5SBarry Smith   SNESLineSearch              linesearch, pclinesearch;
24336e2a1849SPeter Brune   void                        *lsprectx,*lspostctx;
24346e2a1849SPeter Brune   SNESLineSearchPreCheckFunc  lsprefunc;
24356e2a1849SPeter Brune   SNESLineSearchPostCheckFunc lspostfunc;
24366e2a1849SPeter Brune   PetscErrorCode              (*func)(SNES,Vec,Vec,void*);
24376e2a1849SPeter Brune   Vec                         f,fpc;
24386e2a1849SPeter Brune   void                        *funcctx;
24396e2a1849SPeter Brune   PetscErrorCode              (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*);
24401eb13d49SPeter Brune   void                        *jacctx,*appctx;
24416e2a1849SPeter Brune   Mat                         A,B;
24423a40ed3dSBarry Smith 
24433a40ed3dSBarry Smith   PetscFunctionBegin;
24440700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
24454dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
24469b94acceSBarry Smith 
24477adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
244885385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
244985385478SLisandro Dalcin   }
245085385478SLisandro Dalcin 
2451a63bb30eSJed Brown   ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
245217186662SBarry Smith   if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
245358c9b817SLisandro Dalcin   if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
245458c9b817SLisandro Dalcin 
245558c9b817SLisandro Dalcin   if (!snes->vec_sol_update /* && snes->vec_sol */) {
245658c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
245758c9b817SLisandro Dalcin     ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr);
245858c9b817SLisandro Dalcin   }
245958c9b817SLisandro Dalcin 
24606cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2461d8f46077SPeter Brune   ierr = DMShellSetGlobalVector(snes->dm,snes->vec_sol);CHKERRQ(ierr);
24626cab3a1bSJed Brown   ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */
24636cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
24646cab3a1bSJed Brown   if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc");
24656cab3a1bSJed Brown   if (!snes->vec_func) {
24666cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2467214df951SJed Brown   }
2468efd51863SBarry Smith 
2469b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
2470b710008aSBarry Smith 
2471f1c6b773SPeter Brune   if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);}
24729e764e56SPeter Brune 
2473c40d0f55SPeter Brune   if (snes->pc && (snes->pcside == PC_LEFT)) snes->mf = PETSC_TRUE;
2474d8f46077SPeter Brune 
2475d8f46077SPeter Brune   if (snes->mf) { ierr = SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version);CHKERRQ(ierr); }
2476d8f46077SPeter Brune 
2477d8f46077SPeter Brune 
2478d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
2479d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
2480d25893d9SBarry Smith   }
2481d25893d9SBarry Smith 
24826e2a1849SPeter Brune   if (snes->pc) {
24836e2a1849SPeter Brune     /* copy the DM over */
24846e2a1849SPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
24856e2a1849SPeter Brune     ierr = SNESSetDM(snes->pc,dm);CHKERRQ(ierr);
24866e2a1849SPeter Brune 
24876e2a1849SPeter Brune     /* copy the legacy SNES context not related to the DM over*/
24886e2a1849SPeter Brune     ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr);
24896e2a1849SPeter Brune     ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr);
24906e2a1849SPeter Brune     ierr = SNESSetFunction(snes->pc,fpc,func,funcctx);CHKERRQ(ierr);
24916e2a1849SPeter Brune     ierr = SNESGetJacobian(snes,&A,&B,&jac,&jacctx);CHKERRQ(ierr);
24926e2a1849SPeter Brune     ierr = SNESSetJacobian(snes->pc,A,B,jac,jacctx);CHKERRQ(ierr);
24931eb13d49SPeter Brune     ierr = SNESGetApplicationContext(snes,&appctx);CHKERRQ(ierr);
24941eb13d49SPeter Brune     ierr = SNESSetApplicationContext(snes->pc,appctx);CHKERRQ(ierr);
24956e2a1849SPeter Brune     ierr = VecDestroy(&fpc);CHKERRQ(ierr);
24966e2a1849SPeter Brune 
24976e2a1849SPeter Brune     /* copy the function pointers over */
24986e2a1849SPeter Brune     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr);
24996e2a1849SPeter Brune 
25006e2a1849SPeter Brune      /* default to 1 iteration */
2501140836e4SPeter Brune     ierr = SNESSetTolerances(snes->pc, 0.0, 0.0, 0.0, 1, snes->pc->max_funcs);CHKERRQ(ierr);
25026e2a1849SPeter Brune     ierr = SNESSetNormType(snes->pc, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr);
25036e2a1849SPeter Brune     ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr);
25046e2a1849SPeter Brune 
25056e2a1849SPeter Brune     /* copy the line search context over */
25066e2a1849SPeter Brune     ierr = SNESGetSNESLineSearch(snes,&linesearch);CHKERRQ(ierr);
25076e2a1849SPeter Brune     ierr = SNESGetSNESLineSearch(snes->pc,&pclinesearch);CHKERRQ(ierr);
25086e2a1849SPeter Brune     ierr = SNESLineSearchGetPreCheck(linesearch,&lsprefunc,&lsprectx);CHKERRQ(ierr);
25096e2a1849SPeter Brune     ierr = SNESLineSearchGetPostCheck(linesearch,&lspostfunc,&lspostctx);CHKERRQ(ierr);
25106e2a1849SPeter Brune     ierr = SNESLineSearchSetPreCheck(pclinesearch,lsprefunc,lsprectx);CHKERRQ(ierr);
25116e2a1849SPeter Brune     ierr = SNESLineSearchSetPostCheck(pclinesearch,lspostfunc,lspostctx);CHKERRQ(ierr);
25126e2a1849SPeter Brune     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr);
25136e2a1849SPeter Brune   }
25146e2a1849SPeter Brune 
2515410397dcSLisandro Dalcin   if (snes->ops->setup) {
2516410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2517410397dcSLisandro Dalcin   }
251858c9b817SLisandro Dalcin 
25197aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
25203a40ed3dSBarry Smith   PetscFunctionReturn(0);
25219b94acceSBarry Smith }
25229b94acceSBarry Smith 
25234a2ae208SSatish Balay #undef __FUNCT__
252437596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
252537596af1SLisandro Dalcin /*@
252637596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
252737596af1SLisandro Dalcin 
252837596af1SLisandro Dalcin    Collective on SNES
252937596af1SLisandro Dalcin 
253037596af1SLisandro Dalcin    Input Parameter:
253137596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
253237596af1SLisandro Dalcin 
2533d25893d9SBarry Smith    Level: intermediate
2534d25893d9SBarry Smith 
2535d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
253637596af1SLisandro Dalcin 
253737596af1SLisandro Dalcin .keywords: SNES, destroy
253837596af1SLisandro Dalcin 
253937596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
254037596af1SLisandro Dalcin @*/
254137596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
254237596af1SLisandro Dalcin {
254337596af1SLisandro Dalcin   PetscErrorCode ierr;
254437596af1SLisandro Dalcin 
254537596af1SLisandro Dalcin   PetscFunctionBegin;
254637596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2547d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
2548d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
2549d25893d9SBarry Smith     snes->user = PETSC_NULL;
2550d25893d9SBarry Smith   }
25518a23116dSBarry Smith   if (snes->pc) {
25528a23116dSBarry Smith     ierr = SNESReset(snes->pc);CHKERRQ(ierr);
25538a23116dSBarry Smith   }
25548a23116dSBarry Smith 
255537596af1SLisandro Dalcin   if (snes->ops->reset) {
255637596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
255737596af1SLisandro Dalcin   }
25589e764e56SPeter Brune   if (snes->ksp) {
25599e764e56SPeter Brune     ierr = KSPReset(snes->ksp);CHKERRQ(ierr);
25609e764e56SPeter Brune   }
25619e764e56SPeter Brune 
25629e764e56SPeter Brune   if (snes->linesearch) {
2563f1c6b773SPeter Brune     ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr);
25649e764e56SPeter Brune   }
25659e764e56SPeter Brune 
25666bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
25676bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
25686bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
25696bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
25706bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
25716bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2572c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
2573c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
257437596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
257537596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
257637596af1SLisandro Dalcin   PetscFunctionReturn(0);
257737596af1SLisandro Dalcin }
257837596af1SLisandro Dalcin 
257937596af1SLisandro Dalcin #undef __FUNCT__
25804a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
258152baeb72SSatish Balay /*@
25829b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
25839b94acceSBarry Smith    with SNESCreate().
25849b94acceSBarry Smith 
2585c7afd0dbSLois Curfman McInnes    Collective on SNES
2586c7afd0dbSLois Curfman McInnes 
25879b94acceSBarry Smith    Input Parameter:
25889b94acceSBarry Smith .  snes - the SNES context
25899b94acceSBarry Smith 
259036851e7fSLois Curfman McInnes    Level: beginner
259136851e7fSLois Curfman McInnes 
25929b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
25939b94acceSBarry Smith 
259463a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
25959b94acceSBarry Smith @*/
25966bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
25979b94acceSBarry Smith {
25986849ba73SBarry Smith   PetscErrorCode ierr;
25993a40ed3dSBarry Smith 
26003a40ed3dSBarry Smith   PetscFunctionBegin;
26016bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
26026bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
26036bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2604d4bb536fSBarry Smith 
26056bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
26068a23116dSBarry Smith   ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr);
26076b8b9a38SLisandro Dalcin 
2608be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
26096bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
26106bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
26116d4c513bSLisandro Dalcin 
26126bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
26136bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
2614f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr);
26156b8b9a38SLisandro Dalcin 
26166bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
26176bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
26186bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
26196b8b9a38SLisandro Dalcin   }
26206bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
26216bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
26226bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
262358c9b817SLisandro Dalcin   }
26246bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2625a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
26263a40ed3dSBarry Smith  PetscFunctionReturn(0);
26279b94acceSBarry Smith }
26289b94acceSBarry Smith 
26299b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
26309b94acceSBarry Smith 
26314a2ae208SSatish Balay #undef __FUNCT__
2632a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
2633a8054027SBarry Smith /*@
2634a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2635a8054027SBarry Smith 
26363f9fe445SBarry Smith    Logically Collective on SNES
2637a8054027SBarry Smith 
2638a8054027SBarry Smith    Input Parameters:
2639a8054027SBarry Smith +  snes - the SNES context
2640a8054027SBarry 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
26413b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2642a8054027SBarry Smith 
2643a8054027SBarry Smith    Options Database Keys:
2644a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2645a8054027SBarry Smith 
2646a8054027SBarry Smith    Notes:
2647a8054027SBarry Smith    The default is 1
2648a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2649a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2650a8054027SBarry Smith 
2651a8054027SBarry Smith    Level: intermediate
2652a8054027SBarry Smith 
2653a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2654a8054027SBarry Smith 
2655e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2656a8054027SBarry Smith 
2657a8054027SBarry Smith @*/
26587087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2659a8054027SBarry Smith {
2660a8054027SBarry Smith   PetscFunctionBegin;
26610700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2662e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2663e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2664c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2665a8054027SBarry Smith   snes->lagpreconditioner = lag;
2666a8054027SBarry Smith   PetscFunctionReturn(0);
2667a8054027SBarry Smith }
2668a8054027SBarry Smith 
2669a8054027SBarry Smith #undef __FUNCT__
2670efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
2671efd51863SBarry Smith /*@
2672efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2673efd51863SBarry Smith 
2674efd51863SBarry Smith    Logically Collective on SNES
2675efd51863SBarry Smith 
2676efd51863SBarry Smith    Input Parameters:
2677efd51863SBarry Smith +  snes - the SNES context
2678efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
2679efd51863SBarry Smith 
2680efd51863SBarry Smith    Options Database Keys:
2681efd51863SBarry Smith .    -snes_grid_sequence <steps>
2682efd51863SBarry Smith 
2683efd51863SBarry Smith    Level: intermediate
2684efd51863SBarry Smith 
2685c0df2a02SJed Brown    Notes:
2686c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2687c0df2a02SJed Brown 
2688efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2689efd51863SBarry Smith 
2690efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2691efd51863SBarry Smith 
2692efd51863SBarry Smith @*/
2693efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2694efd51863SBarry Smith {
2695efd51863SBarry Smith   PetscFunctionBegin;
2696efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2697efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
2698efd51863SBarry Smith   snes->gridsequence = steps;
2699efd51863SBarry Smith   PetscFunctionReturn(0);
2700efd51863SBarry Smith }
2701efd51863SBarry Smith 
2702efd51863SBarry Smith #undef __FUNCT__
2703a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
2704a8054027SBarry Smith /*@
2705a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
2706a8054027SBarry Smith 
27073f9fe445SBarry Smith    Not Collective
2708a8054027SBarry Smith 
2709a8054027SBarry Smith    Input Parameter:
2710a8054027SBarry Smith .  snes - the SNES context
2711a8054027SBarry Smith 
2712a8054027SBarry Smith    Output Parameter:
2713a8054027SBarry 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
27143b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2715a8054027SBarry Smith 
2716a8054027SBarry Smith    Options Database Keys:
2717a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2718a8054027SBarry Smith 
2719a8054027SBarry Smith    Notes:
2720a8054027SBarry Smith    The default is 1
2721a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2722a8054027SBarry Smith 
2723a8054027SBarry Smith    Level: intermediate
2724a8054027SBarry Smith 
2725a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2726a8054027SBarry Smith 
2727a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
2728a8054027SBarry Smith 
2729a8054027SBarry Smith @*/
27307087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
2731a8054027SBarry Smith {
2732a8054027SBarry Smith   PetscFunctionBegin;
27330700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2734a8054027SBarry Smith   *lag = snes->lagpreconditioner;
2735a8054027SBarry Smith   PetscFunctionReturn(0);
2736a8054027SBarry Smith }
2737a8054027SBarry Smith 
2738a8054027SBarry Smith #undef __FUNCT__
2739e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
2740e35cf81dSBarry Smith /*@
2741e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
2742e35cf81dSBarry Smith      often the preconditioner is rebuilt.
2743e35cf81dSBarry Smith 
27443f9fe445SBarry Smith    Logically Collective on SNES
2745e35cf81dSBarry Smith 
2746e35cf81dSBarry Smith    Input Parameters:
2747e35cf81dSBarry Smith +  snes - the SNES context
2748e35cf81dSBarry 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
2749fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
2750e35cf81dSBarry Smith 
2751e35cf81dSBarry Smith    Options Database Keys:
2752e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2753e35cf81dSBarry Smith 
2754e35cf81dSBarry Smith    Notes:
2755e35cf81dSBarry Smith    The default is 1
2756e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2757fe3ffe1eSBarry 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
2758fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
2759e35cf81dSBarry Smith 
2760e35cf81dSBarry Smith    Level: intermediate
2761e35cf81dSBarry Smith 
2762e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2763e35cf81dSBarry Smith 
2764e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
2765e35cf81dSBarry Smith 
2766e35cf81dSBarry Smith @*/
27677087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
2768e35cf81dSBarry Smith {
2769e35cf81dSBarry Smith   PetscFunctionBegin;
27700700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2771e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2772e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2773c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2774e35cf81dSBarry Smith   snes->lagjacobian = lag;
2775e35cf81dSBarry Smith   PetscFunctionReturn(0);
2776e35cf81dSBarry Smith }
2777e35cf81dSBarry Smith 
2778e35cf81dSBarry Smith #undef __FUNCT__
2779e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
2780e35cf81dSBarry Smith /*@
2781e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
2782e35cf81dSBarry Smith 
27833f9fe445SBarry Smith    Not Collective
2784e35cf81dSBarry Smith 
2785e35cf81dSBarry Smith    Input Parameter:
2786e35cf81dSBarry Smith .  snes - the SNES context
2787e35cf81dSBarry Smith 
2788e35cf81dSBarry Smith    Output Parameter:
2789e35cf81dSBarry 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
2790e35cf81dSBarry Smith          the Jacobian is built etc.
2791e35cf81dSBarry Smith 
2792e35cf81dSBarry Smith    Options Database Keys:
2793e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2794e35cf81dSBarry Smith 
2795e35cf81dSBarry Smith    Notes:
2796e35cf81dSBarry Smith    The default is 1
2797e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2798e35cf81dSBarry Smith 
2799e35cf81dSBarry Smith    Level: intermediate
2800e35cf81dSBarry Smith 
2801e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2802e35cf81dSBarry Smith 
2803e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
2804e35cf81dSBarry Smith 
2805e35cf81dSBarry Smith @*/
28067087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
2807e35cf81dSBarry Smith {
2808e35cf81dSBarry Smith   PetscFunctionBegin;
28090700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2810e35cf81dSBarry Smith   *lag = snes->lagjacobian;
2811e35cf81dSBarry Smith   PetscFunctionReturn(0);
2812e35cf81dSBarry Smith }
2813e35cf81dSBarry Smith 
2814e35cf81dSBarry Smith #undef __FUNCT__
28154a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
28169b94acceSBarry Smith /*@
2817d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
28189b94acceSBarry Smith 
28193f9fe445SBarry Smith    Logically Collective on SNES
2820c7afd0dbSLois Curfman McInnes 
28219b94acceSBarry Smith    Input Parameters:
2822c7afd0dbSLois Curfman McInnes +  snes - the SNES context
282370441072SBarry Smith .  abstol - absolute convergence tolerance
282433174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
282533174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
282633174efeSLois Curfman McInnes            of the change in the solution between steps
282733174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2828c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2829fee21e36SBarry Smith 
283033174efeSLois Curfman McInnes    Options Database Keys:
283170441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
2832c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
2833c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
2834c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
2835c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
28369b94acceSBarry Smith 
2837d7a720efSLois Curfman McInnes    Notes:
28389b94acceSBarry Smith    The default maximum number of iterations is 50.
28399b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
28409b94acceSBarry Smith 
284136851e7fSLois Curfman McInnes    Level: intermediate
284236851e7fSLois Curfman McInnes 
284333174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
28449b94acceSBarry Smith 
28452492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
28469b94acceSBarry Smith @*/
28477087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
28489b94acceSBarry Smith {
28493a40ed3dSBarry Smith   PetscFunctionBegin;
28500700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2851c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
2852c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
2853c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
2854c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
2855c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
2856c5eb9154SBarry Smith 
2857ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
2858ab54825eSJed Brown     if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol);
2859ab54825eSJed Brown     snes->abstol = abstol;
2860ab54825eSJed Brown   }
2861ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
2862ab54825eSJed 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);
2863ab54825eSJed Brown     snes->rtol = rtol;
2864ab54825eSJed Brown   }
2865ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
2866ab54825eSJed Brown     if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol);
2867c60f73f4SPeter Brune     snes->stol = stol;
2868ab54825eSJed Brown   }
2869ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
2870ab54825eSJed Brown     if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
2871ab54825eSJed Brown     snes->max_its = maxit;
2872ab54825eSJed Brown   }
2873ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
2874ab54825eSJed Brown     if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
2875ab54825eSJed Brown     snes->max_funcs = maxf;
2876ab54825eSJed Brown   }
287788976e71SPeter Brune   snes->tolerancesset = PETSC_TRUE;
28783a40ed3dSBarry Smith   PetscFunctionReturn(0);
28799b94acceSBarry Smith }
28809b94acceSBarry Smith 
28814a2ae208SSatish Balay #undef __FUNCT__
28824a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
28839b94acceSBarry Smith /*@
288433174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
288533174efeSLois Curfman McInnes 
2886c7afd0dbSLois Curfman McInnes    Not Collective
2887c7afd0dbSLois Curfman McInnes 
288833174efeSLois Curfman McInnes    Input Parameters:
2889c7afd0dbSLois Curfman McInnes +  snes - the SNES context
289085385478SLisandro Dalcin .  atol - absolute convergence tolerance
289133174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
289233174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
289333174efeSLois Curfman McInnes            of the change in the solution between steps
289433174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2895c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2896fee21e36SBarry Smith 
289733174efeSLois Curfman McInnes    Notes:
289833174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
289933174efeSLois Curfman McInnes 
290036851e7fSLois Curfman McInnes    Level: intermediate
290136851e7fSLois Curfman McInnes 
290233174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
290333174efeSLois Curfman McInnes 
290433174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
290533174efeSLois Curfman McInnes @*/
29067087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
290733174efeSLois Curfman McInnes {
29083a40ed3dSBarry Smith   PetscFunctionBegin;
29090700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
291085385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
291133174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
2912c60f73f4SPeter Brune   if (stol)  *stol  = snes->stol;
291333174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
291433174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
29153a40ed3dSBarry Smith   PetscFunctionReturn(0);
291633174efeSLois Curfman McInnes }
291733174efeSLois Curfman McInnes 
29184a2ae208SSatish Balay #undef __FUNCT__
29194a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
292033174efeSLois Curfman McInnes /*@
29219b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
29229b94acceSBarry Smith 
29233f9fe445SBarry Smith    Logically Collective on SNES
2924fee21e36SBarry Smith 
2925c7afd0dbSLois Curfman McInnes    Input Parameters:
2926c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2927c7afd0dbSLois Curfman McInnes -  tol - tolerance
2928c7afd0dbSLois Curfman McInnes 
29299b94acceSBarry Smith    Options Database Key:
2930c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
29319b94acceSBarry Smith 
293236851e7fSLois Curfman McInnes    Level: intermediate
293336851e7fSLois Curfman McInnes 
29349b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
29359b94acceSBarry Smith 
29362492ecdbSBarry Smith .seealso: SNESSetTolerances()
29379b94acceSBarry Smith @*/
29387087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
29399b94acceSBarry Smith {
29403a40ed3dSBarry Smith   PetscFunctionBegin;
29410700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2942c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
29439b94acceSBarry Smith   snes->deltatol = tol;
29443a40ed3dSBarry Smith   PetscFunctionReturn(0);
29459b94acceSBarry Smith }
29469b94acceSBarry Smith 
2947df9fa365SBarry Smith /*
2948df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
2949df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
2950df9fa365SBarry Smith    macros instead of functions
2951df9fa365SBarry Smith */
29524a2ae208SSatish Balay #undef __FUNCT__
29534619e776SBarry Smith #define __FUNCT__ "SNESMonitorLGResidualNorm"
29544619e776SBarry Smith PetscErrorCode  SNESMonitorLGResidualNorm(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2955ce1608b8SBarry Smith {
2956dfbe8321SBarry Smith   PetscErrorCode ierr;
2957ce1608b8SBarry Smith 
2958ce1608b8SBarry Smith   PetscFunctionBegin;
29590700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2960a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
2961ce1608b8SBarry Smith   PetscFunctionReturn(0);
2962ce1608b8SBarry Smith }
2963ce1608b8SBarry Smith 
29644a2ae208SSatish Balay #undef __FUNCT__
2965a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
29667087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2967df9fa365SBarry Smith {
2968dfbe8321SBarry Smith   PetscErrorCode ierr;
2969df9fa365SBarry Smith 
2970df9fa365SBarry Smith   PetscFunctionBegin;
2971a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2972df9fa365SBarry Smith   PetscFunctionReturn(0);
2973df9fa365SBarry Smith }
2974df9fa365SBarry Smith 
29754a2ae208SSatish Balay #undef __FUNCT__
2976a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
29776bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
2978df9fa365SBarry Smith {
2979dfbe8321SBarry Smith   PetscErrorCode ierr;
2980df9fa365SBarry Smith 
2981df9fa365SBarry Smith   PetscFunctionBegin;
2982a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2983df9fa365SBarry Smith   PetscFunctionReturn(0);
2984df9fa365SBarry Smith }
2985df9fa365SBarry Smith 
29867087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
2987b271bb04SBarry Smith #undef __FUNCT__
2988b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
29897087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2990b271bb04SBarry Smith {
2991b271bb04SBarry Smith   PetscDrawLG      lg;
2992b271bb04SBarry Smith   PetscErrorCode   ierr;
2993b271bb04SBarry Smith   PetscReal        x,y,per;
2994b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
2995b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
2996b271bb04SBarry Smith   PetscDraw        draw;
2997b271bb04SBarry Smith 
2998*459f5d12SBarry Smith   PetscFunctionBegin;
2999b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
3000b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3001b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3002b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
3003b271bb04SBarry Smith   x = (PetscReal) n;
3004b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
3005b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
3006b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
3007b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
3008b271bb04SBarry Smith   }
3009b271bb04SBarry Smith 
3010b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
3011b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3012b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3013b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
3014b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
3015b271bb04SBarry Smith   x = (PetscReal) n;
3016b271bb04SBarry Smith   y = 100.0*per;
3017b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
3018b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
3019b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
3020b271bb04SBarry Smith   }
3021b271bb04SBarry Smith 
3022b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
3023b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3024b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3025b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
3026b271bb04SBarry Smith   x = (PetscReal) n;
3027b271bb04SBarry Smith   y = (prev - rnorm)/prev;
3028b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
3029b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
3030b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
3031b271bb04SBarry Smith   }
3032b271bb04SBarry Smith 
3033b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
3034b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3035b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3036b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
3037b271bb04SBarry Smith   x = (PetscReal) n;
3038b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
3039b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
3040b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
3041b271bb04SBarry Smith   }
3042b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
3043b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
3044b271bb04SBarry Smith   }
3045b271bb04SBarry Smith   prev = rnorm;
3046b271bb04SBarry Smith   PetscFunctionReturn(0);
3047b271bb04SBarry Smith }
3048b271bb04SBarry Smith 
3049b271bb04SBarry Smith #undef __FUNCT__
30507a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
3051228d79bcSJed Brown /*@
3052228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
3053228d79bcSJed Brown 
3054228d79bcSJed Brown    Collective on SNES
3055228d79bcSJed Brown 
3056228d79bcSJed Brown    Input Parameters:
3057228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
3058228d79bcSJed Brown .  iter - iteration number
3059228d79bcSJed Brown -  rnorm - relative norm of the residual
3060228d79bcSJed Brown 
3061228d79bcSJed Brown    Notes:
3062228d79bcSJed Brown    This routine is called by the SNES implementations.
3063228d79bcSJed Brown    It does not typically need to be called by the user.
3064228d79bcSJed Brown 
3065228d79bcSJed Brown    Level: developer
3066228d79bcSJed Brown 
3067228d79bcSJed Brown .seealso: SNESMonitorSet()
3068228d79bcSJed Brown @*/
30697a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
30707a03ce2fSLisandro Dalcin {
30717a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
30727a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
30737a03ce2fSLisandro Dalcin 
30747a03ce2fSLisandro Dalcin   PetscFunctionBegin;
30757a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
30767a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
30777a03ce2fSLisandro Dalcin   }
30787a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
30797a03ce2fSLisandro Dalcin }
30807a03ce2fSLisandro Dalcin 
30819b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
30829b94acceSBarry Smith 
30834a2ae208SSatish Balay #undef __FUNCT__
3084a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
30859b94acceSBarry Smith /*@C
3086a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
30879b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
30889b94acceSBarry Smith    progress.
30899b94acceSBarry Smith 
30903f9fe445SBarry Smith    Logically Collective on SNES
3091fee21e36SBarry Smith 
3092c7afd0dbSLois Curfman McInnes    Input Parameters:
3093c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3094c7afd0dbSLois Curfman McInnes .  func - monitoring routine
3095b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
3096e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
3097b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
3098b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
30999b94acceSBarry Smith 
3100c7afd0dbSLois Curfman McInnes    Calling sequence of func:
3101a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
3102c7afd0dbSLois Curfman McInnes 
3103c7afd0dbSLois Curfman McInnes +    snes - the SNES context
3104c7afd0dbSLois Curfman McInnes .    its - iteration number
3105c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
310640a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
31079b94acceSBarry Smith 
31089665c990SLois Curfman McInnes    Options Database Keys:
3109a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
31104619e776SBarry Smith .    -snes_monitor_lg_residualnorm    - sets line graph monitor,
3111a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
3112cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
3113c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
3114a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
3115c7afd0dbSLois Curfman McInnes                             does not cancel those set via
3116c7afd0dbSLois Curfman McInnes                             the options database.
31179665c990SLois Curfman McInnes 
3118639f9d9dSBarry Smith    Notes:
31196bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
3120a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
31216bc08f3fSLois Curfman McInnes    order in which they were set.
3122639f9d9dSBarry Smith 
3123025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
3124025f1a04SBarry Smith 
312536851e7fSLois Curfman McInnes    Level: intermediate
312636851e7fSLois Curfman McInnes 
31279b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
31289b94acceSBarry Smith 
3129a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
31309b94acceSBarry Smith @*/
3131c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
31329b94acceSBarry Smith {
3133b90d0a6eSBarry Smith   PetscInt       i;
3134649052a6SBarry Smith   PetscErrorCode ierr;
3135b90d0a6eSBarry Smith 
31363a40ed3dSBarry Smith   PetscFunctionBegin;
31370700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
313817186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
3139b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
3140649052a6SBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
3141649052a6SBarry Smith       if (monitordestroy) {
3142c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
3143649052a6SBarry Smith       }
3144b90d0a6eSBarry Smith       PetscFunctionReturn(0);
3145b90d0a6eSBarry Smith     }
3146b90d0a6eSBarry Smith   }
3147b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
3148b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
3149639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
31503a40ed3dSBarry Smith   PetscFunctionReturn(0);
31519b94acceSBarry Smith }
31529b94acceSBarry Smith 
31534a2ae208SSatish Balay #undef __FUNCT__
3154a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
31555cd90555SBarry Smith /*@C
3156a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
31575cd90555SBarry Smith 
31583f9fe445SBarry Smith    Logically Collective on SNES
3159c7afd0dbSLois Curfman McInnes 
31605cd90555SBarry Smith    Input Parameters:
31615cd90555SBarry Smith .  snes - the SNES context
31625cd90555SBarry Smith 
31631a480d89SAdministrator    Options Database Key:
3164a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
3165a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
3166c7afd0dbSLois Curfman McInnes     set via the options database
31675cd90555SBarry Smith 
31685cd90555SBarry Smith    Notes:
31695cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
31705cd90555SBarry Smith 
317136851e7fSLois Curfman McInnes    Level: intermediate
317236851e7fSLois Curfman McInnes 
31735cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
31745cd90555SBarry Smith 
3175a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
31765cd90555SBarry Smith @*/
31777087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
31785cd90555SBarry Smith {
3179d952e501SBarry Smith   PetscErrorCode ierr;
3180d952e501SBarry Smith   PetscInt       i;
3181d952e501SBarry Smith 
31825cd90555SBarry Smith   PetscFunctionBegin;
31830700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3184d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
3185d952e501SBarry Smith     if (snes->monitordestroy[i]) {
31863c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
3187d952e501SBarry Smith     }
3188d952e501SBarry Smith   }
31895cd90555SBarry Smith   snes->numbermonitors = 0;
31905cd90555SBarry Smith   PetscFunctionReturn(0);
31915cd90555SBarry Smith }
31925cd90555SBarry Smith 
31934a2ae208SSatish Balay #undef __FUNCT__
31944a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
31959b94acceSBarry Smith /*@C
31969b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
31979b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
31989b94acceSBarry Smith 
31993f9fe445SBarry Smith    Logically Collective on SNES
3200fee21e36SBarry Smith 
3201c7afd0dbSLois Curfman McInnes    Input Parameters:
3202c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3203c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
32047f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
32057f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
32069b94acceSBarry Smith 
3207c7afd0dbSLois Curfman McInnes    Calling sequence of func:
320806ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
3209c7afd0dbSLois Curfman McInnes 
3210c7afd0dbSLois Curfman McInnes +    snes - the SNES context
321106ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
3212c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
3213184914b5SBarry Smith .    reason - reason for convergence/divergence
3214c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
32154b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
32164b27c08aSLois Curfman McInnes -    f - 2-norm of function
32179b94acceSBarry Smith 
321836851e7fSLois Curfman McInnes    Level: advanced
321936851e7fSLois Curfman McInnes 
32209b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
32219b94acceSBarry Smith 
322285385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
32239b94acceSBarry Smith @*/
32247087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
32259b94acceSBarry Smith {
32267f7931b9SBarry Smith   PetscErrorCode ierr;
32277f7931b9SBarry Smith 
32283a40ed3dSBarry Smith   PetscFunctionBegin;
32290700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
323085385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
32317f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
32327f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
32337f7931b9SBarry Smith   }
323485385478SLisandro Dalcin   snes->ops->converged        = func;
32357f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
323685385478SLisandro Dalcin   snes->cnvP                  = cctx;
32373a40ed3dSBarry Smith   PetscFunctionReturn(0);
32389b94acceSBarry Smith }
32399b94acceSBarry Smith 
32404a2ae208SSatish Balay #undef __FUNCT__
32414a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
324252baeb72SSatish Balay /*@
3243184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
3244184914b5SBarry Smith 
3245184914b5SBarry Smith    Not Collective
3246184914b5SBarry Smith 
3247184914b5SBarry Smith    Input Parameter:
3248184914b5SBarry Smith .  snes - the SNES context
3249184914b5SBarry Smith 
3250184914b5SBarry Smith    Output Parameter:
32514d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
3252184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
3253184914b5SBarry Smith 
3254184914b5SBarry Smith    Level: intermediate
3255184914b5SBarry Smith 
3256184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
3257184914b5SBarry Smith 
3258184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
3259184914b5SBarry Smith 
326085385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
3261184914b5SBarry Smith @*/
32627087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
3263184914b5SBarry Smith {
3264184914b5SBarry Smith   PetscFunctionBegin;
32650700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
32664482741eSBarry Smith   PetscValidPointer(reason,2);
3267184914b5SBarry Smith   *reason = snes->reason;
3268184914b5SBarry Smith   PetscFunctionReturn(0);
3269184914b5SBarry Smith }
3270184914b5SBarry Smith 
32714a2ae208SSatish Balay #undef __FUNCT__
32724a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
3273c9005455SLois Curfman McInnes /*@
3274c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
3275c9005455SLois Curfman McInnes 
32763f9fe445SBarry Smith    Logically Collective on SNES
3277fee21e36SBarry Smith 
3278c7afd0dbSLois Curfman McInnes    Input Parameters:
3279c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
32808c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
3281cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
3282758f92a0SBarry Smith .  na  - size of a and its
328364731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
3284758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
3285c7afd0dbSLois Curfman McInnes 
3286308dcc3eSBarry Smith    Notes:
3287308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
3288308dcc3eSBarry Smith    default array of length 10000 is allocated.
3289308dcc3eSBarry Smith 
3290c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
3291c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
3292c9005455SLois Curfman McInnes    during the section of code that is being timed.
3293c9005455SLois Curfman McInnes 
329436851e7fSLois Curfman McInnes    Level: intermediate
329536851e7fSLois Curfman McInnes 
3296c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
3297758f92a0SBarry Smith 
329808405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
3299758f92a0SBarry Smith 
3300c9005455SLois Curfman McInnes @*/
33017087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
3302c9005455SLois Curfman McInnes {
3303308dcc3eSBarry Smith   PetscErrorCode ierr;
3304308dcc3eSBarry Smith 
33053a40ed3dSBarry Smith   PetscFunctionBegin;
33060700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
33074482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
3308a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
3309308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
3310308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
3311308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
3312308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
3313308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
3314308dcc3eSBarry Smith   }
3315c9005455SLois Curfman McInnes   snes->conv_hist       = a;
3316758f92a0SBarry Smith   snes->conv_hist_its   = its;
3317758f92a0SBarry Smith   snes->conv_hist_max   = na;
3318a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
3319758f92a0SBarry Smith   snes->conv_hist_reset = reset;
3320758f92a0SBarry Smith   PetscFunctionReturn(0);
3321758f92a0SBarry Smith }
3322758f92a0SBarry Smith 
3323308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3324c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
3325c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
3326308dcc3eSBarry Smith EXTERN_C_BEGIN
3327308dcc3eSBarry Smith #undef __FUNCT__
3328308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
3329308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
3330308dcc3eSBarry Smith {
3331308dcc3eSBarry Smith   mxArray   *mat;
3332308dcc3eSBarry Smith   PetscInt  i;
3333308dcc3eSBarry Smith   PetscReal *ar;
3334308dcc3eSBarry Smith 
3335308dcc3eSBarry Smith   PetscFunctionBegin;
3336308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
3337308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
3338308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
3339308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
3340308dcc3eSBarry Smith   }
3341308dcc3eSBarry Smith   PetscFunctionReturn(mat);
3342308dcc3eSBarry Smith }
3343308dcc3eSBarry Smith EXTERN_C_END
3344308dcc3eSBarry Smith #endif
3345308dcc3eSBarry Smith 
3346308dcc3eSBarry Smith 
33474a2ae208SSatish Balay #undef __FUNCT__
33484a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
33490c4c9dddSBarry Smith /*@C
3350758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
3351758f92a0SBarry Smith 
33523f9fe445SBarry Smith    Not Collective
3353758f92a0SBarry Smith 
3354758f92a0SBarry Smith    Input Parameter:
3355758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
3356758f92a0SBarry Smith 
3357758f92a0SBarry Smith    Output Parameters:
3358758f92a0SBarry Smith .  a   - array to hold history
3359758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
3360758f92a0SBarry Smith          negative if not converged) for each solve.
3361758f92a0SBarry Smith -  na  - size of a and its
3362758f92a0SBarry Smith 
3363758f92a0SBarry Smith    Notes:
3364758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
3365758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
3366758f92a0SBarry Smith 
3367758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
3368758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
3369758f92a0SBarry Smith    during the section of code that is being timed.
3370758f92a0SBarry Smith 
3371758f92a0SBarry Smith    Level: intermediate
3372758f92a0SBarry Smith 
3373758f92a0SBarry Smith .keywords: SNES, get, convergence, history
3374758f92a0SBarry Smith 
3375758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
3376758f92a0SBarry Smith 
3377758f92a0SBarry Smith @*/
33787087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3379758f92a0SBarry Smith {
3380758f92a0SBarry Smith   PetscFunctionBegin;
33810700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3382758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
3383758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
3384758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
33853a40ed3dSBarry Smith   PetscFunctionReturn(0);
3386c9005455SLois Curfman McInnes }
3387c9005455SLois Curfman McInnes 
3388e74ef692SMatthew Knepley #undef __FUNCT__
3389e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
3390ac226902SBarry Smith /*@C
339176b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
3392eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
33937e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
339476b2cf59SMatthew Knepley 
33953f9fe445SBarry Smith   Logically Collective on SNES
339676b2cf59SMatthew Knepley 
339776b2cf59SMatthew Knepley   Input Parameters:
339876b2cf59SMatthew Knepley . snes - The nonlinear solver context
339976b2cf59SMatthew Knepley . func - The function
340076b2cf59SMatthew Knepley 
340176b2cf59SMatthew Knepley   Calling sequence of func:
3402b5d30489SBarry Smith . func (SNES snes, PetscInt step);
340376b2cf59SMatthew Knepley 
340476b2cf59SMatthew Knepley . step - The current step of the iteration
340576b2cf59SMatthew Knepley 
3406fe97e370SBarry Smith   Level: advanced
3407fe97e370SBarry Smith 
3408fe97e370SBarry 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()
3409fe97e370SBarry Smith         This is not used by most users.
341076b2cf59SMatthew Knepley 
341176b2cf59SMatthew Knepley .keywords: SNES, update
3412b5d30489SBarry Smith 
341385385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
341476b2cf59SMatthew Knepley @*/
34157087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
341676b2cf59SMatthew Knepley {
341776b2cf59SMatthew Knepley   PetscFunctionBegin;
34180700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
3419e7788613SBarry Smith   snes->ops->update = func;
342076b2cf59SMatthew Knepley   PetscFunctionReturn(0);
342176b2cf59SMatthew Knepley }
342276b2cf59SMatthew Knepley 
3423e74ef692SMatthew Knepley #undef __FUNCT__
3424e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
342576b2cf59SMatthew Knepley /*@
342676b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
342776b2cf59SMatthew Knepley 
342876b2cf59SMatthew Knepley   Not collective
342976b2cf59SMatthew Knepley 
343076b2cf59SMatthew Knepley   Input Parameters:
343176b2cf59SMatthew Knepley . snes - The nonlinear solver context
343276b2cf59SMatthew Knepley . step - The current step of the iteration
343376b2cf59SMatthew Knepley 
3434205452f4SMatthew Knepley   Level: intermediate
3435205452f4SMatthew Knepley 
343676b2cf59SMatthew Knepley .keywords: SNES, update
3437a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
343876b2cf59SMatthew Knepley @*/
34397087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
344076b2cf59SMatthew Knepley {
344176b2cf59SMatthew Knepley   PetscFunctionBegin;
344276b2cf59SMatthew Knepley   PetscFunctionReturn(0);
344376b2cf59SMatthew Knepley }
344476b2cf59SMatthew Knepley 
34454a2ae208SSatish Balay #undef __FUNCT__
34464a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
34479b94acceSBarry Smith /*
34489b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
34499b94acceSBarry Smith    positive parameter delta.
34509b94acceSBarry Smith 
34519b94acceSBarry Smith     Input Parameters:
3452c7afd0dbSLois Curfman McInnes +   snes - the SNES context
34539b94acceSBarry Smith .   y - approximate solution of linear system
34549b94acceSBarry Smith .   fnorm - 2-norm of current function
3455c7afd0dbSLois Curfman McInnes -   delta - trust region size
34569b94acceSBarry Smith 
34579b94acceSBarry Smith     Output Parameters:
3458c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
34599b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
34609b94acceSBarry Smith     region, and exceeds zero otherwise.
3461c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
34629b94acceSBarry Smith 
34639b94acceSBarry Smith     Note:
34644b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
34659b94acceSBarry Smith     is set to be the maximum allowable step size.
34669b94acceSBarry Smith 
34679b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
34689b94acceSBarry Smith */
3469dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
34709b94acceSBarry Smith {
3471064f8208SBarry Smith   PetscReal      nrm;
3472ea709b57SSatish Balay   PetscScalar    cnorm;
3473dfbe8321SBarry Smith   PetscErrorCode ierr;
34743a40ed3dSBarry Smith 
34753a40ed3dSBarry Smith   PetscFunctionBegin;
34760700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
34770700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3478c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
3479184914b5SBarry Smith 
3480064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
3481064f8208SBarry Smith   if (nrm > *delta) {
3482064f8208SBarry Smith      nrm = *delta/nrm;
3483064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
3484064f8208SBarry Smith      cnorm = nrm;
34852dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
34869b94acceSBarry Smith      *ynorm = *delta;
34879b94acceSBarry Smith   } else {
34889b94acceSBarry Smith      *gpnorm = 0.0;
3489064f8208SBarry Smith      *ynorm = nrm;
34909b94acceSBarry Smith   }
34913a40ed3dSBarry Smith   PetscFunctionReturn(0);
34929b94acceSBarry Smith }
34939b94acceSBarry Smith 
34944a2ae208SSatish Balay #undef __FUNCT__
34954a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
34966ce558aeSBarry Smith /*@C
3497f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
3498f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
34999b94acceSBarry Smith 
3500c7afd0dbSLois Curfman McInnes    Collective on SNES
3501c7afd0dbSLois Curfman McInnes 
3502b2002411SLois Curfman McInnes    Input Parameters:
3503c7afd0dbSLois Curfman McInnes +  snes - the SNES context
35043cebf274SJed Brown .  b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero.
350585385478SLisandro Dalcin -  x - the solution vector.
35069b94acceSBarry Smith 
3507b2002411SLois Curfman McInnes    Notes:
35088ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
35098ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
35108ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
35118ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
35128ddd3da0SLois Curfman McInnes 
351336851e7fSLois Curfman McInnes    Level: beginner
351436851e7fSLois Curfman McInnes 
35159b94acceSBarry Smith .keywords: SNES, nonlinear, solve
35169b94acceSBarry Smith 
3517c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
35189b94acceSBarry Smith @*/
35197087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
35209b94acceSBarry Smith {
3521dfbe8321SBarry Smith   PetscErrorCode ierr;
3522ace3abfcSBarry Smith   PetscBool      flg;
3523eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
3524eabae89aSBarry Smith   PetscViewer    viewer;
3525efd51863SBarry Smith   PetscInt       grid;
3526a69afd8bSBarry Smith   Vec            xcreated = PETSC_NULL;
3527caa4e7f2SJed Brown   DM             dm;
3528052efed2SBarry Smith 
35293a40ed3dSBarry Smith   PetscFunctionBegin;
35300700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3531a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3532a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
35330700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
353485385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
353585385478SLisandro Dalcin 
3536caa4e7f2SJed Brown   if (!x) {
3537caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3538caa4e7f2SJed Brown     ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr);
3539a69afd8bSBarry Smith     x    = xcreated;
3540a69afd8bSBarry Smith   }
3541a69afd8bSBarry Smith 
3542a8248277SBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);}
3543efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
3544efd51863SBarry Smith 
354585385478SLisandro Dalcin     /* set solution vector */
3546efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
35476bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
354885385478SLisandro Dalcin     snes->vec_sol = x;
3549caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3550caa4e7f2SJed Brown 
3551caa4e7f2SJed Brown     /* set affine vector if provided */
355285385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
35536bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
355485385478SLisandro Dalcin     snes->vec_rhs = b;
355585385478SLisandro Dalcin 
355670e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
35573f149594SLisandro Dalcin 
35587eee914bSBarry Smith     if (!grid) {
35597eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
3560d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
3561dd568438SSatish Balay       } else if (snes->dm) {
3562dd568438SSatish Balay         PetscBool ig;
3563dd568438SSatish Balay         ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr);
3564dd568438SSatish Balay         if (ig) {
35657eee914bSBarry Smith           ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr);
35667eee914bSBarry Smith         }
3567d25893d9SBarry Smith       }
3568dd568438SSatish Balay     }
3569d25893d9SBarry Smith 
3570abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
357150ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
3572d5e45103SBarry Smith 
35733f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
35744936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
357585385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
35764936397dSBarry Smith     if (snes->domainerror){
35774936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
35784936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
35794936397dSBarry Smith     }
358017186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
35813f149594SLisandro Dalcin 
358290d69ab7SBarry Smith     flg  = PETSC_FALSE;
3583acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
3584da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
35855968eb51SBarry Smith     if (snes->printreason) {
3586a8248277SBarry Smith       ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
35875968eb51SBarry Smith       if (snes->reason > 0) {
3588c7e7b494SJed 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);
35895968eb51SBarry Smith       } else {
3590c7e7b494SJed 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);
35915968eb51SBarry Smith       }
3592a8248277SBarry Smith       ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
35935968eb51SBarry Smith     }
35945968eb51SBarry Smith 
3595e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
3596efd51863SBarry Smith     if (grid <  snes->gridsequence) {
3597efd51863SBarry Smith       DM  fine;
3598efd51863SBarry Smith       Vec xnew;
3599efd51863SBarry Smith       Mat interp;
3600efd51863SBarry Smith 
3601efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
3602c5c77316SJed Brown       if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
3603e727c939SJed Brown       ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
3604efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
3605efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
3606c833c3b5SJed Brown       ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr);
3607efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
3608efd51863SBarry Smith       x    = xnew;
3609efd51863SBarry Smith 
3610efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
3611efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
3612efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
3613a8248277SBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);
3614efd51863SBarry Smith     }
3615efd51863SBarry Smith   }
36163f7e2da0SPeter Brune   /* monitoring and viewing */
36173f7e2da0SPeter Brune   flg = PETSC_FALSE;
36183f7e2da0SPeter Brune   ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
36193f7e2da0SPeter Brune   if (flg && !PetscPreLoadingOn) {
36203f7e2da0SPeter Brune     ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
36213f7e2da0SPeter Brune     ierr = SNESView(snes,viewer);CHKERRQ(ierr);
36223f7e2da0SPeter Brune     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
36233f7e2da0SPeter Brune   }
36243f7e2da0SPeter Brune 
36253f7e2da0SPeter Brune   flg = PETSC_FALSE;
36263f7e2da0SPeter Brune   ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
36273f7e2da0SPeter Brune   if (flg) {
36283f7e2da0SPeter Brune     PetscViewer viewer;
36293f7e2da0SPeter Brune     ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
36303f7e2da0SPeter Brune     ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr);
36313f7e2da0SPeter Brune     ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr);
36323f7e2da0SPeter Brune     ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr);
36333f7e2da0SPeter Brune     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
36343f7e2da0SPeter Brune   }
36353f7e2da0SPeter Brune 
3636a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
36373a40ed3dSBarry Smith   PetscFunctionReturn(0);
36389b94acceSBarry Smith }
36399b94acceSBarry Smith 
36409b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
36419b94acceSBarry Smith 
36424a2ae208SSatish Balay #undef __FUNCT__
36434a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
364482bf6240SBarry Smith /*@C
36454b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
36469b94acceSBarry Smith 
3647fee21e36SBarry Smith    Collective on SNES
3648fee21e36SBarry Smith 
3649c7afd0dbSLois Curfman McInnes    Input Parameters:
3650c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3651454a90a3SBarry Smith -  type - a known method
3652c7afd0dbSLois Curfman McInnes 
3653c7afd0dbSLois Curfman McInnes    Options Database Key:
3654454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
3655c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
3656ae12b187SLois Curfman McInnes 
36579b94acceSBarry Smith    Notes:
3658e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
36594b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
3660c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
36614b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
3662c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
36639b94acceSBarry Smith 
3664ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
3665ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
3666ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
3667ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
3668ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
3669ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
3670ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
3671ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
3672ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
3673b0a32e0cSBarry Smith   appropriate method.
367436851e7fSLois Curfman McInnes 
367536851e7fSLois Curfman McInnes   Level: intermediate
3676a703fe33SLois Curfman McInnes 
3677454a90a3SBarry Smith .keywords: SNES, set, type
3678435da068SBarry Smith 
3679435da068SBarry Smith .seealso: SNESType, SNESCreate()
3680435da068SBarry Smith 
36819b94acceSBarry Smith @*/
368219fd82e9SBarry Smith PetscErrorCode  SNESSetType(SNES snes,SNESType type)
36839b94acceSBarry Smith {
3684dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
3685ace3abfcSBarry Smith   PetscBool      match;
36863a40ed3dSBarry Smith 
36873a40ed3dSBarry Smith   PetscFunctionBegin;
36880700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36894482741eSBarry Smith   PetscValidCharPointer(type,2);
369082bf6240SBarry Smith 
3691251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
36920f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
369392ff6ae8SBarry Smith 
36944b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
3695e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
369675396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
3697b5c23020SJed Brown   if (snes->ops->destroy) {
3698b5c23020SJed Brown     ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
3699b5c23020SJed Brown     snes->ops->destroy = PETSC_NULL;
3700b5c23020SJed Brown   }
370175396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
370275396ef9SLisandro Dalcin   snes->ops->setup          = 0;
370375396ef9SLisandro Dalcin   snes->ops->solve          = 0;
370475396ef9SLisandro Dalcin   snes->ops->view           = 0;
370575396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
370675396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
370775396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
370875396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
3709454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
371003bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
37119fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
37129fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
37139fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
37149fb22e1aSBarry Smith   }
37159fb22e1aSBarry Smith #endif
37163a40ed3dSBarry Smith   PetscFunctionReturn(0);
37179b94acceSBarry Smith }
37189b94acceSBarry Smith 
3719a847f771SSatish Balay 
37209b94acceSBarry Smith /* --------------------------------------------------------------------- */
37214a2ae208SSatish Balay #undef __FUNCT__
37224a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
372352baeb72SSatish Balay /*@
37249b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
3725f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
37269b94acceSBarry Smith 
3727fee21e36SBarry Smith    Not Collective
3728fee21e36SBarry Smith 
372936851e7fSLois Curfman McInnes    Level: advanced
373036851e7fSLois Curfman McInnes 
37319b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
37329b94acceSBarry Smith 
37339b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
37349b94acceSBarry Smith @*/
37357087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
37369b94acceSBarry Smith {
3737dfbe8321SBarry Smith   PetscErrorCode ierr;
373882bf6240SBarry Smith 
37393a40ed3dSBarry Smith   PetscFunctionBegin;
37401441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
37414c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
37423a40ed3dSBarry Smith   PetscFunctionReturn(0);
37439b94acceSBarry Smith }
37449b94acceSBarry Smith 
37454a2ae208SSatish Balay #undef __FUNCT__
37464a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
37479b94acceSBarry Smith /*@C
37489a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
37499b94acceSBarry Smith 
3750c7afd0dbSLois Curfman McInnes    Not Collective
3751c7afd0dbSLois Curfman McInnes 
37529b94acceSBarry Smith    Input Parameter:
37534b0e389bSBarry Smith .  snes - nonlinear solver context
37549b94acceSBarry Smith 
37559b94acceSBarry Smith    Output Parameter:
37563a7fca6bSBarry Smith .  type - SNES method (a character string)
37579b94acceSBarry Smith 
375836851e7fSLois Curfman McInnes    Level: intermediate
375936851e7fSLois Curfman McInnes 
3760454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
37619b94acceSBarry Smith @*/
376219fd82e9SBarry Smith PetscErrorCode  SNESGetType(SNES snes,SNESType *type)
37639b94acceSBarry Smith {
37643a40ed3dSBarry Smith   PetscFunctionBegin;
37650700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37664482741eSBarry Smith   PetscValidPointer(type,2);
37677adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
37683a40ed3dSBarry Smith   PetscFunctionReturn(0);
37699b94acceSBarry Smith }
37709b94acceSBarry Smith 
37714a2ae208SSatish Balay #undef __FUNCT__
37724a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
377352baeb72SSatish Balay /*@
37749b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
3775c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
37769b94acceSBarry Smith 
3777c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3778c7afd0dbSLois Curfman McInnes 
37799b94acceSBarry Smith    Input Parameter:
37809b94acceSBarry Smith .  snes - the SNES context
37819b94acceSBarry Smith 
37829b94acceSBarry Smith    Output Parameter:
37839b94acceSBarry Smith .  x - the solution
37849b94acceSBarry Smith 
378570e92668SMatthew Knepley    Level: intermediate
378636851e7fSLois Curfman McInnes 
37879b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
37889b94acceSBarry Smith 
378985385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
37909b94acceSBarry Smith @*/
37917087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
37929b94acceSBarry Smith {
37933a40ed3dSBarry Smith   PetscFunctionBegin;
37940700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37954482741eSBarry Smith   PetscValidPointer(x,2);
379685385478SLisandro Dalcin   *x = snes->vec_sol;
379770e92668SMatthew Knepley   PetscFunctionReturn(0);
379870e92668SMatthew Knepley }
379970e92668SMatthew Knepley 
380070e92668SMatthew Knepley #undef __FUNCT__
38014a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
380252baeb72SSatish Balay /*@
38039b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
38049b94acceSBarry Smith    stored.
38059b94acceSBarry Smith 
3806c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3807c7afd0dbSLois Curfman McInnes 
38089b94acceSBarry Smith    Input Parameter:
38099b94acceSBarry Smith .  snes - the SNES context
38109b94acceSBarry Smith 
38119b94acceSBarry Smith    Output Parameter:
38129b94acceSBarry Smith .  x - the solution update
38139b94acceSBarry Smith 
381436851e7fSLois Curfman McInnes    Level: advanced
381536851e7fSLois Curfman McInnes 
38169b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
38179b94acceSBarry Smith 
381885385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
38199b94acceSBarry Smith @*/
38207087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
38219b94acceSBarry Smith {
38223a40ed3dSBarry Smith   PetscFunctionBegin;
38230700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
38244482741eSBarry Smith   PetscValidPointer(x,2);
382585385478SLisandro Dalcin   *x = snes->vec_sol_update;
38263a40ed3dSBarry Smith   PetscFunctionReturn(0);
38279b94acceSBarry Smith }
38289b94acceSBarry Smith 
38294a2ae208SSatish Balay #undef __FUNCT__
38304a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
38319b94acceSBarry Smith /*@C
38323638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
38339b94acceSBarry Smith 
3834a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
3835c7afd0dbSLois Curfman McInnes 
38369b94acceSBarry Smith    Input Parameter:
38379b94acceSBarry Smith .  snes - the SNES context
38389b94acceSBarry Smith 
38399b94acceSBarry Smith    Output Parameter:
38407bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
384170e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
384270e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
38439b94acceSBarry Smith 
384436851e7fSLois Curfman McInnes    Level: advanced
384536851e7fSLois Curfman McInnes 
3846a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
38479b94acceSBarry Smith 
38484b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
38499b94acceSBarry Smith @*/
38507087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
38519b94acceSBarry Smith {
3852a63bb30eSJed Brown   PetscErrorCode ierr;
38536cab3a1bSJed Brown   DM             dm;
3854a63bb30eSJed Brown 
38553a40ed3dSBarry Smith   PetscFunctionBegin;
38560700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3857a63bb30eSJed Brown   if (r) {
3858a63bb30eSJed Brown     if (!snes->vec_func) {
3859a63bb30eSJed Brown       if (snes->vec_rhs) {
3860a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
3861a63bb30eSJed Brown       } else if (snes->vec_sol) {
3862a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
3863a63bb30eSJed Brown       } else if (snes->dm) {
3864a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
3865a63bb30eSJed Brown       }
3866a63bb30eSJed Brown     }
3867a63bb30eSJed Brown     *r = snes->vec_func;
3868a63bb30eSJed Brown   }
38696cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
38706cab3a1bSJed Brown   ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr);
38713a40ed3dSBarry Smith   PetscFunctionReturn(0);
38729b94acceSBarry Smith }
38739b94acceSBarry Smith 
3874c79ef259SPeter Brune /*@C
3875c79ef259SPeter Brune    SNESGetGS - Returns the GS function and context.
3876c79ef259SPeter Brune 
3877c79ef259SPeter Brune    Input Parameter:
3878c79ef259SPeter Brune .  snes - the SNES context
3879c79ef259SPeter Brune 
3880c79ef259SPeter Brune    Output Parameter:
3881c79ef259SPeter Brune +  gsfunc - the function (or PETSC_NULL)
3882c79ef259SPeter Brune -  ctx    - the function context (or PETSC_NULL)
3883c79ef259SPeter Brune 
3884c79ef259SPeter Brune    Level: advanced
3885c79ef259SPeter Brune 
3886c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
3887c79ef259SPeter Brune 
3888c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction()
3889c79ef259SPeter Brune @*/
3890c79ef259SPeter Brune 
38914a2ae208SSatish Balay #undef __FUNCT__
3892646217ecSPeter Brune #define __FUNCT__ "SNESGetGS"
3893646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx)
3894646217ecSPeter Brune {
38956cab3a1bSJed Brown   PetscErrorCode ierr;
38966cab3a1bSJed Brown   DM             dm;
38976cab3a1bSJed Brown 
3898646217ecSPeter Brune   PetscFunctionBegin;
3899646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
39006cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
39016cab3a1bSJed Brown   ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr);
3902646217ecSPeter Brune   PetscFunctionReturn(0);
3903646217ecSPeter Brune }
3904646217ecSPeter Brune 
39054a2ae208SSatish Balay #undef __FUNCT__
39064a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
39073c7409f5SSatish Balay /*@C
39083c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
3909d850072dSLois Curfman McInnes    SNES options in the database.
39103c7409f5SSatish Balay 
39113f9fe445SBarry Smith    Logically Collective on SNES
3912fee21e36SBarry Smith 
3913c7afd0dbSLois Curfman McInnes    Input Parameter:
3914c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3915c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3916c7afd0dbSLois Curfman McInnes 
3917d850072dSLois Curfman McInnes    Notes:
3918a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3919c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3920d850072dSLois Curfman McInnes 
392136851e7fSLois Curfman McInnes    Level: advanced
392236851e7fSLois Curfman McInnes 
39233c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
3924a86d99e1SLois Curfman McInnes 
3925a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
39263c7409f5SSatish Balay @*/
39277087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
39283c7409f5SSatish Balay {
3929dfbe8321SBarry Smith   PetscErrorCode ierr;
39303c7409f5SSatish Balay 
39313a40ed3dSBarry Smith   PetscFunctionBegin;
39320700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3933639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
39341cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
393535f5d045SPeter Brune   if (snes->linesearch) {
393635f5d045SPeter Brune     ierr = SNESGetSNESLineSearch(snes,&snes->linesearch);CHKERRQ(ierr);
393708b6c495SPeter Brune     ierr = PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr);
393835f5d045SPeter Brune   }
393935f5d045SPeter Brune   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
39403a40ed3dSBarry Smith   PetscFunctionReturn(0);
39413c7409f5SSatish Balay }
39423c7409f5SSatish Balay 
39434a2ae208SSatish Balay #undef __FUNCT__
39444a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
39453c7409f5SSatish Balay /*@C
3946f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
3947d850072dSLois Curfman McInnes    SNES options in the database.
39483c7409f5SSatish Balay 
39493f9fe445SBarry Smith    Logically Collective on SNES
3950fee21e36SBarry Smith 
3951c7afd0dbSLois Curfman McInnes    Input Parameters:
3952c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3953c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3954c7afd0dbSLois Curfman McInnes 
3955d850072dSLois Curfman McInnes    Notes:
3956a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3957c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3958d850072dSLois Curfman McInnes 
395936851e7fSLois Curfman McInnes    Level: advanced
396036851e7fSLois Curfman McInnes 
39613c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
3962a86d99e1SLois Curfman McInnes 
3963a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
39643c7409f5SSatish Balay @*/
39657087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
39663c7409f5SSatish Balay {
3967dfbe8321SBarry Smith   PetscErrorCode ierr;
39683c7409f5SSatish Balay 
39693a40ed3dSBarry Smith   PetscFunctionBegin;
39700700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3971639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
39721cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
397335f5d045SPeter Brune   if (snes->linesearch) {
397435f5d045SPeter Brune     ierr = SNESGetSNESLineSearch(snes,&snes->linesearch);CHKERRQ(ierr);
397508b6c495SPeter Brune     ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr);
397635f5d045SPeter Brune   }
397735f5d045SPeter Brune   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
39783a40ed3dSBarry Smith   PetscFunctionReturn(0);
39793c7409f5SSatish Balay }
39803c7409f5SSatish Balay 
39814a2ae208SSatish Balay #undef __FUNCT__
39824a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
39839ab63eb5SSatish Balay /*@C
39843c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
39853c7409f5SSatish Balay    SNES options in the database.
39863c7409f5SSatish Balay 
3987c7afd0dbSLois Curfman McInnes    Not Collective
3988c7afd0dbSLois Curfman McInnes 
39893c7409f5SSatish Balay    Input Parameter:
39903c7409f5SSatish Balay .  snes - the SNES context
39913c7409f5SSatish Balay 
39923c7409f5SSatish Balay    Output Parameter:
39933c7409f5SSatish Balay .  prefix - pointer to the prefix string used
39943c7409f5SSatish Balay 
39954ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
39969ab63eb5SSatish Balay    sufficient length to hold the prefix.
39979ab63eb5SSatish Balay 
399836851e7fSLois Curfman McInnes    Level: advanced
399936851e7fSLois Curfman McInnes 
40003c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
4001a86d99e1SLois Curfman McInnes 
4002a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
40033c7409f5SSatish Balay @*/
40047087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
40053c7409f5SSatish Balay {
4006dfbe8321SBarry Smith   PetscErrorCode ierr;
40073c7409f5SSatish Balay 
40083a40ed3dSBarry Smith   PetscFunctionBegin;
40090700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4010639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
40113a40ed3dSBarry Smith   PetscFunctionReturn(0);
40123c7409f5SSatish Balay }
40133c7409f5SSatish Balay 
4014b2002411SLois Curfman McInnes 
40154a2ae208SSatish Balay #undef __FUNCT__
40164a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
40173cea93caSBarry Smith /*@C
40183cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
40193cea93caSBarry Smith 
40207f6c08e0SMatthew Knepley   Level: advanced
40213cea93caSBarry Smith @*/
40227087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
4023b2002411SLois Curfman McInnes {
4024e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
4025dfbe8321SBarry Smith   PetscErrorCode ierr;
4026b2002411SLois Curfman McInnes 
4027b2002411SLois Curfman McInnes   PetscFunctionBegin;
4028b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
4029c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
4030b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
4031b2002411SLois Curfman McInnes }
4032da9b6338SBarry Smith 
4033da9b6338SBarry Smith #undef __FUNCT__
4034da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
40357087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
4036da9b6338SBarry Smith {
4037dfbe8321SBarry Smith   PetscErrorCode ierr;
403877431f27SBarry Smith   PetscInt       N,i,j;
4039da9b6338SBarry Smith   Vec            u,uh,fh;
4040da9b6338SBarry Smith   PetscScalar    value;
4041da9b6338SBarry Smith   PetscReal      norm;
4042da9b6338SBarry Smith 
4043da9b6338SBarry Smith   PetscFunctionBegin;
4044da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
4045da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
4046da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
4047da9b6338SBarry Smith 
4048da9b6338SBarry Smith   /* currently only works for sequential */
4049da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
4050da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
4051da9b6338SBarry Smith   for (i=0; i<N; i++) {
4052da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
405377431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
4054da9b6338SBarry Smith     for (j=-10; j<11; j++) {
4055ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
4056da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
40573ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
4058da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
405977431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
4060da9b6338SBarry Smith       value = -value;
4061da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
4062da9b6338SBarry Smith     }
4063da9b6338SBarry Smith   }
40646bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
40656bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
4066da9b6338SBarry Smith   PetscFunctionReturn(0);
4067da9b6338SBarry Smith }
406871f87433Sdalcinl 
406971f87433Sdalcinl #undef __FUNCT__
4070fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
407171f87433Sdalcinl /*@
4072fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
407371f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
407471f87433Sdalcinl    Newton method.
407571f87433Sdalcinl 
40763f9fe445SBarry Smith    Logically Collective on SNES
407771f87433Sdalcinl 
407871f87433Sdalcinl    Input Parameters:
407971f87433Sdalcinl +  snes - SNES context
408071f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
408171f87433Sdalcinl 
408264ba62caSBarry Smith     Options Database:
408364ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
408464ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
408564ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
408664ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
408764ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
408864ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
408964ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
409064ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
409164ba62caSBarry Smith 
409271f87433Sdalcinl    Notes:
409371f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
409471f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
409571f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
409671f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
409771f87433Sdalcinl    solver.
409871f87433Sdalcinl 
409971f87433Sdalcinl    Level: advanced
410071f87433Sdalcinl 
410171f87433Sdalcinl    Reference:
410271f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
410371f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
410471f87433Sdalcinl 
410571f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
410671f87433Sdalcinl 
4107fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
410871f87433Sdalcinl @*/
41097087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
411071f87433Sdalcinl {
411171f87433Sdalcinl   PetscFunctionBegin;
41120700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4113acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
411471f87433Sdalcinl   snes->ksp_ewconv = flag;
411571f87433Sdalcinl   PetscFunctionReturn(0);
411671f87433Sdalcinl }
411771f87433Sdalcinl 
411871f87433Sdalcinl #undef __FUNCT__
4119fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
412071f87433Sdalcinl /*@
4121fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
412271f87433Sdalcinl    for computing relative tolerance for linear solvers within an
412371f87433Sdalcinl    inexact Newton method.
412471f87433Sdalcinl 
412571f87433Sdalcinl    Not Collective
412671f87433Sdalcinl 
412771f87433Sdalcinl    Input Parameter:
412871f87433Sdalcinl .  snes - SNES context
412971f87433Sdalcinl 
413071f87433Sdalcinl    Output Parameter:
413171f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
413271f87433Sdalcinl 
413371f87433Sdalcinl    Notes:
413471f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
413571f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
413671f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
413771f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
413871f87433Sdalcinl    solver.
413971f87433Sdalcinl 
414071f87433Sdalcinl    Level: advanced
414171f87433Sdalcinl 
414271f87433Sdalcinl    Reference:
414371f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
414471f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
414571f87433Sdalcinl 
414671f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
414771f87433Sdalcinl 
4148fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
414971f87433Sdalcinl @*/
41507087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
415171f87433Sdalcinl {
415271f87433Sdalcinl   PetscFunctionBegin;
41530700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
415471f87433Sdalcinl   PetscValidPointer(flag,2);
415571f87433Sdalcinl   *flag = snes->ksp_ewconv;
415671f87433Sdalcinl   PetscFunctionReturn(0);
415771f87433Sdalcinl }
415871f87433Sdalcinl 
415971f87433Sdalcinl #undef __FUNCT__
4160fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
416171f87433Sdalcinl /*@
4162fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
416371f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
416471f87433Sdalcinl    Newton method.
416571f87433Sdalcinl 
41663f9fe445SBarry Smith    Logically Collective on SNES
416771f87433Sdalcinl 
416871f87433Sdalcinl    Input Parameters:
416971f87433Sdalcinl +    snes - SNES context
417071f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
417171f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
417271f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
417371f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
417471f87433Sdalcinl              (0 <= gamma2 <= 1)
417571f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
417671f87433Sdalcinl .    alpha2 - power for safeguard
417771f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
417871f87433Sdalcinl 
417971f87433Sdalcinl    Note:
418071f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
418171f87433Sdalcinl 
418271f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
418371f87433Sdalcinl 
418471f87433Sdalcinl    Level: advanced
418571f87433Sdalcinl 
418671f87433Sdalcinl    Reference:
418771f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
418871f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
418971f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
419071f87433Sdalcinl 
419171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
419271f87433Sdalcinl 
4193fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
419471f87433Sdalcinl @*/
41957087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
419671f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
419771f87433Sdalcinl {
4198fa9f3622SBarry Smith   SNESKSPEW *kctx;
419971f87433Sdalcinl   PetscFunctionBegin;
42000700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4201fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4202e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
4203c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
4204c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
4205c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
4206c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
4207c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
4208c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
4209c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
421071f87433Sdalcinl 
421171f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
421271f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
421371f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
421471f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
421571f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
421671f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
421771f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
421871f87433Sdalcinl 
421971f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
4220e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
422171f87433Sdalcinl   }
422271f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
4223e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
422471f87433Sdalcinl   }
422571f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
4226e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
422771f87433Sdalcinl   }
422871f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
4229e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
423071f87433Sdalcinl   }
423171f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
4232e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
423371f87433Sdalcinl   }
423471f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
4235e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
423671f87433Sdalcinl   }
423771f87433Sdalcinl   PetscFunctionReturn(0);
423871f87433Sdalcinl }
423971f87433Sdalcinl 
424071f87433Sdalcinl #undef __FUNCT__
4241fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
424271f87433Sdalcinl /*@
4243fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
424471f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
424571f87433Sdalcinl    Newton method.
424671f87433Sdalcinl 
424771f87433Sdalcinl    Not Collective
424871f87433Sdalcinl 
424971f87433Sdalcinl    Input Parameters:
425071f87433Sdalcinl      snes - SNES context
425171f87433Sdalcinl 
425271f87433Sdalcinl    Output Parameters:
425371f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
425471f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
425571f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
425671f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
425771f87433Sdalcinl              (0 <= gamma2 <= 1)
425871f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
425971f87433Sdalcinl .    alpha2 - power for safeguard
426071f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
426171f87433Sdalcinl 
426271f87433Sdalcinl    Level: advanced
426371f87433Sdalcinl 
426471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
426571f87433Sdalcinl 
4266fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
426771f87433Sdalcinl @*/
42687087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
426971f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
427071f87433Sdalcinl {
4271fa9f3622SBarry Smith   SNESKSPEW *kctx;
427271f87433Sdalcinl   PetscFunctionBegin;
42730700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4274fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4275e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
427671f87433Sdalcinl   if (version)   *version   = kctx->version;
427771f87433Sdalcinl   if (rtol_0)    *rtol_0    = kctx->rtol_0;
427871f87433Sdalcinl   if (rtol_max)  *rtol_max  = kctx->rtol_max;
427971f87433Sdalcinl   if (gamma)     *gamma     = kctx->gamma;
428071f87433Sdalcinl   if (alpha)     *alpha     = kctx->alpha;
428171f87433Sdalcinl   if (alpha2)    *alpha2    = kctx->alpha2;
428271f87433Sdalcinl   if (threshold) *threshold = kctx->threshold;
428371f87433Sdalcinl   PetscFunctionReturn(0);
428471f87433Sdalcinl }
428571f87433Sdalcinl 
428671f87433Sdalcinl #undef __FUNCT__
4287fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
4288fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
428971f87433Sdalcinl {
429071f87433Sdalcinl   PetscErrorCode ierr;
4291fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
429271f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
429371f87433Sdalcinl 
429471f87433Sdalcinl   PetscFunctionBegin;
4295e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
429671f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
429771f87433Sdalcinl     rtol = kctx->rtol_0;
429871f87433Sdalcinl   } else {
429971f87433Sdalcinl     if (kctx->version == 1) {
430071f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
430171f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
430271f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
430371f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
430471f87433Sdalcinl     } else if (kctx->version == 2) {
430571f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
430671f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
430771f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
430871f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
430971f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
431071f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
431171f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
431271f87433Sdalcinl       stol = PetscMax(rtol,stol);
431371f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
431471f87433Sdalcinl       /* safeguard: avoid oversolving */
431571f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
431671f87433Sdalcinl       stol = PetscMax(rtol,stol);
431771f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
4318e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
431971f87433Sdalcinl   }
432071f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
432171f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
432271f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
432371f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
432471f87433Sdalcinl   PetscFunctionReturn(0);
432571f87433Sdalcinl }
432671f87433Sdalcinl 
432771f87433Sdalcinl #undef __FUNCT__
4328fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
4329fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
433071f87433Sdalcinl {
433171f87433Sdalcinl   PetscErrorCode ierr;
4332fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
433371f87433Sdalcinl   PCSide         pcside;
433471f87433Sdalcinl   Vec            lres;
433571f87433Sdalcinl 
433671f87433Sdalcinl   PetscFunctionBegin;
4337e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
433871f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
433971f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
434071f87433Sdalcinl   if (kctx->version == 1) {
4341b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
434271f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
434371f87433Sdalcinl       /* KSP residual is true linear residual */
434471f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
434571f87433Sdalcinl     } else {
434671f87433Sdalcinl       /* KSP residual is preconditioned residual */
434771f87433Sdalcinl       /* compute true linear residual norm */
434871f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
434971f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
435071f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
435171f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
43526bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
435371f87433Sdalcinl     }
435471f87433Sdalcinl   }
435571f87433Sdalcinl   PetscFunctionReturn(0);
435671f87433Sdalcinl }
435771f87433Sdalcinl 
435871f87433Sdalcinl #undef __FUNCT__
435971f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
436071f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
436171f87433Sdalcinl {
436271f87433Sdalcinl   PetscErrorCode ierr;
436371f87433Sdalcinl 
436471f87433Sdalcinl   PetscFunctionBegin;
4365fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
436671f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
4367fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
436871f87433Sdalcinl   PetscFunctionReturn(0);
436971f87433Sdalcinl }
43706c699258SBarry Smith 
43716c699258SBarry Smith #undef __FUNCT__
43726c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
43736c699258SBarry Smith /*@
43746c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
43756c699258SBarry Smith 
43763f9fe445SBarry Smith    Logically Collective on SNES
43776c699258SBarry Smith 
43786c699258SBarry Smith    Input Parameters:
43796c699258SBarry Smith +  snes - the preconditioner context
43806c699258SBarry Smith -  dm - the dm
43816c699258SBarry Smith 
43826c699258SBarry Smith    Level: intermediate
43836c699258SBarry Smith 
43846c699258SBarry Smith 
43856c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
43866c699258SBarry Smith @*/
43877087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
43886c699258SBarry Smith {
43896c699258SBarry Smith   PetscErrorCode ierr;
4390345fed2cSBarry Smith   KSP            ksp;
43916cab3a1bSJed Brown   SNESDM         sdm;
43926c699258SBarry Smith 
43936c699258SBarry Smith   PetscFunctionBegin;
43940700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4395d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
43966cab3a1bSJed Brown   if (snes->dm) {               /* Move the SNESDM context over to the new DM unless the new DM already has one */
43976cab3a1bSJed Brown     PetscContainer oldcontainer,container;
43986cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr);
43996cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr);
4400116d1032SJed Brown     if (oldcontainer && snes->dmAuto && !container) {
44016cab3a1bSJed Brown       ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr);
44026cab3a1bSJed Brown       ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr);
44036cab3a1bSJed Brown       if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */
44046cab3a1bSJed Brown         sdm->originaldm = dm;
44056cab3a1bSJed Brown       }
44066cab3a1bSJed Brown     }
44076bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
44086cab3a1bSJed Brown   }
44096c699258SBarry Smith   snes->dm = dm;
4410116d1032SJed Brown   snes->dmAuto = PETSC_FALSE;
4411345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4412345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4413f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
44142c155ee1SBarry Smith   if (snes->pc) {
44152c155ee1SBarry Smith     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
4416c40d0f55SPeter Brune     ierr = SNESSetPCSide(snes,snes->pcside);CHKERRQ(ierr);
44172c155ee1SBarry Smith   }
44186c699258SBarry Smith   PetscFunctionReturn(0);
44196c699258SBarry Smith }
44206c699258SBarry Smith 
44216c699258SBarry Smith #undef __FUNCT__
44226c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
44236c699258SBarry Smith /*@
44246c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
44256c699258SBarry Smith 
44263f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
44276c699258SBarry Smith 
44286c699258SBarry Smith    Input Parameter:
44296c699258SBarry Smith . snes - the preconditioner context
44306c699258SBarry Smith 
44316c699258SBarry Smith    Output Parameter:
44326c699258SBarry Smith .  dm - the dm
44336c699258SBarry Smith 
44346c699258SBarry Smith    Level: intermediate
44356c699258SBarry Smith 
44366c699258SBarry Smith 
44376c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
44386c699258SBarry Smith @*/
44397087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
44406c699258SBarry Smith {
44416cab3a1bSJed Brown   PetscErrorCode ierr;
44426cab3a1bSJed Brown 
44436c699258SBarry Smith   PetscFunctionBegin;
44440700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
44456cab3a1bSJed Brown   if (!snes->dm) {
44466cab3a1bSJed Brown     ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr);
4447116d1032SJed Brown     snes->dmAuto = PETSC_TRUE;
44486cab3a1bSJed Brown   }
44496c699258SBarry Smith   *dm = snes->dm;
44506c699258SBarry Smith   PetscFunctionReturn(0);
44516c699258SBarry Smith }
44520807856dSBarry Smith 
445331823bd8SMatthew G Knepley #undef __FUNCT__
445431823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
445531823bd8SMatthew G Knepley /*@
4456fd4b34e9SJed Brown   SNESSetPC - Sets the nonlinear preconditioner to be used.
445731823bd8SMatthew G Knepley 
445831823bd8SMatthew G Knepley   Collective on SNES
445931823bd8SMatthew G Knepley 
446031823bd8SMatthew G Knepley   Input Parameters:
446131823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
446231823bd8SMatthew G Knepley - pc   - the preconditioner object
446331823bd8SMatthew G Knepley 
446431823bd8SMatthew G Knepley   Notes:
446531823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
446631823bd8SMatthew G Knepley   to configure it using the API).
446731823bd8SMatthew G Knepley 
446831823bd8SMatthew G Knepley   Level: developer
446931823bd8SMatthew G Knepley 
447031823bd8SMatthew G Knepley .keywords: SNES, set, precondition
447131823bd8SMatthew G Knepley .seealso: SNESGetPC()
447231823bd8SMatthew G Knepley @*/
447331823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
447431823bd8SMatthew G Knepley {
447531823bd8SMatthew G Knepley   PetscErrorCode ierr;
447631823bd8SMatthew G Knepley 
447731823bd8SMatthew G Knepley   PetscFunctionBegin;
447831823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
447931823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
448031823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
448131823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4482bf11d3b6SBarry Smith   ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr);
448331823bd8SMatthew G Knepley   snes->pc = pc;
448431823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
448531823bd8SMatthew G Knepley   PetscFunctionReturn(0);
448631823bd8SMatthew G Knepley }
448731823bd8SMatthew G Knepley 
448831823bd8SMatthew G Knepley #undef __FUNCT__
448931823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
449031823bd8SMatthew G Knepley /*@
4491fd4b34e9SJed Brown   SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().
449231823bd8SMatthew G Knepley 
449331823bd8SMatthew G Knepley   Not Collective
449431823bd8SMatthew G Knepley 
449531823bd8SMatthew G Knepley   Input Parameter:
449631823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
449731823bd8SMatthew G Knepley 
449831823bd8SMatthew G Knepley   Output Parameter:
449931823bd8SMatthew G Knepley . pc - preconditioner context
450031823bd8SMatthew G Knepley 
450131823bd8SMatthew G Knepley   Level: developer
450231823bd8SMatthew G Knepley 
450331823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
450431823bd8SMatthew G Knepley .seealso: SNESSetPC()
450531823bd8SMatthew G Knepley @*/
450631823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
450731823bd8SMatthew G Knepley {
450831823bd8SMatthew G Knepley   PetscErrorCode              ierr;
4509a64e098fSPeter Brune   const char                  *optionsprefix;
451031823bd8SMatthew G Knepley 
451131823bd8SMatthew G Knepley   PetscFunctionBegin;
451231823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
451331823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
451431823bd8SMatthew G Knepley   if (!snes->pc) {
451531823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm,&snes->pc);CHKERRQ(ierr);
45164a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);CHKERRQ(ierr);
451731823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes,snes->pc);CHKERRQ(ierr);
4518a64e098fSPeter Brune     ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr);
4519a64e098fSPeter Brune     ierr = SNESSetOptionsPrefix(snes->pc,optionsprefix);CHKERRQ(ierr);
4520a64e098fSPeter Brune     ierr = SNESAppendOptionsPrefix(snes->pc,"npc_");CHKERRQ(ierr);
452131823bd8SMatthew G Knepley   }
452231823bd8SMatthew G Knepley   *pc = snes->pc;
452331823bd8SMatthew G Knepley   PetscFunctionReturn(0);
452431823bd8SMatthew G Knepley }
452531823bd8SMatthew G Knepley 
4526c40d0f55SPeter Brune 
4527c40d0f55SPeter Brune #undef __FUNCT__
4528c40d0f55SPeter Brune #define __FUNCT__ "SNESSetPCSide"
4529c40d0f55SPeter Brune /*@
4530c40d0f55SPeter Brune     SNESSetPCSide - Sets the preconditioning side.
4531c40d0f55SPeter Brune 
4532c40d0f55SPeter Brune     Logically Collective on SNES
4533c40d0f55SPeter Brune 
4534c40d0f55SPeter Brune     Input Parameter:
4535c40d0f55SPeter Brune .   snes - iterative context obtained from SNESCreate()
4536c40d0f55SPeter Brune 
4537c40d0f55SPeter Brune     Output Parameter:
4538c40d0f55SPeter Brune .   side - the preconditioning side, where side is one of
4539c40d0f55SPeter Brune .vb
4540c40d0f55SPeter Brune       PC_LEFT - left preconditioning (default)
4541c40d0f55SPeter Brune       PC_RIGHT - right preconditioning
4542c40d0f55SPeter Brune .ve
4543c40d0f55SPeter Brune 
4544c40d0f55SPeter Brune     Options Database Keys:
4545c40d0f55SPeter Brune .   -snes_pc_side <right,left>
4546c40d0f55SPeter Brune 
4547c40d0f55SPeter Brune     Level: intermediate
4548c40d0f55SPeter Brune 
4549c40d0f55SPeter Brune .keywords: SNES, set, right, left, side, preconditioner, flag
4550c40d0f55SPeter Brune 
4551c40d0f55SPeter Brune .seealso: SNESGetPCSide(), KSPSetPCSide()
4552c40d0f55SPeter Brune @*/
4553c40d0f55SPeter Brune PetscErrorCode  SNESSetPCSide(SNES snes,PCSide side)
4554c40d0f55SPeter Brune {
4555c40d0f55SPeter Brune   PetscFunctionBegin;
4556c40d0f55SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4557c40d0f55SPeter Brune   PetscValidLogicalCollectiveEnum(snes,side,2);
4558c40d0f55SPeter Brune   snes->pcside = side;
4559c40d0f55SPeter Brune   PetscFunctionReturn(0);
4560c40d0f55SPeter Brune }
4561c40d0f55SPeter Brune 
4562c40d0f55SPeter Brune #undef __FUNCT__
4563c40d0f55SPeter Brune #define __FUNCT__ "SNESGetPCSide"
4564c40d0f55SPeter Brune /*@
4565c40d0f55SPeter Brune     SNESGetPCSide - Gets the preconditioning side.
4566c40d0f55SPeter Brune 
4567c40d0f55SPeter Brune     Not Collective
4568c40d0f55SPeter Brune 
4569c40d0f55SPeter Brune     Input Parameter:
4570c40d0f55SPeter Brune .   snes - iterative context obtained from SNESCreate()
4571c40d0f55SPeter Brune 
4572c40d0f55SPeter Brune     Output Parameter:
4573c40d0f55SPeter Brune .   side - the preconditioning side, where side is one of
4574c40d0f55SPeter Brune .vb
4575c40d0f55SPeter Brune       PC_LEFT - left preconditioning (default)
4576c40d0f55SPeter Brune       PC_RIGHT - right preconditioning
4577c40d0f55SPeter Brune .ve
4578c40d0f55SPeter Brune 
4579c40d0f55SPeter Brune     Level: intermediate
4580c40d0f55SPeter Brune 
4581c40d0f55SPeter Brune .keywords: SNES, get, right, left, side, preconditioner, flag
4582c40d0f55SPeter Brune 
4583c40d0f55SPeter Brune .seealso: SNESSetPCSide(), KSPGetPCSide()
4584c40d0f55SPeter Brune @*/
4585c40d0f55SPeter Brune PetscErrorCode  SNESGetPCSide(SNES snes,PCSide *side)
4586c40d0f55SPeter Brune {
4587c40d0f55SPeter Brune   PetscFunctionBegin;
4588c40d0f55SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4589c40d0f55SPeter Brune   PetscValidPointer(side,2);
4590c40d0f55SPeter Brune   *side = snes->pcside;
4591c40d0f55SPeter Brune   PetscFunctionReturn(0);
4592c40d0f55SPeter Brune }
4593c40d0f55SPeter Brune 
45949e764e56SPeter Brune #undef __FUNCT__
4595f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch"
45969e764e56SPeter Brune /*@
45978141a3b9SPeter Brune   SNESSetSNESLineSearch - Sets the linesearch on the SNES instance.
45989e764e56SPeter Brune 
45999e764e56SPeter Brune   Collective on SNES
46009e764e56SPeter Brune 
46019e764e56SPeter Brune   Input Parameters:
46029e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
46039e764e56SPeter Brune - linesearch   - the linesearch object
46049e764e56SPeter Brune 
46059e764e56SPeter Brune   Notes:
4606f1c6b773SPeter Brune   Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example,
46079e764e56SPeter Brune   to configure it using the API).
46089e764e56SPeter Brune 
46099e764e56SPeter Brune   Level: developer
46109e764e56SPeter Brune 
46119e764e56SPeter Brune .keywords: SNES, set, linesearch
4612f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch()
46139e764e56SPeter Brune @*/
4614f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch)
46159e764e56SPeter Brune {
46169e764e56SPeter Brune   PetscErrorCode ierr;
46179e764e56SPeter Brune 
46189e764e56SPeter Brune   PetscFunctionBegin;
46199e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4620f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
46219e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
46229e764e56SPeter Brune   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
4623f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
46249e764e56SPeter Brune   snes->linesearch = linesearch;
46259e764e56SPeter Brune   ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
46269e764e56SPeter Brune   PetscFunctionReturn(0);
46279e764e56SPeter Brune }
46289e764e56SPeter Brune 
46299e764e56SPeter Brune #undef __FUNCT__
4630f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch"
4631ea5d4fccSPeter Brune /*@C
46328141a3b9SPeter Brune   SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch()
46338141a3b9SPeter Brune   or creates a default line search instance associated with the SNES and returns it.
46349e764e56SPeter Brune 
46359e764e56SPeter Brune   Not Collective
46369e764e56SPeter Brune 
46379e764e56SPeter Brune   Input Parameter:
46389e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
46399e764e56SPeter Brune 
46409e764e56SPeter Brune   Output Parameter:
46419e764e56SPeter Brune . linesearch - linesearch context
46429e764e56SPeter Brune 
46439e764e56SPeter Brune   Level: developer
46449e764e56SPeter Brune 
46459e764e56SPeter Brune .keywords: SNES, get, linesearch
4646f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch()
46479e764e56SPeter Brune @*/
4648f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch)
46499e764e56SPeter Brune {
46509e764e56SPeter Brune   PetscErrorCode ierr;
46519e764e56SPeter Brune   const char     *optionsprefix;
46529e764e56SPeter Brune 
46539e764e56SPeter Brune   PetscFunctionBegin;
46549e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
46559e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
46569e764e56SPeter Brune   if (!snes->linesearch) {
46579e764e56SPeter Brune     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
4658f1c6b773SPeter Brune     ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr);
4659f1c6b773SPeter Brune     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
4660b1dca40bSPeter Brune     ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr);
46619e764e56SPeter Brune     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
46629e764e56SPeter Brune     ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
46639e764e56SPeter Brune   }
46649e764e56SPeter Brune   *linesearch = snes->linesearch;
46659e764e56SPeter Brune   PetscFunctionReturn(0);
46669e764e56SPeter Brune }
46679e764e56SPeter Brune 
466869b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4669c6db04a5SJed Brown #include <mex.h>
467069b4f73cSBarry Smith 
46718f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
46728f6e6473SBarry Smith 
46730807856dSBarry Smith #undef __FUNCT__
46740807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
46750807856dSBarry Smith /*
46760807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
46770807856dSBarry Smith                          SNESSetFunctionMatlab().
46780807856dSBarry Smith 
46790807856dSBarry Smith    Collective on SNES
46800807856dSBarry Smith 
46810807856dSBarry Smith    Input Parameters:
46820807856dSBarry Smith +  snes - the SNES context
46830807856dSBarry Smith -  x - input vector
46840807856dSBarry Smith 
46850807856dSBarry Smith    Output Parameter:
46860807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
46870807856dSBarry Smith 
46880807856dSBarry Smith    Notes:
46890807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
46900807856dSBarry Smith    implementations, so most users would not generally call this routine
46910807856dSBarry Smith    themselves.
46920807856dSBarry Smith 
46930807856dSBarry Smith    Level: developer
46940807856dSBarry Smith 
46950807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
46960807856dSBarry Smith 
46970807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
469861b2408cSBarry Smith */
46997087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
47000807856dSBarry Smith {
4701e650e774SBarry Smith   PetscErrorCode    ierr;
47028f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
47038f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
47048f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
470591621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
4706e650e774SBarry Smith 
47070807856dSBarry Smith   PetscFunctionBegin;
47080807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
47090807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
47100807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
47110807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
47120807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
47130807856dSBarry Smith 
47140807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
4715e650e774SBarry Smith 
471691621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4717e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4718e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
471991621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
472091621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
472191621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
47228f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
47238f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
4724b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
4725e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4726e650e774SBarry Smith   mxDestroyArray(prhs[0]);
4727e650e774SBarry Smith   mxDestroyArray(prhs[1]);
4728e650e774SBarry Smith   mxDestroyArray(prhs[2]);
47298f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
4730e650e774SBarry Smith   mxDestroyArray(plhs[0]);
47310807856dSBarry Smith   PetscFunctionReturn(0);
47320807856dSBarry Smith }
47330807856dSBarry Smith 
47340807856dSBarry Smith 
47350807856dSBarry Smith #undef __FUNCT__
47360807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
473761b2408cSBarry Smith /*
47380807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
47390807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4740e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
47410807856dSBarry Smith 
47420807856dSBarry Smith    Logically Collective on SNES
47430807856dSBarry Smith 
47440807856dSBarry Smith    Input Parameters:
47450807856dSBarry Smith +  snes - the SNES context
47460807856dSBarry Smith .  r - vector to store function value
47470807856dSBarry Smith -  func - function evaluation routine
47480807856dSBarry Smith 
47490807856dSBarry Smith    Calling sequence of func:
475061b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
47510807856dSBarry Smith 
47520807856dSBarry Smith 
47530807856dSBarry Smith    Notes:
47540807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
47550807856dSBarry Smith $      f'(x) x = -f(x),
47560807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
47570807856dSBarry Smith 
47580807856dSBarry Smith    Level: beginner
47590807856dSBarry Smith 
47600807856dSBarry Smith .keywords: SNES, nonlinear, set, function
47610807856dSBarry Smith 
47620807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
476361b2408cSBarry Smith */
47647087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
47650807856dSBarry Smith {
47660807856dSBarry Smith   PetscErrorCode    ierr;
47678f6e6473SBarry Smith   SNESMatlabContext *sctx;
47680807856dSBarry Smith 
47690807856dSBarry Smith   PetscFunctionBegin;
47708f6e6473SBarry Smith   /* currently sctx is memory bleed */
47718f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
47728f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
47738f6e6473SBarry Smith   /*
47748f6e6473SBarry Smith      This should work, but it doesn't
47758f6e6473SBarry Smith   sctx->ctx = ctx;
47768f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
47778f6e6473SBarry Smith   */
47788f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
47798f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
47800807856dSBarry Smith   PetscFunctionReturn(0);
47810807856dSBarry Smith }
478269b4f73cSBarry Smith 
478361b2408cSBarry Smith #undef __FUNCT__
478461b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
478561b2408cSBarry Smith /*
478661b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
478761b2408cSBarry Smith                          SNESSetJacobianMatlab().
478861b2408cSBarry Smith 
478961b2408cSBarry Smith    Collective on SNES
479061b2408cSBarry Smith 
479161b2408cSBarry Smith    Input Parameters:
479261b2408cSBarry Smith +  snes - the SNES context
479361b2408cSBarry Smith .  x - input vector
479461b2408cSBarry Smith .  A, B - the matrices
479561b2408cSBarry Smith -  ctx - user context
479661b2408cSBarry Smith 
479761b2408cSBarry Smith    Output Parameter:
479861b2408cSBarry Smith .  flag - structure of the matrix
479961b2408cSBarry Smith 
480061b2408cSBarry Smith    Level: developer
480161b2408cSBarry Smith 
480261b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
480361b2408cSBarry Smith 
480461b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
480561b2408cSBarry Smith @*/
48067087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
480761b2408cSBarry Smith {
480861b2408cSBarry Smith   PetscErrorCode    ierr;
480961b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
481061b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
481161b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
481261b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
481361b2408cSBarry Smith 
481461b2408cSBarry Smith   PetscFunctionBegin;
481561b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
481661b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
481761b2408cSBarry Smith 
481861b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
481961b2408cSBarry Smith 
482061b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
482161b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
482261b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
482361b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
482461b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
482561b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
482661b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
482761b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
482861b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
482961b2408cSBarry Smith   prhs[5] =  sctx->ctx;
4830b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
483161b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
483261b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
483361b2408cSBarry Smith   mxDestroyArray(prhs[0]);
483461b2408cSBarry Smith   mxDestroyArray(prhs[1]);
483561b2408cSBarry Smith   mxDestroyArray(prhs[2]);
483661b2408cSBarry Smith   mxDestroyArray(prhs[3]);
483761b2408cSBarry Smith   mxDestroyArray(prhs[4]);
483861b2408cSBarry Smith   mxDestroyArray(plhs[0]);
483961b2408cSBarry Smith   mxDestroyArray(plhs[1]);
484061b2408cSBarry Smith   PetscFunctionReturn(0);
484161b2408cSBarry Smith }
484261b2408cSBarry Smith 
484361b2408cSBarry Smith 
484461b2408cSBarry Smith #undef __FUNCT__
484561b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
484661b2408cSBarry Smith /*
484761b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
484861b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4849e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
485061b2408cSBarry Smith 
485161b2408cSBarry Smith    Logically Collective on SNES
485261b2408cSBarry Smith 
485361b2408cSBarry Smith    Input Parameters:
485461b2408cSBarry Smith +  snes - the SNES context
485561b2408cSBarry Smith .  A,B - Jacobian matrices
485661b2408cSBarry Smith .  func - function evaluation routine
485761b2408cSBarry Smith -  ctx - user context
485861b2408cSBarry Smith 
485961b2408cSBarry Smith    Calling sequence of func:
486061b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
486161b2408cSBarry Smith 
486261b2408cSBarry Smith 
486361b2408cSBarry Smith    Level: developer
486461b2408cSBarry Smith 
486561b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
486661b2408cSBarry Smith 
486761b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
486861b2408cSBarry Smith */
48697087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
487061b2408cSBarry Smith {
487161b2408cSBarry Smith   PetscErrorCode    ierr;
487261b2408cSBarry Smith   SNESMatlabContext *sctx;
487361b2408cSBarry Smith 
487461b2408cSBarry Smith   PetscFunctionBegin;
487561b2408cSBarry Smith   /* currently sctx is memory bleed */
487661b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
487761b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
487861b2408cSBarry Smith   /*
487961b2408cSBarry Smith      This should work, but it doesn't
488061b2408cSBarry Smith   sctx->ctx = ctx;
488161b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
488261b2408cSBarry Smith   */
488361b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
488461b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
488561b2408cSBarry Smith   PetscFunctionReturn(0);
488661b2408cSBarry Smith }
488769b4f73cSBarry Smith 
4888f9eb7ae2SShri Abhyankar #undef __FUNCT__
4889f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
4890f9eb7ae2SShri Abhyankar /*
4891f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
4892f9eb7ae2SShri Abhyankar 
4893f9eb7ae2SShri Abhyankar    Collective on SNES
4894f9eb7ae2SShri Abhyankar 
4895f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
4896f9eb7ae2SShri Abhyankar @*/
48977087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
4898f9eb7ae2SShri Abhyankar {
4899f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
490048f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
4901f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
4902f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
4903f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
4904f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
4905f9eb7ae2SShri Abhyankar 
4906f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4907f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4908f9eb7ae2SShri Abhyankar 
4909f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4910f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4911f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
4912f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
4913f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
4914f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
4915f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
4916f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
4917f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
4918f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4919f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
4920f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
4921f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
4922f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
4923f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
4924f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
4925f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4926f9eb7ae2SShri Abhyankar }
4927f9eb7ae2SShri Abhyankar 
4928f9eb7ae2SShri Abhyankar 
4929f9eb7ae2SShri Abhyankar #undef __FUNCT__
4930f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
4931f9eb7ae2SShri Abhyankar /*
4932e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
4933f9eb7ae2SShri Abhyankar 
4934f9eb7ae2SShri Abhyankar    Level: developer
4935f9eb7ae2SShri Abhyankar 
4936f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
4937f9eb7ae2SShri Abhyankar 
4938f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
4939f9eb7ae2SShri Abhyankar */
49407087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
4941f9eb7ae2SShri Abhyankar {
4942f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
4943f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
4944f9eb7ae2SShri Abhyankar 
4945f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4946f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
4947f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
4948f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4949f9eb7ae2SShri Abhyankar   /*
4950f9eb7ae2SShri Abhyankar      This should work, but it doesn't
4951f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
4952f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
4953f9eb7ae2SShri Abhyankar   */
4954f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
4955f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4956f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4957f9eb7ae2SShri Abhyankar }
4958f9eb7ae2SShri Abhyankar 
495969b4f73cSBarry Smith #endif
4960