xref: /petsc/src/snes/interface/snes.c (revision 4e269d778a4980f937dbf53e8c867b2c3b45d02b)
19b94acceSBarry Smith 
2b45d2f2cSJed Brown #include <petsc-private/snesimpl.h>      /*I "petscsnes.h"  I*/
36cab3a1bSJed Brown #include <petscdmshell.h>                /*I "petscdmshell.h" I*/
4a64e098fSPeter Brune #include <petscsys.h>                    /*I "petscsys.h" I*/
59b94acceSBarry Smith 
6ace3abfcSBarry Smith PetscBool  SNESRegisterAllCalled = PETSC_FALSE;
78ba1e511SMatthew Knepley PetscFList SNESList              = PETSC_NULL;
88ba1e511SMatthew Knepley 
98ba1e511SMatthew Knepley /* Logging support */
107087cfbeSBarry Smith PetscClassId  SNES_CLASSID;
11f1c6b773SPeter Brune PetscLogEvent  SNES_Solve, SNES_FunctionEval, SNES_JacobianEval, SNES_GSEval;
12a09944afSBarry Smith 
13a09944afSBarry Smith #undef __FUNCT__
14e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged"
15e113a28aSBarry Smith /*@
16e113a28aSBarry Smith    SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged.
17e113a28aSBarry Smith 
183f9fe445SBarry Smith    Logically Collective on SNES
19e113a28aSBarry Smith 
20e113a28aSBarry Smith    Input Parameters:
21e113a28aSBarry Smith +  snes - iterative context obtained from SNESCreate()
22e113a28aSBarry Smith -  flg - PETSC_TRUE indicates you want the error generated
23e113a28aSBarry Smith 
24e113a28aSBarry Smith    Options database keys:
25e113a28aSBarry Smith .  -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false)
26e113a28aSBarry Smith 
27e113a28aSBarry Smith    Level: intermediate
28e113a28aSBarry Smith 
29e113a28aSBarry Smith    Notes:
30e113a28aSBarry Smith     Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve()
31e113a28aSBarry Smith     to determine if it has converged.
32e113a28aSBarry Smith 
33e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
34e113a28aSBarry Smith 
35e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
36e113a28aSBarry Smith @*/
377087cfbeSBarry Smith PetscErrorCode  SNESSetErrorIfNotConverged(SNES snes,PetscBool  flg)
38e113a28aSBarry Smith {
39e113a28aSBarry Smith   PetscFunctionBegin;
40e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
41acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flg,2);
42e113a28aSBarry Smith   snes->errorifnotconverged = flg;
43dd568438SSatish Balay 
44e113a28aSBarry Smith   PetscFunctionReturn(0);
45e113a28aSBarry Smith }
46e113a28aSBarry Smith 
47e113a28aSBarry Smith #undef __FUNCT__
48e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged"
49e113a28aSBarry Smith /*@
50e113a28aSBarry Smith    SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge?
51e113a28aSBarry Smith 
52e113a28aSBarry Smith    Not Collective
53e113a28aSBarry Smith 
54e113a28aSBarry Smith    Input Parameter:
55e113a28aSBarry Smith .  snes - iterative context obtained from SNESCreate()
56e113a28aSBarry Smith 
57e113a28aSBarry Smith    Output Parameter:
58e113a28aSBarry Smith .  flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE
59e113a28aSBarry Smith 
60e113a28aSBarry Smith    Level: intermediate
61e113a28aSBarry Smith 
62e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
63e113a28aSBarry Smith 
64e113a28aSBarry Smith .seealso:  SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
65e113a28aSBarry Smith @*/
667087cfbeSBarry Smith PetscErrorCode  SNESGetErrorIfNotConverged(SNES snes,PetscBool  *flag)
67e113a28aSBarry Smith {
68e113a28aSBarry Smith   PetscFunctionBegin;
69e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
70e113a28aSBarry Smith   PetscValidPointer(flag,2);
71e113a28aSBarry Smith   *flag = snes->errorifnotconverged;
72e113a28aSBarry Smith   PetscFunctionReturn(0);
73e113a28aSBarry Smith }
74e113a28aSBarry Smith 
75e113a28aSBarry Smith #undef __FUNCT__
764936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError"
77e725d27bSBarry Smith /*@
784936397dSBarry Smith    SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not
794936397dSBarry Smith      in the functions domain. For example, negative pressure.
804936397dSBarry Smith 
813f9fe445SBarry Smith    Logically Collective on SNES
824936397dSBarry Smith 
834936397dSBarry Smith    Input Parameters:
846a388c36SPeter Brune .  snes - the SNES context
854936397dSBarry Smith 
8628529972SSatish Balay    Level: advanced
874936397dSBarry Smith 
884936397dSBarry Smith .keywords: SNES, view
894936397dSBarry Smith 
904936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction()
914936397dSBarry Smith @*/
927087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionDomainError(SNES snes)
934936397dSBarry Smith {
944936397dSBarry Smith   PetscFunctionBegin;
950700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
964936397dSBarry Smith   snes->domainerror = PETSC_TRUE;
974936397dSBarry Smith   PetscFunctionReturn(0);
984936397dSBarry Smith }
994936397dSBarry Smith 
1006a388c36SPeter Brune 
1016a388c36SPeter Brune #undef __FUNCT__
1026a388c36SPeter Brune #define __FUNCT__ "SNESGetFunctionDomainError"
1036a388c36SPeter Brune /*@
104c77b2880SPeter Brune    SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction;
1056a388c36SPeter Brune 
1066a388c36SPeter Brune    Logically Collective on SNES
1076a388c36SPeter Brune 
1086a388c36SPeter Brune    Input Parameters:
1096a388c36SPeter Brune .  snes - the SNES context
1106a388c36SPeter Brune 
1116a388c36SPeter Brune    Output Parameters:
1126a388c36SPeter Brune .  domainerror Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise.
1136a388c36SPeter Brune 
1146a388c36SPeter Brune    Level: advanced
1156a388c36SPeter Brune 
1166a388c36SPeter Brune .keywords: SNES, view
1176a388c36SPeter Brune 
1186a388c36SPeter Brune .seealso: SNESSetFunctionDomainError, SNESComputeFunction()
1196a388c36SPeter Brune @*/
1206a388c36SPeter Brune PetscErrorCode  SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror)
1216a388c36SPeter Brune {
1226a388c36SPeter Brune   PetscFunctionBegin;
1236a388c36SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1246a388c36SPeter Brune   PetscValidPointer(domainerror, 2);
1256a388c36SPeter Brune   *domainerror = snes->domainerror;
1266a388c36SPeter Brune   PetscFunctionReturn(0);
1276a388c36SPeter Brune }
1286a388c36SPeter Brune 
1296a388c36SPeter Brune 
1304936397dSBarry Smith #undef __FUNCT__
1314a2ae208SSatish Balay #define __FUNCT__ "SNESView"
1327e2c5f70SBarry Smith /*@C
1339b94acceSBarry Smith    SNESView - Prints the SNES data structure.
1349b94acceSBarry Smith 
1354c49b128SBarry Smith    Collective on SNES
136fee21e36SBarry Smith 
137c7afd0dbSLois Curfman McInnes    Input Parameters:
138c7afd0dbSLois Curfman McInnes +  SNES - the SNES context
139c7afd0dbSLois Curfman McInnes -  viewer - visualization context
140c7afd0dbSLois Curfman McInnes 
1419b94acceSBarry Smith    Options Database Key:
142c8a8ba5cSLois Curfman McInnes .  -snes_view - Calls SNESView() at end of SNESSolve()
1439b94acceSBarry Smith 
1449b94acceSBarry Smith    Notes:
1459b94acceSBarry Smith    The available visualization contexts include
146b0a32e0cSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
147b0a32e0cSBarry Smith -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
148c8a8ba5cSLois Curfman McInnes          output where only the first processor opens
149c8a8ba5cSLois Curfman McInnes          the file.  All other processors send their
150c8a8ba5cSLois Curfman McInnes          data to the first processor to print.
1519b94acceSBarry Smith 
1523e081fefSLois Curfman McInnes    The user can open an alternative visualization context with
153b0a32e0cSBarry Smith    PetscViewerASCIIOpen() - output to a specified file.
1549b94acceSBarry Smith 
15536851e7fSLois Curfman McInnes    Level: beginner
15636851e7fSLois Curfman McInnes 
1579b94acceSBarry Smith .keywords: SNES, view
1589b94acceSBarry Smith 
159b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen()
1609b94acceSBarry Smith @*/
1617087cfbeSBarry Smith PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
1629b94acceSBarry Smith {
163fa9f3622SBarry Smith   SNESKSPEW           *kctx;
164dfbe8321SBarry Smith   PetscErrorCode      ierr;
16594b7f48cSBarry Smith   KSP                 ksp;
1667f1410a3SPeter Brune   SNESLineSearch      linesearch;
167ace3abfcSBarry Smith   PetscBool           iascii,isstring;
1689b94acceSBarry Smith 
1693a40ed3dSBarry Smith   PetscFunctionBegin;
1700700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1713050cee2SBarry Smith   if (!viewer) {
1727adad957SLisandro Dalcin     ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
1733050cee2SBarry Smith   }
1740700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
175c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,viewer,2);
17674679c65SBarry Smith 
177251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
178251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
17932077d6dSBarry Smith   if (iascii) {
180317d6ea6SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr);
181e7788613SBarry Smith     if (snes->ops->view) {
182b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
183e7788613SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
184b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1850ef38995SBarry Smith     }
18677431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr);
187a83599f4SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%G, absolute=%G, solution=%G\n",
188c60f73f4SPeter Brune                  snes->rtol,snes->abstol,snes->stol);CHKERRQ(ierr);
18977431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr);
19077431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr);
19117fe4bdfSPeter Brune     if (snes->gridsequence) {
19217fe4bdfSPeter Brune       ierr = PetscViewerASCIIPrintf(viewer,"  total number of grid sequence refinements=%D\n",snes->gridsequence);CHKERRQ(ierr);
19317fe4bdfSPeter Brune     }
1949b94acceSBarry Smith     if (snes->ksp_ewconv) {
195fa9f3622SBarry Smith       kctx = (SNESKSPEW *)snes->kspconvctx;
1969b94acceSBarry Smith       if (kctx) {
19777431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr);
198a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr);
199a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr);
2009b94acceSBarry Smith       }
2019b94acceSBarry Smith     }
202eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
203eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");CHKERRQ(ierr);
204eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
205eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr);
206eb1f6c34SBarry Smith     }
207eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
208eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");CHKERRQ(ierr);
209eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
21042f4f86dSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr);
211eb1f6c34SBarry Smith     }
2120f5bd95cSBarry Smith   } else if (isstring) {
213317d6ea6SBarry Smith     const char *type;
214454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
215b0a32e0cSBarry Smith     ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr);
21619bcc07fSBarry Smith   }
21742f4f86dSBarry Smith   if (snes->pc && snes->usespc) {
2184a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2194a0c5b0cSMatthew G Knepley     ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr);
2204a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2214a0c5b0cSMatthew G Knepley   }
2222c155ee1SBarry Smith   if (snes->usesksp) {
2232c155ee1SBarry Smith     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
224b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
22594b7f48cSBarry Smith     ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
226b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2272c155ee1SBarry Smith   }
2287f1410a3SPeter Brune   if (snes->linesearch) {
2297f1410a3SPeter Brune     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2307f1410a3SPeter Brune     ierr = SNESGetSNESLineSearch(snes, &linesearch);CHKERRQ(ierr);
2317f1410a3SPeter Brune     ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr);
2327f1410a3SPeter Brune     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2337f1410a3SPeter Brune   }
2343a40ed3dSBarry Smith   PetscFunctionReturn(0);
2359b94acceSBarry Smith }
2369b94acceSBarry Smith 
23776b2cf59SMatthew Knepley /*
23876b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
23976b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
24076b2cf59SMatthew Knepley */
24176b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
242a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
2436849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
24476b2cf59SMatthew Knepley 
245e74ef692SMatthew Knepley #undef __FUNCT__
246e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker"
247ac226902SBarry Smith /*@C
24876b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
24976b2cf59SMatthew Knepley 
25076b2cf59SMatthew Knepley   Not Collective
25176b2cf59SMatthew Knepley 
25276b2cf59SMatthew Knepley   Input Parameter:
25376b2cf59SMatthew Knepley . snescheck - function that checks for options
25476b2cf59SMatthew Knepley 
25576b2cf59SMatthew Knepley   Level: developer
25676b2cf59SMatthew Knepley 
25776b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
25876b2cf59SMatthew Knepley @*/
2597087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
26076b2cf59SMatthew Knepley {
26176b2cf59SMatthew Knepley   PetscFunctionBegin;
26276b2cf59SMatthew Knepley   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
263e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
26476b2cf59SMatthew Knepley   }
26576b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
26676b2cf59SMatthew Knepley   PetscFunctionReturn(0);
26776b2cf59SMatthew Knepley }
26876b2cf59SMatthew Knepley 
2697087cfbeSBarry Smith extern PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
270aa3661deSLisandro Dalcin 
271aa3661deSLisandro Dalcin #undef __FUNCT__
272aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private"
273ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool  hasOperator, PetscInt version)
274aa3661deSLisandro Dalcin {
275aa3661deSLisandro Dalcin   Mat            J;
276aa3661deSLisandro Dalcin   KSP            ksp;
277aa3661deSLisandro Dalcin   PC             pc;
278ace3abfcSBarry Smith   PetscBool      match;
279aa3661deSLisandro Dalcin   PetscErrorCode ierr;
280aa3661deSLisandro Dalcin 
281aa3661deSLisandro Dalcin   PetscFunctionBegin;
2820700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
283aa3661deSLisandro Dalcin 
28498613b67SLisandro Dalcin   if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
28598613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
28698613b67SLisandro Dalcin     ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr);
28798613b67SLisandro Dalcin   }
28898613b67SLisandro Dalcin 
289aa3661deSLisandro Dalcin   if (version == 1) {
290aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
29198613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
2929c6ac3b3SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
293aa3661deSLisandro Dalcin   } else if (version == 2) {
294e32f2f54SBarry Smith     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
29582a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
296aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
297aa3661deSLisandro Dalcin #else
298e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
299aa3661deSLisandro Dalcin #endif
300a8248277SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
301aa3661deSLisandro Dalcin 
302aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
303d3462f78SMatthew Knepley   if (hasOperator) {
304aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
305aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
306aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
307aa3661deSLisandro Dalcin   } else {
308aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
309aa3661deSLisandro Dalcin        provided preconditioner matrix with the default matrix free version. */
3106cab3a1bSJed Brown     void *functx;
3116cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
3126cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
313aa3661deSLisandro Dalcin     /* Force no preconditioner */
314aa3661deSLisandro Dalcin     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
315aa3661deSLisandro Dalcin     ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
316251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
317aa3661deSLisandro Dalcin     if (!match) {
318aa3661deSLisandro Dalcin       ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
319aa3661deSLisandro Dalcin       ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
320aa3661deSLisandro Dalcin     }
321aa3661deSLisandro Dalcin   }
3226bf464f9SBarry Smith   ierr = MatDestroy(&J);CHKERRQ(ierr);
323aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
324aa3661deSLisandro Dalcin }
325aa3661deSLisandro Dalcin 
3264a2ae208SSatish Balay #undef __FUNCT__
327dfe15315SJed Brown #define __FUNCT__ "DMRestrictHook_SNESVecSol"
328dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx)
329dfe15315SJed Brown {
330dfe15315SJed Brown   SNES snes = (SNES)ctx;
331dfe15315SJed Brown   PetscErrorCode ierr;
332dfe15315SJed Brown   Vec Xfine,Xfine_named = PETSC_NULL,Xcoarse;
333dfe15315SJed Brown 
334dfe15315SJed Brown   PetscFunctionBegin;
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;
378*4e269d77SPeter Brune   void                        *ctxsave;
379*4e269d77SPeter 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;
388*4e269d77SPeter Brune     ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,&jac,&ctxsave);CHKERRQ(ierr);
389*4e269d77SPeter Brune     /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */
390*4e269d77SPeter Brune     if (jac == SNESDefaultComputeJacobianColor) {
391*4e269d77SPeter Brune       ierr = SNESSetJacobian(snes,PETSC_NULL,PETSC_NULL,SNESDefaultComputeJacobianColor,0);CHKERRQ(ierr);
392dfe15315SJed Brown     }
393*4e269d77SPeter Brune   }
394*4e269d77SPeter Brune   /* put the previous context back */
395*4e269d77SPeter Brune 
396dfe15315SJed Brown   ierr = SNESComputeJacobian(snes,X,&A,&B,mstruct);CHKERRQ(ierr);
397*4e269d77SPeter Brune   if (snes->dm != dmsave && jac == SNESDefaultComputeJacobianColor) {
398*4e269d77SPeter Brune     ierr = SNESSetJacobian(snes,PETSC_NULL,PETSC_NULL,jac,ctxsave);CHKERRQ(ierr);
399*4e269d77SPeter Brune   }
400*4e269d77SPeter 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) {
43317842b4fSJed Brown     SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_PLIB,"SNESDM not improperly configured");
4346cab3a1bSJed Brown   } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) {
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);
4416cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);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
501a6570f20SBarry Smith .  -snes_monitor_draw - plots residual norm at each iteration
502e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
5035968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
504fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
50582738288SBarry Smith 
50682738288SBarry Smith     Options Database for Eisenstat-Walker method:
507fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
5084b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
50936851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
51036851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
51136851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
51236851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
51336851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
51436851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
51582738288SBarry Smith 
51611ca99fdSLois Curfman McInnes    Notes:
51711ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
5180598bfebSBarry Smith    the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>.
51983e2fdc7SBarry Smith 
52036851e7fSLois Curfman McInnes    Level: beginner
52136851e7fSLois Curfman McInnes 
5229b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
5239b94acceSBarry Smith 
52469ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
5259b94acceSBarry Smith @*/
5267087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
5279b94acceSBarry Smith {
528872b6db9SPeter Brune   PetscBool               flg,mf,mf_operator,pcset;
529efd51863SBarry Smith   PetscInt                i,indx,lag,mf_version,grids;
530aa3661deSLisandro Dalcin   MatStructure            matflag;
53185385478SLisandro Dalcin   const char              *deft = SNESLS;
53285385478SLisandro Dalcin   const char              *convtests[] = {"default","skip"};
53385385478SLisandro Dalcin   SNESKSPEW               *kctx = NULL;
534e8105e01SRichard Katz   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
535649052a6SBarry Smith   PetscViewer             monviewer;
53685385478SLisandro Dalcin   PetscErrorCode          ierr;
537a64e098fSPeter Brune   const char              *optionsprefix;
5389b94acceSBarry Smith 
5393a40ed3dSBarry Smith   PetscFunctionBegin;
5400700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
541ca161407SBarry Smith 
542186905e3SBarry Smith   if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
5433194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
5447adad957SLisandro Dalcin     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
545b0a32e0cSBarry Smith     ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
546d64ed03dSBarry Smith     if (flg) {
547186905e3SBarry Smith       ierr = SNESSetType(snes,type);CHKERRQ(ierr);
5487adad957SLisandro Dalcin     } else if (!((PetscObject)snes)->type_name) {
549186905e3SBarry Smith       ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
550d64ed03dSBarry Smith     }
55190d69ab7SBarry Smith     /* not used here, but called so will go into help messaage */
552909c8a9fSBarry Smith     ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr);
55393c39befSBarry Smith 
554c60f73f4SPeter Brune     ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);CHKERRQ(ierr);
55557034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr);
556186905e3SBarry Smith 
55757034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr);
558b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr);
559b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr);
56024254dc1SJed Brown     ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr);
561ddf469c8SBarry Smith     ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr);
562acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr);
56385385478SLisandro Dalcin 
564a8054027SBarry Smith     ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
565a8054027SBarry Smith     if (flg) {
566a8054027SBarry Smith       ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
567a8054027SBarry Smith     }
568e35cf81dSBarry Smith     ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
569e35cf81dSBarry Smith     if (flg) {
570e35cf81dSBarry Smith       ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
571e35cf81dSBarry Smith     }
572efd51863SBarry Smith     ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
573efd51863SBarry Smith     if (flg) {
574efd51863SBarry Smith       ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
575efd51863SBarry Smith     }
576a8054027SBarry Smith 
57785385478SLisandro Dalcin     ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
57885385478SLisandro Dalcin     if (flg) {
57985385478SLisandro Dalcin       switch (indx) {
5807f7931b9SBarry Smith       case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break;
5817f7931b9SBarry Smith       case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);    break;
58285385478SLisandro Dalcin       }
58385385478SLisandro Dalcin     }
58485385478SLisandro Dalcin 
585acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr);
586186905e3SBarry Smith 
587fdacfa88SPeter Brune     ierr = PetscOptionsEList("-snes_norm_type","SNES Norm type","SNESSetNormType",SNESNormTypes,5,"function",&indx,&flg);CHKERRQ(ierr);
588fdacfa88SPeter Brune     if (flg) { ierr = SNESSetNormType(snes,(SNESNormType)indx);CHKERRQ(ierr); }
589fdacfa88SPeter Brune 
59085385478SLisandro Dalcin     kctx = (SNESKSPEW *)snes->kspconvctx;
59185385478SLisandro Dalcin 
592acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr);
593186905e3SBarry Smith 
594fa9f3622SBarry Smith     ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr);
595fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr);
596fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr);
597fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr);
598fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr);
599fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr);
600fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr);
601186905e3SBarry Smith 
60290d69ab7SBarry Smith     flg  = PETSC_FALSE;
603acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
604a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
605eabae89aSBarry Smith 
606a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
607e8105e01SRichard Katz     if (flg) {
608649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
609649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
610e8105e01SRichard Katz     }
611eabae89aSBarry Smith 
612b271bb04SBarry Smith     ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
613b271bb04SBarry Smith     if (flg) {
614b271bb04SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr);
615b271bb04SBarry Smith     }
616b271bb04SBarry Smith 
617a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
618eabae89aSBarry Smith     if (flg) {
619649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
620f1bef1bcSMatthew Knepley       ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr);
621e8105e01SRichard Katz     }
622eabae89aSBarry Smith 
623a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
624eabae89aSBarry Smith     if (flg) {
625649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
626649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
627eabae89aSBarry Smith     }
628eabae89aSBarry Smith 
6295180491cSLisandro Dalcin     ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
6305180491cSLisandro Dalcin     if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);}
6315180491cSLisandro Dalcin 
63290d69ab7SBarry Smith     flg  = PETSC_FALSE;
633acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
634a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
63590d69ab7SBarry Smith     flg  = PETSC_FALSE;
636acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
637a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
63890d69ab7SBarry Smith     flg  = PETSC_FALSE;
639acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
640a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
64190d69ab7SBarry Smith     flg  = PETSC_FALSE;
642acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
643a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
64490d69ab7SBarry Smith     flg  = PETSC_FALSE;
645acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
646b271bb04SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
647e24b481bSBarry Smith 
64890d69ab7SBarry Smith     flg  = PETSC_FALSE;
649acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
6504b27c08aSLois Curfman McInnes     if (flg) {
6516cab3a1bSJed Brown       void *functx;
6526cab3a1bSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
6536cab3a1bSJed Brown       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr);
654ae15b995SBarry Smith       ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
6559b94acceSBarry Smith     }
656639f9d9dSBarry Smith 
657aa3661deSLisandro Dalcin     mf = mf_operator = PETSC_FALSE;
658aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
659acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr);
660a8248277SBarry Smith     if (flg && mf_operator) {
661a8248277SBarry Smith       snes->mf_operator = PETSC_TRUE;
662a8248277SBarry Smith       mf = PETSC_TRUE;
663a8248277SBarry Smith     }
664aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
665acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr);
666aa3661deSLisandro Dalcin     if (!flg && mf_operator) mf = PETSC_TRUE;
667aa3661deSLisandro Dalcin     mf_version = 1;
668aa3661deSLisandro Dalcin     ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr);
669aa3661deSLisandro Dalcin 
670d28543b3SPeter Brune 
67189b92e6fSPeter Brune     /* GS Options */
67289b92e6fSPeter Brune     ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr);
67389b92e6fSPeter Brune 
67476b2cf59SMatthew Knepley     for(i = 0; i < numberofsetfromoptions; i++) {
67576b2cf59SMatthew Knepley       ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
67676b2cf59SMatthew Knepley     }
67776b2cf59SMatthew Knepley 
678e7788613SBarry Smith     if (snes->ops->setfromoptions) {
679e7788613SBarry Smith       ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr);
680639f9d9dSBarry Smith     }
6815d973c19SBarry Smith 
6825d973c19SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
6835d973c19SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr);
684b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
6854bbc92c1SBarry Smith 
686aa3661deSLisandro Dalcin   if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); }
6871cee3971SBarry Smith 
6881cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
689aa3661deSLisandro Dalcin   ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
690aa3661deSLisandro Dalcin   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr);
69185385478SLisandro Dalcin   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
69293993e2dSLois Curfman McInnes 
6939e764e56SPeter Brune   if (!snes->linesearch) {
694f1c6b773SPeter Brune     ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
6959e764e56SPeter Brune   }
696f1c6b773SPeter Brune   ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr);
6979e764e56SPeter Brune 
69851e86f29SPeter Brune   /* if someone has set the SNES PC type, create it. */
69951e86f29SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
70051e86f29SPeter Brune   ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr);
70151e86f29SPeter Brune   if (pcset && (!snes->pc)) {
70251e86f29SPeter Brune     ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr);
70351e86f29SPeter Brune   }
7043a40ed3dSBarry Smith   PetscFunctionReturn(0);
7059b94acceSBarry Smith }
7069b94acceSBarry Smith 
707d25893d9SBarry Smith #undef __FUNCT__
708d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext"
709d25893d9SBarry Smith /*@
710d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
711d25893d9SBarry Smith    the nonlinear solvers.
712d25893d9SBarry Smith 
713d25893d9SBarry Smith    Logically Collective on SNES
714d25893d9SBarry Smith 
715d25893d9SBarry Smith    Input Parameters:
716d25893d9SBarry Smith +  snes - the SNES context
717d25893d9SBarry Smith .  compute - function to compute the context
718d25893d9SBarry Smith -  destroy - function to destroy the context
719d25893d9SBarry Smith 
720d25893d9SBarry Smith    Level: intermediate
721d25893d9SBarry Smith 
722d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
723d25893d9SBarry Smith 
724d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
725d25893d9SBarry Smith @*/
726d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
727d25893d9SBarry Smith {
728d25893d9SBarry Smith   PetscFunctionBegin;
729d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
730d25893d9SBarry Smith   snes->ops->usercompute = compute;
731d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
732d25893d9SBarry Smith   PetscFunctionReturn(0);
733d25893d9SBarry Smith }
734a847f771SSatish Balay 
7354a2ae208SSatish Balay #undef __FUNCT__
7364a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
737b07ff414SBarry Smith /*@
7389b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
7399b94acceSBarry Smith    the nonlinear solvers.
7409b94acceSBarry Smith 
7413f9fe445SBarry Smith    Logically Collective on SNES
742fee21e36SBarry Smith 
743c7afd0dbSLois Curfman McInnes    Input Parameters:
744c7afd0dbSLois Curfman McInnes +  snes - the SNES context
745c7afd0dbSLois Curfman McInnes -  usrP - optional user context
746c7afd0dbSLois Curfman McInnes 
74736851e7fSLois Curfman McInnes    Level: intermediate
74836851e7fSLois Curfman McInnes 
7499b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
7509b94acceSBarry Smith 
751ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext()
7529b94acceSBarry Smith @*/
7537087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
7549b94acceSBarry Smith {
7551b2093e4SBarry Smith   PetscErrorCode ierr;
756b07ff414SBarry Smith   KSP            ksp;
7571b2093e4SBarry Smith 
7583a40ed3dSBarry Smith   PetscFunctionBegin;
7590700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
760b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
761b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
7629b94acceSBarry Smith   snes->user = usrP;
7633a40ed3dSBarry Smith   PetscFunctionReturn(0);
7649b94acceSBarry Smith }
76574679c65SBarry Smith 
7664a2ae208SSatish Balay #undef __FUNCT__
7674a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
768b07ff414SBarry Smith /*@
7699b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
7709b94acceSBarry Smith    nonlinear solvers.
7719b94acceSBarry Smith 
772c7afd0dbSLois Curfman McInnes    Not Collective
773c7afd0dbSLois Curfman McInnes 
7749b94acceSBarry Smith    Input Parameter:
7759b94acceSBarry Smith .  snes - SNES context
7769b94acceSBarry Smith 
7779b94acceSBarry Smith    Output Parameter:
7789b94acceSBarry Smith .  usrP - user context
7799b94acceSBarry Smith 
78036851e7fSLois Curfman McInnes    Level: intermediate
78136851e7fSLois Curfman McInnes 
7829b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
7839b94acceSBarry Smith 
7849b94acceSBarry Smith .seealso: SNESSetApplicationContext()
7859b94acceSBarry Smith @*/
786e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
7879b94acceSBarry Smith {
7883a40ed3dSBarry Smith   PetscFunctionBegin;
7890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
790e71120c6SJed Brown   *(void**)usrP = snes->user;
7913a40ed3dSBarry Smith   PetscFunctionReturn(0);
7929b94acceSBarry Smith }
79374679c65SBarry Smith 
7944a2ae208SSatish Balay #undef __FUNCT__
7954a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
7969b94acceSBarry Smith /*@
797c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
798c8228a4eSBarry Smith    at this time.
7999b94acceSBarry Smith 
800c7afd0dbSLois Curfman McInnes    Not Collective
801c7afd0dbSLois Curfman McInnes 
8029b94acceSBarry Smith    Input Parameter:
8039b94acceSBarry Smith .  snes - SNES context
8049b94acceSBarry Smith 
8059b94acceSBarry Smith    Output Parameter:
8069b94acceSBarry Smith .  iter - iteration number
8079b94acceSBarry Smith 
808c8228a4eSBarry Smith    Notes:
809c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
810c8228a4eSBarry Smith 
811c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
81208405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
81308405cd6SLois Curfman McInnes .vb
81408405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
81508405cd6SLois Curfman McInnes       if (!(it % 2)) {
81608405cd6SLois Curfman McInnes         [compute Jacobian here]
81708405cd6SLois Curfman McInnes       }
81808405cd6SLois Curfman McInnes .ve
819c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
82008405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
821c8228a4eSBarry Smith 
82236851e7fSLois Curfman McInnes    Level: intermediate
82336851e7fSLois Curfman McInnes 
8242b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
8252b668275SBarry Smith 
826b850b91aSLisandro Dalcin .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
8279b94acceSBarry Smith @*/
8287087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
8299b94acceSBarry Smith {
8303a40ed3dSBarry Smith   PetscFunctionBegin;
8310700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8324482741eSBarry Smith   PetscValidIntPointer(iter,2);
8339b94acceSBarry Smith   *iter = snes->iter;
8343a40ed3dSBarry Smith   PetscFunctionReturn(0);
8359b94acceSBarry Smith }
83674679c65SBarry Smith 
8374a2ae208SSatish Balay #undef __FUNCT__
838360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber"
839360c497dSPeter Brune /*@
840360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
841360c497dSPeter Brune 
842360c497dSPeter Brune    Not Collective
843360c497dSPeter Brune 
844360c497dSPeter Brune    Input Parameter:
845360c497dSPeter Brune .  snes - SNES context
846360c497dSPeter Brune .  iter - iteration number
847360c497dSPeter Brune 
848360c497dSPeter Brune    Level: developer
849360c497dSPeter Brune 
850360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number,
851360c497dSPeter Brune 
852360c497dSPeter Brune .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
853360c497dSPeter Brune @*/
854360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
855360c497dSPeter Brune {
856360c497dSPeter Brune   PetscErrorCode ierr;
857360c497dSPeter Brune 
858360c497dSPeter Brune   PetscFunctionBegin;
859360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
860360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
861360c497dSPeter Brune   snes->iter = iter;
862360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
863360c497dSPeter Brune   PetscFunctionReturn(0);
864360c497dSPeter Brune }
865360c497dSPeter Brune 
866360c497dSPeter Brune #undef __FUNCT__
8674a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm"
8689b94acceSBarry Smith /*@
8699b94acceSBarry Smith    SNESGetFunctionNorm - Gets the norm of the current function that was set
8709b94acceSBarry Smith    with SNESSSetFunction().
8719b94acceSBarry Smith 
872c7afd0dbSLois Curfman McInnes    Collective on SNES
873c7afd0dbSLois Curfman McInnes 
8749b94acceSBarry Smith    Input Parameter:
8759b94acceSBarry Smith .  snes - SNES context
8769b94acceSBarry Smith 
8779b94acceSBarry Smith    Output Parameter:
8789b94acceSBarry Smith .  fnorm - 2-norm of function
8799b94acceSBarry Smith 
88036851e7fSLois Curfman McInnes    Level: intermediate
88136851e7fSLois Curfman McInnes 
8829b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm
883a86d99e1SLois Curfman McInnes 
884b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
8859b94acceSBarry Smith @*/
8867087cfbeSBarry Smith PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
8879b94acceSBarry Smith {
8883a40ed3dSBarry Smith   PetscFunctionBegin;
8890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8904482741eSBarry Smith   PetscValidScalarPointer(fnorm,2);
8919b94acceSBarry Smith   *fnorm = snes->norm;
8923a40ed3dSBarry Smith   PetscFunctionReturn(0);
8939b94acceSBarry Smith }
89474679c65SBarry Smith 
895360c497dSPeter Brune 
896360c497dSPeter Brune #undef __FUNCT__
897360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm"
898360c497dSPeter Brune /*@
899360c497dSPeter Brune    SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm().
900360c497dSPeter Brune 
901360c497dSPeter Brune    Collective on SNES
902360c497dSPeter Brune 
903360c497dSPeter Brune    Input Parameter:
904360c497dSPeter Brune .  snes - SNES context
905360c497dSPeter Brune .  fnorm - 2-norm of function
906360c497dSPeter Brune 
907360c497dSPeter Brune    Level: developer
908360c497dSPeter Brune 
909360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm
910360c497dSPeter Brune 
911360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm().
912360c497dSPeter Brune @*/
913360c497dSPeter Brune PetscErrorCode  SNESSetFunctionNorm(SNES snes,PetscReal fnorm)
914360c497dSPeter Brune {
915360c497dSPeter Brune 
916360c497dSPeter Brune   PetscErrorCode ierr;
917360c497dSPeter Brune 
918360c497dSPeter Brune   PetscFunctionBegin;
919360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
920360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
921360c497dSPeter Brune   snes->norm = fnorm;
922360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
923360c497dSPeter Brune   PetscFunctionReturn(0);
924360c497dSPeter Brune }
925360c497dSPeter Brune 
9264a2ae208SSatish Balay #undef __FUNCT__
927b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
9289b94acceSBarry Smith /*@
929b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
9309b94acceSBarry Smith    attempted by the nonlinear solver.
9319b94acceSBarry Smith 
932c7afd0dbSLois Curfman McInnes    Not Collective
933c7afd0dbSLois Curfman McInnes 
9349b94acceSBarry Smith    Input Parameter:
9359b94acceSBarry Smith .  snes - SNES context
9369b94acceSBarry Smith 
9379b94acceSBarry Smith    Output Parameter:
9389b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
9399b94acceSBarry Smith 
940c96a6f78SLois Curfman McInnes    Notes:
941c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
942c96a6f78SLois Curfman McInnes 
94336851e7fSLois Curfman McInnes    Level: intermediate
94436851e7fSLois Curfman McInnes 
9459b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
94658ebbce7SBarry Smith 
947e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
94858ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
9499b94acceSBarry Smith @*/
9507087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
9519b94acceSBarry Smith {
9523a40ed3dSBarry Smith   PetscFunctionBegin;
9530700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9544482741eSBarry Smith   PetscValidIntPointer(nfails,2);
95550ffb88aSMatthew Knepley   *nfails = snes->numFailures;
95650ffb88aSMatthew Knepley   PetscFunctionReturn(0);
95750ffb88aSMatthew Knepley }
95850ffb88aSMatthew Knepley 
95950ffb88aSMatthew Knepley #undef __FUNCT__
960b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
96150ffb88aSMatthew Knepley /*@
962b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
96350ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
96450ffb88aSMatthew Knepley 
96550ffb88aSMatthew Knepley    Not Collective
96650ffb88aSMatthew Knepley 
96750ffb88aSMatthew Knepley    Input Parameters:
96850ffb88aSMatthew Knepley +  snes     - SNES context
96950ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
97050ffb88aSMatthew Knepley 
97150ffb88aSMatthew Knepley    Level: intermediate
97250ffb88aSMatthew Knepley 
97350ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
97458ebbce7SBarry Smith 
975e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
97658ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
97750ffb88aSMatthew Knepley @*/
9787087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
97950ffb88aSMatthew Knepley {
98050ffb88aSMatthew Knepley   PetscFunctionBegin;
9810700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
98250ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
98350ffb88aSMatthew Knepley   PetscFunctionReturn(0);
98450ffb88aSMatthew Knepley }
98550ffb88aSMatthew Knepley 
98650ffb88aSMatthew Knepley #undef __FUNCT__
987b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
98850ffb88aSMatthew Knepley /*@
989b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
99050ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
99150ffb88aSMatthew Knepley 
99250ffb88aSMatthew Knepley    Not Collective
99350ffb88aSMatthew Knepley 
99450ffb88aSMatthew Knepley    Input Parameter:
99550ffb88aSMatthew Knepley .  snes     - SNES context
99650ffb88aSMatthew Knepley 
99750ffb88aSMatthew Knepley    Output Parameter:
99850ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
99950ffb88aSMatthew Knepley 
100050ffb88aSMatthew Knepley    Level: intermediate
100150ffb88aSMatthew Knepley 
100250ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
100358ebbce7SBarry Smith 
1004e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
100558ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
100658ebbce7SBarry Smith 
100750ffb88aSMatthew Knepley @*/
10087087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
100950ffb88aSMatthew Knepley {
101050ffb88aSMatthew Knepley   PetscFunctionBegin;
10110700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10124482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
101350ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
10143a40ed3dSBarry Smith   PetscFunctionReturn(0);
10159b94acceSBarry Smith }
1016a847f771SSatish Balay 
10174a2ae208SSatish Balay #undef __FUNCT__
10182541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
10192541af92SBarry Smith /*@
10202541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
10212541af92SBarry Smith      done by SNES.
10222541af92SBarry Smith 
10232541af92SBarry Smith    Not Collective
10242541af92SBarry Smith 
10252541af92SBarry Smith    Input Parameter:
10262541af92SBarry Smith .  snes     - SNES context
10272541af92SBarry Smith 
10282541af92SBarry Smith    Output Parameter:
10292541af92SBarry Smith .  nfuncs - number of evaluations
10302541af92SBarry Smith 
10312541af92SBarry Smith    Level: intermediate
10322541af92SBarry Smith 
10332541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
103458ebbce7SBarry Smith 
1035e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
10362541af92SBarry Smith @*/
10377087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
10382541af92SBarry Smith {
10392541af92SBarry Smith   PetscFunctionBegin;
10400700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10412541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
10422541af92SBarry Smith   *nfuncs = snes->nfuncs;
10432541af92SBarry Smith   PetscFunctionReturn(0);
10442541af92SBarry Smith }
10452541af92SBarry Smith 
10462541af92SBarry Smith #undef __FUNCT__
10473d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
10483d4c4710SBarry Smith /*@
10493d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
10503d4c4710SBarry Smith    linear solvers.
10513d4c4710SBarry Smith 
10523d4c4710SBarry Smith    Not Collective
10533d4c4710SBarry Smith 
10543d4c4710SBarry Smith    Input Parameter:
10553d4c4710SBarry Smith .  snes - SNES context
10563d4c4710SBarry Smith 
10573d4c4710SBarry Smith    Output Parameter:
10583d4c4710SBarry Smith .  nfails - number of failed solves
10593d4c4710SBarry Smith 
10603d4c4710SBarry Smith    Notes:
10613d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
10623d4c4710SBarry Smith 
10633d4c4710SBarry Smith    Level: intermediate
10643d4c4710SBarry Smith 
10653d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
106658ebbce7SBarry Smith 
1067e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
10683d4c4710SBarry Smith @*/
10697087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
10703d4c4710SBarry Smith {
10713d4c4710SBarry Smith   PetscFunctionBegin;
10720700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10733d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
10743d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
10753d4c4710SBarry Smith   PetscFunctionReturn(0);
10763d4c4710SBarry Smith }
10773d4c4710SBarry Smith 
10783d4c4710SBarry Smith #undef __FUNCT__
10793d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
10803d4c4710SBarry Smith /*@
10813d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
10823d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
10833d4c4710SBarry Smith 
10843f9fe445SBarry Smith    Logically Collective on SNES
10853d4c4710SBarry Smith 
10863d4c4710SBarry Smith    Input Parameters:
10873d4c4710SBarry Smith +  snes     - SNES context
10883d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
10893d4c4710SBarry Smith 
10903d4c4710SBarry Smith    Level: intermediate
10913d4c4710SBarry Smith 
1092a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
10933d4c4710SBarry Smith 
10943d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
10953d4c4710SBarry Smith 
109658ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
10973d4c4710SBarry Smith @*/
10987087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
10993d4c4710SBarry Smith {
11003d4c4710SBarry Smith   PetscFunctionBegin;
11010700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1102c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
11033d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
11043d4c4710SBarry Smith   PetscFunctionReturn(0);
11053d4c4710SBarry Smith }
11063d4c4710SBarry Smith 
11073d4c4710SBarry Smith #undef __FUNCT__
11083d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
11093d4c4710SBarry Smith /*@
11103d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
11113d4c4710SBarry Smith      are allowed before SNES terminates
11123d4c4710SBarry Smith 
11133d4c4710SBarry Smith    Not Collective
11143d4c4710SBarry Smith 
11153d4c4710SBarry Smith    Input Parameter:
11163d4c4710SBarry Smith .  snes     - SNES context
11173d4c4710SBarry Smith 
11183d4c4710SBarry Smith    Output Parameter:
11193d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
11203d4c4710SBarry Smith 
11213d4c4710SBarry Smith    Level: intermediate
11223d4c4710SBarry Smith 
11233d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
11243d4c4710SBarry Smith 
11253d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
11263d4c4710SBarry Smith 
1127e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
11283d4c4710SBarry Smith @*/
11297087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
11303d4c4710SBarry Smith {
11313d4c4710SBarry Smith   PetscFunctionBegin;
11320700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11333d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
11343d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
11353d4c4710SBarry Smith   PetscFunctionReturn(0);
11363d4c4710SBarry Smith }
11373d4c4710SBarry Smith 
11383d4c4710SBarry Smith #undef __FUNCT__
1139b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
1140c96a6f78SLois Curfman McInnes /*@
1141b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1142c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1143c96a6f78SLois Curfman McInnes 
1144c7afd0dbSLois Curfman McInnes    Not Collective
1145c7afd0dbSLois Curfman McInnes 
1146c96a6f78SLois Curfman McInnes    Input Parameter:
1147c96a6f78SLois Curfman McInnes .  snes - SNES context
1148c96a6f78SLois Curfman McInnes 
1149c96a6f78SLois Curfman McInnes    Output Parameter:
1150c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1151c96a6f78SLois Curfman McInnes 
1152c96a6f78SLois Curfman McInnes    Notes:
1153c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1154c96a6f78SLois Curfman McInnes 
115536851e7fSLois Curfman McInnes    Level: intermediate
115636851e7fSLois Curfman McInnes 
1157c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
11582b668275SBarry Smith 
11598c7482ecSBarry Smith .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
1160c96a6f78SLois Curfman McInnes @*/
11617087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
1162c96a6f78SLois Curfman McInnes {
11633a40ed3dSBarry Smith   PetscFunctionBegin;
11640700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11654482741eSBarry Smith   PetscValidIntPointer(lits,2);
1166c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
11673a40ed3dSBarry Smith   PetscFunctionReturn(0);
1168c96a6f78SLois Curfman McInnes }
1169c96a6f78SLois Curfman McInnes 
11704a2ae208SSatish Balay #undef __FUNCT__
117194b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP"
117252baeb72SSatish Balay /*@
117394b7f48cSBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
11749b94acceSBarry Smith 
117594b7f48cSBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
1176c7afd0dbSLois Curfman McInnes 
11779b94acceSBarry Smith    Input Parameter:
11789b94acceSBarry Smith .  snes - the SNES context
11799b94acceSBarry Smith 
11809b94acceSBarry Smith    Output Parameter:
118194b7f48cSBarry Smith .  ksp - the KSP context
11829b94acceSBarry Smith 
11839b94acceSBarry Smith    Notes:
118494b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
11859b94acceSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
11862999313aSBarry Smith    PC contexts as well.
11879b94acceSBarry Smith 
118836851e7fSLois Curfman McInnes    Level: beginner
118936851e7fSLois Curfman McInnes 
119094b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
11919b94acceSBarry Smith 
11922999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
11939b94acceSBarry Smith @*/
11947087cfbeSBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
11959b94acceSBarry Smith {
11961cee3971SBarry Smith   PetscErrorCode ierr;
11971cee3971SBarry Smith 
11983a40ed3dSBarry Smith   PetscFunctionBegin;
11990700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12004482741eSBarry Smith   PetscValidPointer(ksp,2);
12011cee3971SBarry Smith 
12021cee3971SBarry Smith   if (!snes->ksp) {
12031cee3971SBarry Smith     ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr);
12041cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
12051cee3971SBarry Smith     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
12061cee3971SBarry Smith   }
120794b7f48cSBarry Smith   *ksp = snes->ksp;
12083a40ed3dSBarry Smith   PetscFunctionReturn(0);
12099b94acceSBarry Smith }
121082bf6240SBarry Smith 
12114a2ae208SSatish Balay #undef __FUNCT__
12122999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
12132999313aSBarry Smith /*@
12142999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
12152999313aSBarry Smith 
12162999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
12172999313aSBarry Smith 
12182999313aSBarry Smith    Input Parameters:
12192999313aSBarry Smith +  snes - the SNES context
12202999313aSBarry Smith -  ksp - the KSP context
12212999313aSBarry Smith 
12222999313aSBarry Smith    Notes:
12232999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
12242999313aSBarry Smith    so this routine is rarely needed.
12252999313aSBarry Smith 
12262999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
12272999313aSBarry Smith    decreased by one.
12282999313aSBarry Smith 
12292999313aSBarry Smith    Level: developer
12302999313aSBarry Smith 
12312999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
12322999313aSBarry Smith 
12332999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
12342999313aSBarry Smith @*/
12357087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
12362999313aSBarry Smith {
12372999313aSBarry Smith   PetscErrorCode ierr;
12382999313aSBarry Smith 
12392999313aSBarry Smith   PetscFunctionBegin;
12400700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12410700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
12422999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
12437dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1244906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
12452999313aSBarry Smith   snes->ksp = ksp;
12462999313aSBarry Smith   PetscFunctionReturn(0);
12472999313aSBarry Smith }
12482999313aSBarry Smith 
12497adad957SLisandro Dalcin #if 0
12502999313aSBarry Smith #undef __FUNCT__
12514a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc"
12526849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
1253e24b481bSBarry Smith {
1254e24b481bSBarry Smith   PetscFunctionBegin;
1255e24b481bSBarry Smith   PetscFunctionReturn(0);
1256e24b481bSBarry Smith }
12577adad957SLisandro Dalcin #endif
1258e24b481bSBarry Smith 
12599b94acceSBarry Smith /* -----------------------------------------------------------*/
12604a2ae208SSatish Balay #undef __FUNCT__
12614a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
126252baeb72SSatish Balay /*@
12639b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
12649b94acceSBarry Smith 
1265c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1266c7afd0dbSLois Curfman McInnes 
1267c7afd0dbSLois Curfman McInnes    Input Parameters:
1268906ed7ccSBarry Smith .  comm - MPI communicator
12699b94acceSBarry Smith 
12709b94acceSBarry Smith    Output Parameter:
12719b94acceSBarry Smith .  outsnes - the new SNES context
12729b94acceSBarry Smith 
1273c7afd0dbSLois Curfman McInnes    Options Database Keys:
1274c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1275c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1276c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1277c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1278c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1279c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1280c1f60f51SBarry Smith 
128136851e7fSLois Curfman McInnes    Level: beginner
128236851e7fSLois Curfman McInnes 
12839b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
12849b94acceSBarry Smith 
1285a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1286a8054027SBarry Smith 
12879b94acceSBarry Smith @*/
12887087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
12899b94acceSBarry Smith {
1290dfbe8321SBarry Smith   PetscErrorCode      ierr;
12919b94acceSBarry Smith   SNES                snes;
1292fa9f3622SBarry Smith   SNESKSPEW           *kctx;
129337fcc0dbSBarry Smith 
12943a40ed3dSBarry Smith   PetscFunctionBegin;
1295ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
12968ba1e511SMatthew Knepley   *outsnes = PETSC_NULL;
12978ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
12988ba1e511SMatthew Knepley   ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr);
12998ba1e511SMatthew Knepley #endif
13008ba1e511SMatthew Knepley 
13013194b578SJed Brown   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
13027adad957SLisandro Dalcin 
130385385478SLisandro Dalcin   snes->ops->converged    = SNESDefaultConverged;
13042c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
130588976e71SPeter Brune   snes->tolerancesset     = PETSC_FALSE;
13069b94acceSBarry Smith   snes->max_its           = 50;
13079750a799SBarry Smith   snes->max_funcs         = 10000;
13089b94acceSBarry Smith   snes->norm              = 0.0;
1309fdacfa88SPeter Brune   snes->normtype          = SNES_NORM_FUNCTION;
1310b4874afaSBarry Smith   snes->rtol              = 1.e-8;
1311b4874afaSBarry Smith   snes->ttol              = 0.0;
131270441072SBarry Smith   snes->abstol            = 1.e-50;
1313c60f73f4SPeter Brune   snes->stol              = 1.e-8;
13144b27c08aSLois Curfman McInnes   snes->deltatol          = 1.e-12;
13159b94acceSBarry Smith   snes->nfuncs            = 0;
131650ffb88aSMatthew Knepley   snes->numFailures       = 0;
131750ffb88aSMatthew Knepley   snes->maxFailures       = 1;
13187a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1319e35cf81dSBarry Smith   snes->lagjacobian       = 1;
1320a8054027SBarry Smith   snes->lagpreconditioner = 1;
1321639f9d9dSBarry Smith   snes->numbermonitors    = 0;
13229b94acceSBarry Smith   snes->data              = 0;
13234dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1324186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
13256f24a144SLois Curfman McInnes   snes->nwork             = 0;
132658c9b817SLisandro Dalcin   snes->work              = 0;
132758c9b817SLisandro Dalcin   snes->nvwork            = 0;
132858c9b817SLisandro Dalcin   snes->vwork             = 0;
1329758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1330758f92a0SBarry Smith   snes->conv_hist_max     = 0;
1331758f92a0SBarry Smith   snes->conv_hist         = PETSC_NULL;
1332758f92a0SBarry Smith   snes->conv_hist_its     = PETSC_NULL;
1333758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1334e4ed7901SPeter Brune   snes->vec_func_init_set = PETSC_FALSE;
1335e4ed7901SPeter Brune   snes->norm_init         = 0.;
1336e4ed7901SPeter Brune   snes->norm_init_set     = PETSC_FALSE;
1337184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
133889b92e6fSPeter Brune   snes->gssweeps          = 1;
13399b94acceSBarry Smith 
13403d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
13413d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
13423d4c4710SBarry Smith 
13439b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
134438f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr);
13459b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
13469b94acceSBarry Smith   kctx->version     = 2;
13479b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
13489b94acceSBarry Smith                              this was too large for some test cases */
134975567043SBarry Smith   kctx->rtol_last   = 0.0;
13509b94acceSBarry Smith   kctx->rtol_max    = .9;
13519b94acceSBarry Smith   kctx->gamma       = 1.0;
135262d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
135371f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
13549b94acceSBarry Smith   kctx->threshold   = .1;
135575567043SBarry Smith   kctx->lresid_last = 0.0;
135675567043SBarry Smith   kctx->norm_last   = 0.0;
13579b94acceSBarry Smith 
13589b94acceSBarry Smith   *outsnes = snes;
13593a40ed3dSBarry Smith   PetscFunctionReturn(0);
13609b94acceSBarry Smith }
13619b94acceSBarry Smith 
13624a2ae208SSatish Balay #undef __FUNCT__
13634a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
13649b94acceSBarry Smith /*@C
13659b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
13669b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
13679b94acceSBarry Smith    equations.
13689b94acceSBarry Smith 
13693f9fe445SBarry Smith    Logically Collective on SNES
1370fee21e36SBarry Smith 
1371c7afd0dbSLois Curfman McInnes    Input Parameters:
1372c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1373c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1374de044059SHong Zhang .  func - function evaluation routine
1375c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1376c7afd0dbSLois Curfman McInnes          function evaluation routine (may be PETSC_NULL)
13779b94acceSBarry Smith 
1378c7afd0dbSLois Curfman McInnes    Calling sequence of func:
13798d76a1e5SLois Curfman McInnes $    func (SNES snes,Vec x,Vec f,void *ctx);
1380c7afd0dbSLois Curfman McInnes 
1381c586c404SJed Brown +  snes - the SNES context
1382c586c404SJed Brown .  x - state at which to evaluate residual
1383c586c404SJed Brown .  f - vector to put residual
1384c7afd0dbSLois Curfman McInnes -  ctx - optional user-defined function context
13859b94acceSBarry Smith 
13869b94acceSBarry Smith    Notes:
13879b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
13889b94acceSBarry Smith $      f'(x) x = -f(x),
1389c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
13909b94acceSBarry Smith 
139136851e7fSLois Curfman McInnes    Level: beginner
139236851e7fSLois Curfman McInnes 
13939b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
13949b94acceSBarry Smith 
13958b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard()
13969b94acceSBarry Smith @*/
13977087cfbeSBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
13989b94acceSBarry Smith {
139985385478SLisandro Dalcin   PetscErrorCode ierr;
14006cab3a1bSJed Brown   DM             dm;
14016cab3a1bSJed Brown 
14023a40ed3dSBarry Smith   PetscFunctionBegin;
14030700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1404d2a683ecSLisandro Dalcin   if (r) {
1405d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1406d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
140785385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
14086bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
140985385478SLisandro Dalcin     snes->vec_func = r;
1410d2a683ecSLisandro Dalcin   }
14116cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
14126cab3a1bSJed Brown   ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr);
14133a40ed3dSBarry Smith   PetscFunctionReturn(0);
14149b94acceSBarry Smith }
14159b94acceSBarry Smith 
1416646217ecSPeter Brune 
1417646217ecSPeter Brune #undef __FUNCT__
1418e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction"
1419e4ed7901SPeter Brune /*@C
1420e4ed7901SPeter Brune    SNESSetInitialFunction - Sets the function vector to be used as the
1421e4ed7901SPeter Brune    function norm at the initialization of the method.  In some
1422e4ed7901SPeter Brune    instances, the user has precomputed the function before calling
1423e4ed7901SPeter Brune    SNESSolve.  This function allows one to avoid a redundant call
1424e4ed7901SPeter Brune    to SNESComputeFunction in that case.
1425e4ed7901SPeter Brune 
1426e4ed7901SPeter Brune    Logically Collective on SNES
1427e4ed7901SPeter Brune 
1428e4ed7901SPeter Brune    Input Parameters:
1429e4ed7901SPeter Brune +  snes - the SNES context
1430e4ed7901SPeter Brune -  f - vector to store function value
1431e4ed7901SPeter Brune 
1432e4ed7901SPeter Brune    Notes:
1433e4ed7901SPeter Brune    This should not be modified during the solution procedure.
1434e4ed7901SPeter Brune 
1435e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1436e4ed7901SPeter Brune 
1437e4ed7901SPeter Brune    Level: developer
1438e4ed7901SPeter Brune 
1439e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function
1440e4ed7901SPeter Brune 
1441e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm()
1442e4ed7901SPeter Brune @*/
1443e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunction(SNES snes, Vec f)
1444e4ed7901SPeter Brune {
1445e4ed7901SPeter Brune   PetscErrorCode ierr;
1446e4ed7901SPeter Brune   Vec            vec_func;
1447e4ed7901SPeter Brune 
1448e4ed7901SPeter Brune   PetscFunctionBegin;
1449e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1450e4ed7901SPeter Brune   PetscValidHeaderSpecific(f,VEC_CLASSID,2);
1451e4ed7901SPeter Brune   PetscCheckSameComm(snes,1,f,2);
1452e4ed7901SPeter Brune   ierr = SNESGetFunction(snes,&vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
1453e4ed7901SPeter Brune   ierr = VecCopy(f, vec_func);CHKERRQ(ierr);
1454217b9c2eSPeter Brune   snes->vec_func_init_set = PETSC_TRUE;
1455e4ed7901SPeter Brune   PetscFunctionReturn(0);
1456e4ed7901SPeter Brune }
1457e4ed7901SPeter Brune 
1458e4ed7901SPeter Brune 
1459e4ed7901SPeter Brune #undef __FUNCT__
1460e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunctionNorm"
1461e4ed7901SPeter Brune /*@C
1462e4ed7901SPeter Brune    SNESSetInitialFunctionNorm - Sets the function norm to be used as the function norm
1463e4ed7901SPeter Brune    at the initialization of the  method.  In some instances, the user has precomputed
1464e4ed7901SPeter Brune    the function and its norm before calling SNESSolve.  This function allows one to
1465e4ed7901SPeter Brune    avoid a redundant call to SNESComputeFunction() and VecNorm() in that case.
1466e4ed7901SPeter Brune 
1467e4ed7901SPeter Brune    Logically Collective on SNES
1468e4ed7901SPeter Brune 
1469e4ed7901SPeter Brune    Input Parameters:
1470e4ed7901SPeter Brune +  snes - the SNES context
1471e4ed7901SPeter Brune -  fnorm - the norm of F as set by SNESSetInitialFunction()
1472e4ed7901SPeter Brune 
1473e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1474e4ed7901SPeter Brune 
1475e4ed7901SPeter Brune    Level: developer
1476e4ed7901SPeter Brune 
1477e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function, norm
1478e4ed7901SPeter Brune 
1479e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction()
1480e4ed7901SPeter Brune @*/
1481e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm)
1482e4ed7901SPeter Brune {
1483e4ed7901SPeter Brune   PetscFunctionBegin;
1484e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1485e4ed7901SPeter Brune   snes->norm_init = fnorm;
1486e4ed7901SPeter Brune   snes->norm_init_set = PETSC_TRUE;
1487e4ed7901SPeter Brune   PetscFunctionReturn(0);
1488e4ed7901SPeter Brune }
1489e4ed7901SPeter Brune 
1490e4ed7901SPeter Brune #undef __FUNCT__
1491534ebe21SPeter Brune #define __FUNCT__ "SNESSetNormType"
1492534ebe21SPeter Brune /*@
1493534ebe21SPeter Brune    SNESSetNormType - Sets the SNESNormType used in covergence and monitoring
1494534ebe21SPeter Brune    of the SNES method.
1495534ebe21SPeter Brune 
1496534ebe21SPeter Brune    Logically Collective on SNES
1497534ebe21SPeter Brune 
1498534ebe21SPeter Brune    Input Parameters:
1499534ebe21SPeter Brune +  snes - the SNES context
1500534ebe21SPeter Brune -  normtype - the type of the norm used
1501534ebe21SPeter Brune 
1502534ebe21SPeter Brune    Notes:
1503534ebe21SPeter Brune    Only certain SNES methods support certain SNESNormTypes.  Most require evaluation
1504534ebe21SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
1505534ebe21SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1506534ebe21SPeter Brune    (SNESGS) and the like do not require the norm of the function to be computed, and therfore
1507534ebe21SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
1508534ebe21SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
1509534ebe21SPeter Brune    their solution.
1510534ebe21SPeter Brune 
1511534ebe21SPeter Brune    Level: developer
1512534ebe21SPeter Brune 
1513534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1514534ebe21SPeter Brune 
1515534ebe21SPeter Brune .seealso: SNESGetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType
1516534ebe21SPeter Brune @*/
1517534ebe21SPeter Brune PetscErrorCode  SNESSetNormType(SNES snes, SNESNormType normtype)
1518534ebe21SPeter Brune {
1519534ebe21SPeter Brune   PetscFunctionBegin;
1520534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1521534ebe21SPeter Brune   snes->normtype = normtype;
1522534ebe21SPeter Brune   PetscFunctionReturn(0);
1523534ebe21SPeter Brune }
1524534ebe21SPeter Brune 
1525534ebe21SPeter Brune 
1526534ebe21SPeter Brune #undef __FUNCT__
1527534ebe21SPeter Brune #define __FUNCT__ "SNESGetNormType"
1528534ebe21SPeter Brune /*@
1529534ebe21SPeter Brune    SNESGetNormType - Gets the SNESNormType used in covergence and monitoring
1530534ebe21SPeter Brune    of the SNES method.
1531534ebe21SPeter Brune 
1532534ebe21SPeter Brune    Logically Collective on SNES
1533534ebe21SPeter Brune 
1534534ebe21SPeter Brune    Input Parameters:
1535534ebe21SPeter Brune +  snes - the SNES context
1536534ebe21SPeter Brune -  normtype - the type of the norm used
1537534ebe21SPeter Brune 
1538534ebe21SPeter Brune    Level: advanced
1539534ebe21SPeter Brune 
1540534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1541534ebe21SPeter Brune 
1542534ebe21SPeter Brune .seealso: SNESSetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType
1543534ebe21SPeter Brune @*/
1544534ebe21SPeter Brune PetscErrorCode  SNESGetNormType(SNES snes, SNESNormType *normtype)
1545534ebe21SPeter Brune {
1546534ebe21SPeter Brune   PetscFunctionBegin;
1547534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1548534ebe21SPeter Brune   *normtype = snes->normtype;
1549534ebe21SPeter Brune   PetscFunctionReturn(0);
1550534ebe21SPeter Brune }
1551534ebe21SPeter Brune 
1552534ebe21SPeter Brune #undef __FUNCT__
1553646217ecSPeter Brune #define __FUNCT__ "SNESSetGS"
1554c79ef259SPeter Brune /*@C
1555c79ef259SPeter Brune    SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for
1556c79ef259SPeter Brune    use with composed nonlinear solvers.
1557c79ef259SPeter Brune 
1558c79ef259SPeter Brune    Input Parameters:
1559c79ef259SPeter Brune +  snes   - the SNES context
1560c79ef259SPeter Brune .  gsfunc - function evaluation routine
1561c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
1562c79ef259SPeter Brune             smoother evaluation routine (may be PETSC_NULL)
1563c79ef259SPeter Brune 
1564c79ef259SPeter Brune    Calling sequence of func:
1565c79ef259SPeter Brune $    func (SNES snes,Vec x,Vec b,void *ctx);
1566c79ef259SPeter Brune 
1567c79ef259SPeter Brune +  X   - solution vector
1568c79ef259SPeter Brune .  B   - RHS vector
1569d28543b3SPeter Brune -  ctx - optional user-defined Gauss-Seidel context
1570c79ef259SPeter Brune 
1571c79ef259SPeter Brune    Notes:
1572c79ef259SPeter Brune    The GS routines are used by the composed nonlinear solver to generate
1573c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
1574c79ef259SPeter Brune 
1575d28543b3SPeter Brune    Level: intermediate
1576c79ef259SPeter Brune 
1577d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel
1578c79ef259SPeter Brune 
1579c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS()
1580c79ef259SPeter Brune @*/
15816cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx)
15826cab3a1bSJed Brown {
15836cab3a1bSJed Brown   PetscErrorCode ierr;
15846cab3a1bSJed Brown   DM dm;
15856cab3a1bSJed Brown 
1586646217ecSPeter Brune   PetscFunctionBegin;
15876cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15886cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
15896cab3a1bSJed Brown   ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr);
1590646217ecSPeter Brune   PetscFunctionReturn(0);
1591646217ecSPeter Brune }
1592646217ecSPeter Brune 
1593d25893d9SBarry Smith #undef __FUNCT__
159489b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps"
159589b92e6fSPeter Brune /*@
159689b92e6fSPeter Brune    SNESSetGSSweeps - Sets the number of sweeps of GS to use.
159789b92e6fSPeter Brune 
159889b92e6fSPeter Brune    Input Parameters:
159989b92e6fSPeter Brune +  snes   - the SNES context
160089b92e6fSPeter Brune -  sweeps  - the number of sweeps of GS to perform.
160189b92e6fSPeter Brune 
160289b92e6fSPeter Brune    Level: intermediate
160389b92e6fSPeter Brune 
160489b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
160589b92e6fSPeter Brune 
160689b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps()
160789b92e6fSPeter Brune @*/
160889b92e6fSPeter Brune 
160989b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) {
161089b92e6fSPeter Brune   PetscFunctionBegin;
161189b92e6fSPeter Brune   snes->gssweeps = sweeps;
161289b92e6fSPeter Brune   PetscFunctionReturn(0);
161389b92e6fSPeter Brune }
161489b92e6fSPeter Brune 
161589b92e6fSPeter Brune 
161689b92e6fSPeter Brune #undef __FUNCT__
161789b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps"
161889b92e6fSPeter Brune /*@
161989b92e6fSPeter Brune    SNESGetGSSweeps - Gets the number of sweeps GS will use.
162089b92e6fSPeter Brune 
162189b92e6fSPeter Brune    Input Parameters:
162289b92e6fSPeter Brune .  snes   - the SNES context
162389b92e6fSPeter Brune 
162489b92e6fSPeter Brune    Output Parameters:
162589b92e6fSPeter Brune .  sweeps  - the number of sweeps of GS to perform.
162689b92e6fSPeter Brune 
162789b92e6fSPeter Brune    Level: intermediate
162889b92e6fSPeter Brune 
162989b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
163089b92e6fSPeter Brune 
163189b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps()
163289b92e6fSPeter Brune @*/
163389b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) {
163489b92e6fSPeter Brune   PetscFunctionBegin;
163589b92e6fSPeter Brune   *sweeps = snes->gssweeps;
163689b92e6fSPeter Brune   PetscFunctionReturn(0);
163789b92e6fSPeter Brune }
163889b92e6fSPeter Brune 
163989b92e6fSPeter Brune #undef __FUNCT__
16408b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction"
16418b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
16428b0a5094SBarry Smith {
16438b0a5094SBarry Smith   PetscErrorCode ierr;
1644e03ab78fSPeter Brune   DM dm;
1645e03ab78fSPeter Brune   SNESDM sdm;
16466cab3a1bSJed Brown 
16478b0a5094SBarry Smith   PetscFunctionBegin;
1648e03ab78fSPeter Brune   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1649e03ab78fSPeter Brune   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
16508b0a5094SBarry Smith   /*  A(x)*x - b(x) */
1651e03ab78fSPeter Brune   if (sdm->computepfunction) {
1652e03ab78fSPeter Brune     ierr = (*sdm->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr);
1653e03ab78fSPeter Brune   } else if (snes->dm) {
1654e03ab78fSPeter Brune     ierr = DMComputeFunction(snes->dm,x,f);CHKERRQ(ierr);
1655e03ab78fSPeter Brune   } else {
1656e03ab78fSPeter Brune     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() or SNESSetDM() before SNESPicardComputeFunction to provide Picard function.");
1657e03ab78fSPeter Brune   }
1658e03ab78fSPeter Brune 
1659e03ab78fSPeter Brune   if (sdm->computepjacobian) {
1660e03ab78fSPeter Brune     ierr = (*sdm->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,sdm->pctx);CHKERRQ(ierr);
1661e03ab78fSPeter Brune   } else if (snes->dm) {
1662e03ab78fSPeter Brune     ierr = DMComputeJacobian(snes->dm,x,snes->jacobian,snes->jacobian_pre,&snes->matstruct);CHKERRQ(ierr);
1663e03ab78fSPeter Brune   } else {
1664e03ab78fSPeter Brune     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() or SNESSetDM() before SNESPicardComputeFunction to provide Picard matrix.");
1665e03ab78fSPeter Brune   }
1666e03ab78fSPeter Brune 
16678b0a5094SBarry Smith   ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
16688b0a5094SBarry Smith   ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
16698b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
16708b0a5094SBarry Smith   ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr);
16718b0a5094SBarry Smith   PetscFunctionReturn(0);
16728b0a5094SBarry Smith }
16738b0a5094SBarry Smith 
16748b0a5094SBarry Smith #undef __FUNCT__
16758b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian"
16768b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
16778b0a5094SBarry Smith {
16788b0a5094SBarry Smith   PetscFunctionBegin;
1679e03ab78fSPeter Brune   /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */
16808b0a5094SBarry Smith   *flag = snes->matstruct;
16818b0a5094SBarry Smith   PetscFunctionReturn(0);
16828b0a5094SBarry Smith }
16838b0a5094SBarry Smith 
16848b0a5094SBarry Smith #undef __FUNCT__
16858b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard"
16868b0a5094SBarry Smith /*@C
16870d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
16888b0a5094SBarry Smith 
16898b0a5094SBarry Smith    Logically Collective on SNES
16908b0a5094SBarry Smith 
16918b0a5094SBarry Smith    Input Parameters:
16928b0a5094SBarry Smith +  snes - the SNES context
16938b0a5094SBarry Smith .  r - vector to store function value
16948b0a5094SBarry Smith .  func - function evaluation routine
16958b0a5094SBarry 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)
16968b0a5094SBarry Smith .  mat - matrix to store A
16978b0a5094SBarry Smith .  mfunc  - function to compute matrix value
16988b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
16998b0a5094SBarry Smith          function evaluation routine (may be PETSC_NULL)
17008b0a5094SBarry Smith 
17018b0a5094SBarry Smith    Calling sequence of func:
17028b0a5094SBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
17038b0a5094SBarry Smith 
17048b0a5094SBarry Smith +  f - function vector
17058b0a5094SBarry Smith -  ctx - optional user-defined function context
17068b0a5094SBarry Smith 
17078b0a5094SBarry Smith    Calling sequence of mfunc:
17088b0a5094SBarry Smith $     mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx);
17098b0a5094SBarry Smith 
17108b0a5094SBarry Smith +  x - input vector
17118b0a5094SBarry 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(),
17128b0a5094SBarry Smith           normally just pass mat in this location
17138b0a5094SBarry Smith .  mat - form A(x) matrix
17148b0a5094SBarry Smith .  flag - flag indicating information about the preconditioner matrix
17158b0a5094SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
17168b0a5094SBarry Smith -  ctx - [optional] user-defined Jacobian context
17178b0a5094SBarry Smith 
17188b0a5094SBarry Smith    Notes:
17198b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
17208b0a5094SBarry Smith 
17218b0a5094SBarry 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}
17228b0a5094SBarry 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.
17238b0a5094SBarry Smith 
17248b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
17258b0a5094SBarry Smith 
17260d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
17270d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
17288b0a5094SBarry Smith 
17298b0a5094SBarry 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
17308b0a5094SBarry 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
17318b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
17328b0a5094SBarry Smith 
17338b0a5094SBarry Smith    Level: beginner
17348b0a5094SBarry Smith 
17358b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function
17368b0a5094SBarry Smith 
17370d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard()
17388b0a5094SBarry Smith @*/
17398b0a5094SBarry 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)
17408b0a5094SBarry Smith {
17418b0a5094SBarry Smith   PetscErrorCode ierr;
1742e03ab78fSPeter Brune   DM             dm;
1743e03ab78fSPeter Brune 
17448b0a5094SBarry Smith   PetscFunctionBegin;
17458b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1746e03ab78fSPeter Brune   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
1747e03ab78fSPeter Brune   ierr = DMSNESSetPicard(dm,func,mfunc,ctx);CHKERRQ(ierr);
17488b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
17498b0a5094SBarry Smith   ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
17508b0a5094SBarry Smith   PetscFunctionReturn(0);
17518b0a5094SBarry Smith }
17528b0a5094SBarry Smith 
17537971a8bfSPeter Brune 
17547971a8bfSPeter Brune #undef __FUNCT__
17557971a8bfSPeter Brune #define __FUNCT__ "SNESGetPicard"
17567971a8bfSPeter Brune /*@C
17577971a8bfSPeter Brune    SNESGetPicard - Returns the context for the Picard iteration
17587971a8bfSPeter Brune 
17597971a8bfSPeter Brune    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
17607971a8bfSPeter Brune 
17617971a8bfSPeter Brune    Input Parameter:
17627971a8bfSPeter Brune .  snes - the SNES context
17637971a8bfSPeter Brune 
17647971a8bfSPeter Brune    Output Parameter:
17657971a8bfSPeter Brune +  r - the function (or PETSC_NULL)
17667971a8bfSPeter Brune .  func - the function (or PETSC_NULL)
17677971a8bfSPeter Brune .  jmat - the picard matrix (or PETSC_NULL)
17687971a8bfSPeter Brune .  mat  - the picard preconditioner matrix (or PETSC_NULL)
17697971a8bfSPeter Brune .  mfunc - the function for matrix evaluation (or PETSC_NULL)
17707971a8bfSPeter Brune -  ctx - the function context (or PETSC_NULL)
17717971a8bfSPeter Brune 
17727971a8bfSPeter Brune    Level: advanced
17737971a8bfSPeter Brune 
17747971a8bfSPeter Brune .keywords: SNES, nonlinear, get, function
17757971a8bfSPeter Brune 
17767971a8bfSPeter Brune .seealso: SNESSetPicard, SNESGetFunction, SNESGetJacobian, SNESGetDM
17777971a8bfSPeter Brune @*/
17787971a8bfSPeter 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)
17797971a8bfSPeter Brune {
17807971a8bfSPeter Brune   PetscErrorCode ierr;
17817971a8bfSPeter Brune   DM             dm;
17827971a8bfSPeter Brune 
17837971a8bfSPeter Brune   PetscFunctionBegin;
17847971a8bfSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
17857971a8bfSPeter Brune   ierr = SNESGetFunction(snes,r,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
17867971a8bfSPeter Brune   ierr = SNESGetJacobian(snes,jmat,mat,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
17877971a8bfSPeter Brune   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
17887971a8bfSPeter Brune   ierr = DMSNESGetPicard(dm,func,mfunc,ctx);CHKERRQ(ierr);
17897971a8bfSPeter Brune   PetscFunctionReturn(0);
17907971a8bfSPeter Brune }
17917971a8bfSPeter Brune 
17928b0a5094SBarry Smith #undef __FUNCT__
1793d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess"
1794d25893d9SBarry Smith /*@C
1795d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1796d25893d9SBarry Smith 
1797d25893d9SBarry Smith    Logically Collective on SNES
1798d25893d9SBarry Smith 
1799d25893d9SBarry Smith    Input Parameters:
1800d25893d9SBarry Smith +  snes - the SNES context
1801d25893d9SBarry Smith .  func - function evaluation routine
1802d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
1803d25893d9SBarry Smith          function evaluation routine (may be PETSC_NULL)
1804d25893d9SBarry Smith 
1805d25893d9SBarry Smith    Calling sequence of func:
1806d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
1807d25893d9SBarry Smith 
1808d25893d9SBarry Smith .  f - function vector
1809d25893d9SBarry Smith -  ctx - optional user-defined function context
1810d25893d9SBarry Smith 
1811d25893d9SBarry Smith    Level: intermediate
1812d25893d9SBarry Smith 
1813d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
1814d25893d9SBarry Smith 
1815d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1816d25893d9SBarry Smith @*/
1817d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1818d25893d9SBarry Smith {
1819d25893d9SBarry Smith   PetscFunctionBegin;
1820d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1821d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
1822d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
1823d25893d9SBarry Smith   PetscFunctionReturn(0);
1824d25893d9SBarry Smith }
1825d25893d9SBarry Smith 
18263ab0aad5SBarry Smith /* --------------------------------------------------------------- */
18273ab0aad5SBarry Smith #undef __FUNCT__
18281096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
18291096aae1SMatthew Knepley /*@C
18301096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
18311096aae1SMatthew Knepley    it assumes a zero right hand side.
18321096aae1SMatthew Knepley 
18333f9fe445SBarry Smith    Logically Collective on SNES
18341096aae1SMatthew Knepley 
18351096aae1SMatthew Knepley    Input Parameter:
18361096aae1SMatthew Knepley .  snes - the SNES context
18371096aae1SMatthew Knepley 
18381096aae1SMatthew Knepley    Output Parameter:
1839bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
18401096aae1SMatthew Knepley 
18411096aae1SMatthew Knepley    Level: intermediate
18421096aae1SMatthew Knepley 
18431096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
18441096aae1SMatthew Knepley 
184585385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
18461096aae1SMatthew Knepley @*/
18477087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
18481096aae1SMatthew Knepley {
18491096aae1SMatthew Knepley   PetscFunctionBegin;
18500700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
18511096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
185285385478SLisandro Dalcin   *rhs = snes->vec_rhs;
18531096aae1SMatthew Knepley   PetscFunctionReturn(0);
18541096aae1SMatthew Knepley }
18551096aae1SMatthew Knepley 
18561096aae1SMatthew Knepley #undef __FUNCT__
18574a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
18589b94acceSBarry Smith /*@
185936851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
18609b94acceSBarry Smith                          SNESSetFunction().
18619b94acceSBarry Smith 
1862c7afd0dbSLois Curfman McInnes    Collective on SNES
1863c7afd0dbSLois Curfman McInnes 
18649b94acceSBarry Smith    Input Parameters:
1865c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1866c7afd0dbSLois Curfman McInnes -  x - input vector
18679b94acceSBarry Smith 
18689b94acceSBarry Smith    Output Parameter:
18693638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
18709b94acceSBarry Smith 
18711bffabb2SLois Curfman McInnes    Notes:
187236851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
187336851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
187436851e7fSLois Curfman McInnes    themselves.
187536851e7fSLois Curfman McInnes 
187636851e7fSLois Curfman McInnes    Level: developer
187736851e7fSLois Curfman McInnes 
18789b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
18799b94acceSBarry Smith 
1880a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
18819b94acceSBarry Smith @*/
18827087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
18839b94acceSBarry Smith {
1884dfbe8321SBarry Smith   PetscErrorCode ierr;
18856cab3a1bSJed Brown   DM             dm;
18866cab3a1bSJed Brown   SNESDM         sdm;
18879b94acceSBarry Smith 
18883a40ed3dSBarry Smith   PetscFunctionBegin;
18890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
18900700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
18910700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
1892c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
1893c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
18944ec14c9cSBarry Smith   VecValidValues(x,2,PETSC_TRUE);
1895184914b5SBarry Smith 
18966cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
18976cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
1898d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
18996cab3a1bSJed Brown   if (sdm->computefunction) {
1900d64ed03dSBarry Smith     PetscStackPush("SNES user function");
19016cab3a1bSJed Brown     ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
1902d64ed03dSBarry Smith     PetscStackPop;
190373250ac0SBarry Smith   } else if (snes->dm) {
1904644e2e5bSBarry Smith     ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr);
1905c90fad12SPeter Brune   } else if (snes->vec_rhs) {
1906c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
1907644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
190885385478SLisandro Dalcin   if (snes->vec_rhs) {
190985385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
19103ab0aad5SBarry Smith   }
1911ae3c334cSLois Curfman McInnes   snes->nfuncs++;
1912d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
19134ec14c9cSBarry Smith   VecValidValues(y,3,PETSC_FALSE);
19143a40ed3dSBarry Smith   PetscFunctionReturn(0);
19159b94acceSBarry Smith }
19169b94acceSBarry Smith 
19174a2ae208SSatish Balay #undef __FUNCT__
1918646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS"
1919c79ef259SPeter Brune /*@
1920c79ef259SPeter Brune    SNESComputeGS - Calls the Gauss-Seidel function that has been set with
1921c79ef259SPeter Brune                    SNESSetGS().
1922c79ef259SPeter Brune 
1923c79ef259SPeter Brune    Collective on SNES
1924c79ef259SPeter Brune 
1925c79ef259SPeter Brune    Input Parameters:
1926c79ef259SPeter Brune +  snes - the SNES context
1927c79ef259SPeter Brune .  x - input vector
1928c79ef259SPeter Brune -  b - rhs vector
1929c79ef259SPeter Brune 
1930c79ef259SPeter Brune    Output Parameter:
1931c79ef259SPeter Brune .  x - new solution vector
1932c79ef259SPeter Brune 
1933c79ef259SPeter Brune    Notes:
1934c79ef259SPeter Brune    SNESComputeGS() is typically used within composed nonlinear solver
1935c79ef259SPeter Brune    implementations, so most users would not generally call this routine
1936c79ef259SPeter Brune    themselves.
1937c79ef259SPeter Brune 
1938c79ef259SPeter Brune    Level: developer
1939c79ef259SPeter Brune 
1940c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function
1941c79ef259SPeter Brune 
1942c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction()
1943c79ef259SPeter Brune @*/
1944646217ecSPeter Brune PetscErrorCode  SNESComputeGS(SNES snes,Vec b,Vec x)
1945646217ecSPeter Brune {
1946646217ecSPeter Brune   PetscErrorCode ierr;
194789b92e6fSPeter Brune   PetscInt i;
19486cab3a1bSJed Brown   DM dm;
19496cab3a1bSJed Brown   SNESDM sdm;
1950646217ecSPeter Brune 
1951646217ecSPeter Brune   PetscFunctionBegin;
1952646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1953646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
1954646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
1955646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
1956646217ecSPeter Brune   if(b) PetscCheckSameComm(snes,1,b,3);
19574ec14c9cSBarry Smith   if (b) VecValidValues(b,2,PETSC_TRUE);
1958701cf23dSPeter Brune   ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
19596cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
19606cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
19616cab3a1bSJed Brown   if (sdm->computegs) {
196289b92e6fSPeter Brune     for (i = 0; i < snes->gssweeps; i++) {
1963646217ecSPeter Brune       PetscStackPush("SNES user GS");
19646cab3a1bSJed Brown       ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
1965646217ecSPeter Brune       PetscStackPop;
196689b92e6fSPeter Brune     }
1967646217ecSPeter Brune   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve().");
1968701cf23dSPeter Brune   ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
19694ec14c9cSBarry Smith   VecValidValues(x,3,PETSC_FALSE);
1970646217ecSPeter Brune   PetscFunctionReturn(0);
1971646217ecSPeter Brune }
1972646217ecSPeter Brune 
1973646217ecSPeter Brune 
1974646217ecSPeter Brune #undef __FUNCT__
19754a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
197662fef451SLois Curfman McInnes /*@
197762fef451SLois Curfman McInnes    SNESComputeJacobian - Computes the Jacobian matrix that has been
197862fef451SLois Curfman McInnes    set with SNESSetJacobian().
197962fef451SLois Curfman McInnes 
1980c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
1981c7afd0dbSLois Curfman McInnes 
198262fef451SLois Curfman McInnes    Input Parameters:
1983c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1984c7afd0dbSLois Curfman McInnes -  x - input vector
198562fef451SLois Curfman McInnes 
198662fef451SLois Curfman McInnes    Output Parameters:
1987c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
198862fef451SLois Curfman McInnes .  B - optional preconditioning matrix
19892b668275SBarry Smith -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1990fee21e36SBarry Smith 
1991e35cf81dSBarry Smith   Options Database Keys:
1992e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
1993693365a8SJed Brown .    -snes_lag_jacobian <lag>
1994693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
1995693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
1996693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
19974c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
1998c01495d3SJed Brown .    -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference
1999c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
2000c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
2001c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
2002c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
20034c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
2004c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
2005c01495d3SJed Brown 
2006e35cf81dSBarry Smith 
200762fef451SLois Curfman McInnes    Notes:
200862fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
200962fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
201062fef451SLois Curfman McInnes 
201194b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the
2012dc5a77f8SLois Curfman McInnes    flag parameter.
201362fef451SLois Curfman McInnes 
201436851e7fSLois Curfman McInnes    Level: developer
201536851e7fSLois Curfman McInnes 
201662fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
201762fef451SLois Curfman McInnes 
2018e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
201962fef451SLois Curfman McInnes @*/
20207087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
20219b94acceSBarry Smith {
2022dfbe8321SBarry Smith   PetscErrorCode ierr;
2023ace3abfcSBarry Smith   PetscBool      flag;
20246cab3a1bSJed Brown   DM             dm;
20256cab3a1bSJed Brown   SNESDM         sdm;
20263a40ed3dSBarry Smith 
20273a40ed3dSBarry Smith   PetscFunctionBegin;
20280700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
20290700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
20304482741eSBarry Smith   PetscValidPointer(flg,5);
2031c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
20324ec14c9cSBarry Smith   VecValidValues(X,2,PETSC_TRUE);
20336cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
20346cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
20356cab3a1bSJed Brown   if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
2036ebd3b9afSBarry Smith 
2037ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
2038ebd3b9afSBarry Smith 
2039fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
2040fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
2041fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
2042fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
2043e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
2044e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
2045251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
2046ebd3b9afSBarry Smith     if (flag) {
2047ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2048ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2049ebd3b9afSBarry Smith     }
2050e35cf81dSBarry Smith     PetscFunctionReturn(0);
2051e35cf81dSBarry Smith   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
2052e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
2053e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
2054251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
2055ebd3b9afSBarry Smith     if (flag) {
2056ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2057ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2058ebd3b9afSBarry Smith     }
2059e35cf81dSBarry Smith     PetscFunctionReturn(0);
2060e35cf81dSBarry Smith   }
2061e35cf81dSBarry Smith 
2062c4fc05e7SBarry Smith   *flg = DIFFERENT_NONZERO_PATTERN;
2063e35cf81dSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
2064d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
20656cab3a1bSJed Brown   ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr);
2066d64ed03dSBarry Smith   PetscStackPop;
2067d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
2068a8054027SBarry Smith 
20693b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
20703b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
20713b4f5425SBarry Smith     snes->lagpreconditioner = -1;
20723b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
2073a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
2074a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
2075a8054027SBarry Smith   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
2076a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
2077a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
2078a8054027SBarry Smith   }
2079a8054027SBarry Smith 
20806d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
20810700a824SBarry Smith   /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
20820700a824SBarry Smith     PetscValidHeaderSpecific(*B,MAT_CLASSID,4);   */
2083693365a8SJed Brown   {
2084693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
2085693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr);
2086693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
2087693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
2088693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr);
2089693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
2090693365a8SJed Brown       Mat Bexp_mine = PETSC_NULL,Bexp,FDexp;
2091693365a8SJed Brown       MatStructure mstruct;
2092693365a8SJed Brown       PetscViewer vdraw,vstdout;
20936b3a5b13SJed Brown       PetscBool flg;
2094693365a8SJed Brown       if (flag_operator) {
2095693365a8SJed Brown         ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr);
2096693365a8SJed Brown         Bexp = Bexp_mine;
2097693365a8SJed Brown       } else {
2098693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
2099251f4c67SDmitry Karpeev         ierr = PetscObjectTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
2100693365a8SJed Brown         if (flg) Bexp = *B;
2101693365a8SJed Brown         else {
2102693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
2103693365a8SJed Brown           ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr);
2104693365a8SJed Brown           Bexp = Bexp_mine;
2105693365a8SJed Brown         }
2106693365a8SJed Brown       }
2107693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
2108693365a8SJed Brown       ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr);
2109693365a8SJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
2110693365a8SJed Brown       if (flag_draw || flag_contour) {
2111693365a8SJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
2112693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
2113693365a8SJed Brown       } else vdraw = PETSC_NULL;
2114693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr);
2115693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
2116693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
2117693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
2118693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2119693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
2120693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2121693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
2122693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2123693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
2124693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
2125693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
2126693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
2127693365a8SJed Brown       }
2128693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
2129693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
2130693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
2131693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
2132693365a8SJed Brown     }
2133693365a8SJed Brown   }
21344c30e9fbSJed Brown   {
21356719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
21366719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
21374c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr);
21386719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr);
21394c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
21404c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
21416719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr);
21426719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr);
21436719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr);
21446719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
21454c30e9fbSJed Brown       Mat Bfd;
21464c30e9fbSJed Brown       MatStructure mstruct;
21474c30e9fbSJed Brown       PetscViewer vdraw,vstdout;
21484c30e9fbSJed Brown       ISColoring iscoloring;
21494c30e9fbSJed Brown       MatFDColoring matfdcoloring;
21504c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
21514c30e9fbSJed Brown       void *funcctx;
21526719d8e4SJed Brown       PetscReal norm1,norm2,normmax;
21534c30e9fbSJed Brown 
21544c30e9fbSJed Brown       ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
21554c30e9fbSJed Brown       ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
21564c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
21574c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
21584c30e9fbSJed Brown 
21594c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
21604c30e9fbSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr);
21614c30e9fbSJed Brown         ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr);
21624c30e9fbSJed Brown         ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
21634c30e9fbSJed Brown         ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
21644c30e9fbSJed Brown         ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
21654c30e9fbSJed Brown         ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr);
21664c30e9fbSJed Brown         ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
21674c30e9fbSJed Brown 
21684c30e9fbSJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
21694c30e9fbSJed Brown       if (flag_draw || flag_contour) {
21704c30e9fbSJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
21714c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
21724c30e9fbSJed Brown       } else vdraw = PETSC_NULL;
21734c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
21746719d8e4SJed Brown       if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);}
21754c30e9fbSJed Brown       if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);}
21764c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
21776719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
21784c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
21794c30e9fbSJed Brown       ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
21804c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
21816719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
21824c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
21836719d8e4SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr);
21846719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
21854c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
21864c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
21874c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
21884c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
21894c30e9fbSJed Brown       }
21904c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
21916719d8e4SJed Brown 
21926719d8e4SJed Brown       if (flag_threshold) {
21936719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
21946719d8e4SJed Brown         ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr);
21956719d8e4SJed Brown         ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr);
21966719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
21976719d8e4SJed Brown           const PetscScalar *ba,*ca;
21986719d8e4SJed Brown           const PetscInt *bj,*cj;
21996719d8e4SJed Brown           PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
22006719d8e4SJed Brown           PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0;
22016719d8e4SJed Brown           ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
22026719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
22036719d8e4SJed Brown           if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
22046719d8e4SJed Brown           for (j=0; j<bn; j++) {
22056719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
22066719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
22076719d8e4SJed Brown               maxentrycol = bj[j];
22086719d8e4SJed Brown               maxentry = PetscRealPart(ba[j]);
22096719d8e4SJed Brown             }
22106719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
22116719d8e4SJed Brown               maxdiffcol = bj[j];
22126719d8e4SJed Brown               maxdiff = PetscRealPart(ca[j]);
22136719d8e4SJed Brown             }
22146719d8e4SJed Brown             if (rdiff > maxrdiff) {
22156719d8e4SJed Brown               maxrdiffcol = bj[j];
22166719d8e4SJed Brown               maxrdiff = rdiff;
22176719d8e4SJed Brown             }
22186719d8e4SJed Brown           }
22196719d8e4SJed Brown           if (maxrdiff > 1) {
22206719d8e4SJed 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);
22216719d8e4SJed Brown             for (j=0; j<bn; j++) {
22226719d8e4SJed Brown               PetscReal rdiff;
22236719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
22246719d8e4SJed Brown               if (rdiff > 1) {
22256719d8e4SJed Brown                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr);
22266719d8e4SJed Brown               }
22276719d8e4SJed Brown             }
22286719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
22296719d8e4SJed Brown           }
22306719d8e4SJed Brown           ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
22316719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
22326719d8e4SJed Brown         }
22336719d8e4SJed Brown       }
22344c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
22354c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
22364c30e9fbSJed Brown     }
22374c30e9fbSJed Brown   }
22383a40ed3dSBarry Smith   PetscFunctionReturn(0);
22399b94acceSBarry Smith }
22409b94acceSBarry Smith 
22414a2ae208SSatish Balay #undef __FUNCT__
22424a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
22439b94acceSBarry Smith /*@C
22449b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2245044dda88SLois Curfman McInnes    location to store the matrix.
22469b94acceSBarry Smith 
22473f9fe445SBarry Smith    Logically Collective on SNES and Mat
2248c7afd0dbSLois Curfman McInnes 
22499b94acceSBarry Smith    Input Parameters:
2250c7afd0dbSLois Curfman McInnes +  snes - the SNES context
22519b94acceSBarry Smith .  A - Jacobian matrix
22529b94acceSBarry Smith .  B - preconditioner matrix (usually same as the Jacobian)
2253efd51863SBarry Smith .  func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value)
2254c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
2255efd51863SBarry Smith          Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value)
22569b94acceSBarry Smith 
22579b94acceSBarry Smith    Calling sequence of func:
22588d76a1e5SLois Curfman McInnes $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
22599b94acceSBarry Smith 
2260c7afd0dbSLois Curfman McInnes +  x - input vector
22619b94acceSBarry Smith .  A - Jacobian matrix
22629b94acceSBarry Smith .  B - preconditioner matrix, usually the same as A
2263ac21db08SLois Curfman McInnes .  flag - flag indicating information about the preconditioner matrix
22642b668275SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
2265c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined Jacobian context
22669b94acceSBarry Smith 
22679b94acceSBarry Smith    Notes:
226894b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the flag
22692cd2dfdcSLois Curfman McInnes    output parameter in the routine func().  Be sure to read this information!
2270ac21db08SLois Curfman McInnes 
2271ac21db08SLois Curfman McInnes    The routine func() takes Mat * as the matrix arguments rather than Mat.
22729b94acceSBarry Smith    This allows the Jacobian evaluation routine to replace A and/or B with a
22739b94acceSBarry Smith    completely new new matrix structure (not just different matrix elements)
22749b94acceSBarry Smith    when appropriate, for instance, if the nonzero structure is changing
22759b94acceSBarry Smith    throughout the global iterations.
22769b94acceSBarry Smith 
227716913363SBarry Smith    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
227816913363SBarry Smith    each matrix.
227916913363SBarry Smith 
2280a8a26c1eSJed Brown    If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument
2281a8a26c1eSJed Brown    must be a MatFDColoring.
2282a8a26c1eSJed Brown 
2283c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2284c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2285c3cc8fd1SJed Brown 
228636851e7fSLois Curfman McInnes    Level: beginner
228736851e7fSLois Curfman McInnes 
22889b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
22899b94acceSBarry Smith 
22903ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
22919b94acceSBarry Smith @*/
22927087cfbeSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
22939b94acceSBarry Smith {
2294dfbe8321SBarry Smith   PetscErrorCode ierr;
22956cab3a1bSJed Brown   DM             dm;
22963a7fca6bSBarry Smith 
22973a40ed3dSBarry Smith   PetscFunctionBegin;
22980700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
22990700a824SBarry Smith   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
23000700a824SBarry Smith   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
2301c9780b6fSBarry Smith   if (A) PetscCheckSameComm(snes,1,A,2);
230206975374SJed Brown   if (B) PetscCheckSameComm(snes,1,B,3);
23036cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
23046cab3a1bSJed Brown   ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr);
23053a7fca6bSBarry Smith   if (A) {
23067dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
23076bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
23089b94acceSBarry Smith     snes->jacobian = A;
23093a7fca6bSBarry Smith   }
23103a7fca6bSBarry Smith   if (B) {
23117dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
23126bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
23139b94acceSBarry Smith     snes->jacobian_pre = B;
23143a7fca6bSBarry Smith   }
23153a40ed3dSBarry Smith   PetscFunctionReturn(0);
23169b94acceSBarry Smith }
231762fef451SLois Curfman McInnes 
23184a2ae208SSatish Balay #undef __FUNCT__
23194a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
2320c2aafc4cSSatish Balay /*@C
2321b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2322b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2323b4fd4287SBarry Smith 
2324c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2325c7afd0dbSLois Curfman McInnes 
2326b4fd4287SBarry Smith    Input Parameter:
2327b4fd4287SBarry Smith .  snes - the nonlinear solver context
2328b4fd4287SBarry Smith 
2329b4fd4287SBarry Smith    Output Parameters:
2330c7afd0dbSLois Curfman McInnes +  A - location to stash Jacobian matrix (or PETSC_NULL)
2331b4fd4287SBarry Smith .  B - location to stash preconditioner matrix (or PETSC_NULL)
233270e92668SMatthew Knepley .  func - location to put Jacobian function (or PETSC_NULL)
233370e92668SMatthew Knepley -  ctx - location to stash Jacobian ctx (or PETSC_NULL)
2334fee21e36SBarry Smith 
233536851e7fSLois Curfman McInnes    Level: advanced
233636851e7fSLois Curfman McInnes 
2337b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian()
2338b4fd4287SBarry Smith @*/
23397087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
2340b4fd4287SBarry Smith {
23416cab3a1bSJed Brown   PetscErrorCode ierr;
23426cab3a1bSJed Brown   DM             dm;
23436cab3a1bSJed Brown   SNESDM         sdm;
23446cab3a1bSJed Brown 
23453a40ed3dSBarry Smith   PetscFunctionBegin;
23460700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2347b4fd4287SBarry Smith   if (A)    *A    = snes->jacobian;
2348b4fd4287SBarry Smith   if (B)    *B    = snes->jacobian_pre;
23496cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
23506cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
23516cab3a1bSJed Brown   if (func) *func = sdm->computejacobian;
23526cab3a1bSJed Brown   if (ctx)  *ctx  = sdm->jacobianctx;
23533a40ed3dSBarry Smith   PetscFunctionReturn(0);
2354b4fd4287SBarry Smith }
2355b4fd4287SBarry Smith 
23569b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
23579b94acceSBarry Smith 
23584a2ae208SSatish Balay #undef __FUNCT__
23594a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
23609b94acceSBarry Smith /*@
23619b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
2362272ac6f2SLois Curfman McInnes    of a nonlinear solver.
23639b94acceSBarry Smith 
2364fee21e36SBarry Smith    Collective on SNES
2365fee21e36SBarry Smith 
2366c7afd0dbSLois Curfman McInnes    Input Parameters:
236770e92668SMatthew Knepley .  snes - the SNES context
2368c7afd0dbSLois Curfman McInnes 
2369272ac6f2SLois Curfman McInnes    Notes:
2370272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
2371272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
2372272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
2373272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
2374272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
2375272ac6f2SLois Curfman McInnes 
237636851e7fSLois Curfman McInnes    Level: advanced
237736851e7fSLois Curfman McInnes 
23789b94acceSBarry Smith .keywords: SNES, nonlinear, setup
23799b94acceSBarry Smith 
23809b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
23819b94acceSBarry Smith @*/
23827087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
23839b94acceSBarry Smith {
2384dfbe8321SBarry Smith   PetscErrorCode ierr;
23856cab3a1bSJed Brown   DM             dm;
23866cab3a1bSJed Brown   SNESDM         sdm;
23876e2a1849SPeter Brune   SNESLineSearch              linesearch;
23886e2a1849SPeter Brune   SNESLineSearch              pclinesearch;
23896e2a1849SPeter Brune   void                        *lsprectx,*lspostctx;
23906e2a1849SPeter Brune   SNESLineSearchPreCheckFunc  lsprefunc;
23916e2a1849SPeter Brune   SNESLineSearchPostCheckFunc lspostfunc;
23926e2a1849SPeter Brune   PetscErrorCode              (*func)(SNES,Vec,Vec,void*);
23936e2a1849SPeter Brune   Vec                         f,fpc;
23946e2a1849SPeter Brune   void                        *funcctx;
23956e2a1849SPeter Brune   PetscErrorCode              (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*);
23966e2a1849SPeter Brune   void                        *jacctx;
23976e2a1849SPeter Brune   Mat                         A,B;
23983a40ed3dSBarry Smith 
23993a40ed3dSBarry Smith   PetscFunctionBegin;
24000700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
24014dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
24029b94acceSBarry Smith 
24037adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
240485385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
240585385478SLisandro Dalcin   }
240685385478SLisandro Dalcin 
2407a63bb30eSJed Brown   ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
240817186662SBarry Smith   if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
240958c9b817SLisandro Dalcin   if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
241058c9b817SLisandro Dalcin 
241158c9b817SLisandro Dalcin   if (!snes->vec_sol_update /* && snes->vec_sol */) {
241258c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
241358c9b817SLisandro Dalcin     ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr);
241458c9b817SLisandro Dalcin   }
241558c9b817SLisandro Dalcin 
24166cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
24176cab3a1bSJed Brown   ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */
24186cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
24196cab3a1bSJed Brown   if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc");
24206cab3a1bSJed Brown   if (!snes->vec_func) {
24216cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2422214df951SJed Brown   }
2423efd51863SBarry Smith 
2424b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
2425b710008aSBarry Smith 
2426f1c6b773SPeter Brune   if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);}
24279e764e56SPeter Brune 
2428d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
2429d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
2430d25893d9SBarry Smith   }
2431d25893d9SBarry Smith 
24326e2a1849SPeter Brune   if (snes->pc) {
24336e2a1849SPeter Brune     /* copy the DM over */
24346e2a1849SPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
24356e2a1849SPeter Brune     ierr = SNESSetDM(snes->pc,dm);CHKERRQ(ierr);
24366e2a1849SPeter Brune 
24376e2a1849SPeter Brune     /* copy the legacy SNES context not related to the DM over*/
24386e2a1849SPeter Brune     ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr);
24396e2a1849SPeter Brune     ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr);
24406e2a1849SPeter Brune     ierr = SNESSetFunction(snes->pc,fpc,func,funcctx);CHKERRQ(ierr);
24416e2a1849SPeter Brune     ierr = SNESGetJacobian(snes,&A,&B,&jac,&jacctx);CHKERRQ(ierr);
24426e2a1849SPeter Brune     ierr = SNESSetJacobian(snes->pc,A,B,jac,jacctx);CHKERRQ(ierr);
24436e2a1849SPeter Brune     ierr = VecDestroy(&fpc);CHKERRQ(ierr);
24446e2a1849SPeter Brune 
24456e2a1849SPeter Brune     /* copy the function pointers over */
24466e2a1849SPeter Brune     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr);
24476e2a1849SPeter Brune 
24486e2a1849SPeter Brune      /* default to 1 iteration */
2449140836e4SPeter Brune     ierr = SNESSetTolerances(snes->pc, 0.0, 0.0, 0.0, 1, snes->pc->max_funcs);CHKERRQ(ierr);
24506e2a1849SPeter Brune     ierr = SNESSetNormType(snes->pc, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr);
24516e2a1849SPeter Brune     ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr);
24526e2a1849SPeter Brune 
24536e2a1849SPeter Brune     /* copy the line search context over */
24546e2a1849SPeter Brune     ierr = SNESGetSNESLineSearch(snes,&linesearch);CHKERRQ(ierr);
24556e2a1849SPeter Brune     ierr = SNESGetSNESLineSearch(snes->pc,&pclinesearch);CHKERRQ(ierr);
24566e2a1849SPeter Brune     ierr = SNESLineSearchGetPreCheck(linesearch,&lsprefunc,&lsprectx);CHKERRQ(ierr);
24576e2a1849SPeter Brune     ierr = SNESLineSearchGetPostCheck(linesearch,&lspostfunc,&lspostctx);CHKERRQ(ierr);
24586e2a1849SPeter Brune     ierr = SNESLineSearchSetPreCheck(pclinesearch,lsprefunc,lsprectx);CHKERRQ(ierr);
24596e2a1849SPeter Brune     ierr = SNESLineSearchSetPostCheck(pclinesearch,lspostfunc,lspostctx);CHKERRQ(ierr);
24606e2a1849SPeter Brune     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr);
24616e2a1849SPeter Brune   }
24626e2a1849SPeter Brune 
2463410397dcSLisandro Dalcin   if (snes->ops->setup) {
2464410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2465410397dcSLisandro Dalcin   }
246658c9b817SLisandro Dalcin 
24677aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
24683a40ed3dSBarry Smith   PetscFunctionReturn(0);
24699b94acceSBarry Smith }
24709b94acceSBarry Smith 
24714a2ae208SSatish Balay #undef __FUNCT__
247237596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
247337596af1SLisandro Dalcin /*@
247437596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
247537596af1SLisandro Dalcin 
247637596af1SLisandro Dalcin    Collective on SNES
247737596af1SLisandro Dalcin 
247837596af1SLisandro Dalcin    Input Parameter:
247937596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
248037596af1SLisandro Dalcin 
2481d25893d9SBarry Smith    Level: intermediate
2482d25893d9SBarry Smith 
2483d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
248437596af1SLisandro Dalcin 
248537596af1SLisandro Dalcin .keywords: SNES, destroy
248637596af1SLisandro Dalcin 
248737596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
248837596af1SLisandro Dalcin @*/
248937596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
249037596af1SLisandro Dalcin {
249137596af1SLisandro Dalcin   PetscErrorCode ierr;
249237596af1SLisandro Dalcin 
249337596af1SLisandro Dalcin   PetscFunctionBegin;
249437596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2495d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
2496d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
2497d25893d9SBarry Smith     snes->user = PETSC_NULL;
2498d25893d9SBarry Smith   }
24998a23116dSBarry Smith   if (snes->pc) {
25008a23116dSBarry Smith     ierr = SNESReset(snes->pc);CHKERRQ(ierr);
25018a23116dSBarry Smith   }
25028a23116dSBarry Smith 
250337596af1SLisandro Dalcin   if (snes->ops->reset) {
250437596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
250537596af1SLisandro Dalcin   }
25069e764e56SPeter Brune   if (snes->ksp) {
25079e764e56SPeter Brune     ierr = KSPReset(snes->ksp);CHKERRQ(ierr);
25089e764e56SPeter Brune   }
25099e764e56SPeter Brune 
25109e764e56SPeter Brune   if (snes->linesearch) {
2511f1c6b773SPeter Brune     ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr);
25129e764e56SPeter Brune   }
25139e764e56SPeter Brune 
25146bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
25156bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
25166bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
25176bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
25186bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
25196bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2520c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
2521c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
252237596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
252337596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
252437596af1SLisandro Dalcin   PetscFunctionReturn(0);
252537596af1SLisandro Dalcin }
252637596af1SLisandro Dalcin 
252737596af1SLisandro Dalcin #undef __FUNCT__
25284a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
252952baeb72SSatish Balay /*@
25309b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
25319b94acceSBarry Smith    with SNESCreate().
25329b94acceSBarry Smith 
2533c7afd0dbSLois Curfman McInnes    Collective on SNES
2534c7afd0dbSLois Curfman McInnes 
25359b94acceSBarry Smith    Input Parameter:
25369b94acceSBarry Smith .  snes - the SNES context
25379b94acceSBarry Smith 
253836851e7fSLois Curfman McInnes    Level: beginner
253936851e7fSLois Curfman McInnes 
25409b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
25419b94acceSBarry Smith 
254263a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
25439b94acceSBarry Smith @*/
25446bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
25459b94acceSBarry Smith {
25466849ba73SBarry Smith   PetscErrorCode ierr;
25473a40ed3dSBarry Smith 
25483a40ed3dSBarry Smith   PetscFunctionBegin;
25496bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
25506bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
25516bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2552d4bb536fSBarry Smith 
25536bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
25548a23116dSBarry Smith   ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr);
25556b8b9a38SLisandro Dalcin 
2556be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
25576bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
25586bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
25596d4c513bSLisandro Dalcin 
25606bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
25616bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
2562f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr);
25636b8b9a38SLisandro Dalcin 
25646bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
25656bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
25666bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
25676b8b9a38SLisandro Dalcin   }
25686bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
25696bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
25706bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
257158c9b817SLisandro Dalcin   }
25726bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2573a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
25743a40ed3dSBarry Smith  PetscFunctionReturn(0);
25759b94acceSBarry Smith }
25769b94acceSBarry Smith 
25779b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
25789b94acceSBarry Smith 
25794a2ae208SSatish Balay #undef __FUNCT__
2580a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
2581a8054027SBarry Smith /*@
2582a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2583a8054027SBarry Smith 
25843f9fe445SBarry Smith    Logically Collective on SNES
2585a8054027SBarry Smith 
2586a8054027SBarry Smith    Input Parameters:
2587a8054027SBarry Smith +  snes - the SNES context
2588a8054027SBarry 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
25893b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2590a8054027SBarry Smith 
2591a8054027SBarry Smith    Options Database Keys:
2592a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2593a8054027SBarry Smith 
2594a8054027SBarry Smith    Notes:
2595a8054027SBarry Smith    The default is 1
2596a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2597a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2598a8054027SBarry Smith 
2599a8054027SBarry Smith    Level: intermediate
2600a8054027SBarry Smith 
2601a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2602a8054027SBarry Smith 
2603e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2604a8054027SBarry Smith 
2605a8054027SBarry Smith @*/
26067087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2607a8054027SBarry Smith {
2608a8054027SBarry Smith   PetscFunctionBegin;
26090700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2610e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2611e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2612c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2613a8054027SBarry Smith   snes->lagpreconditioner = lag;
2614a8054027SBarry Smith   PetscFunctionReturn(0);
2615a8054027SBarry Smith }
2616a8054027SBarry Smith 
2617a8054027SBarry Smith #undef __FUNCT__
2618efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
2619efd51863SBarry Smith /*@
2620efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2621efd51863SBarry Smith 
2622efd51863SBarry Smith    Logically Collective on SNES
2623efd51863SBarry Smith 
2624efd51863SBarry Smith    Input Parameters:
2625efd51863SBarry Smith +  snes - the SNES context
2626efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
2627efd51863SBarry Smith 
2628efd51863SBarry Smith    Options Database Keys:
2629efd51863SBarry Smith .    -snes_grid_sequence <steps>
2630efd51863SBarry Smith 
2631efd51863SBarry Smith    Level: intermediate
2632efd51863SBarry Smith 
2633c0df2a02SJed Brown    Notes:
2634c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2635c0df2a02SJed Brown 
2636efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2637efd51863SBarry Smith 
2638efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2639efd51863SBarry Smith 
2640efd51863SBarry Smith @*/
2641efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2642efd51863SBarry Smith {
2643efd51863SBarry Smith   PetscFunctionBegin;
2644efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2645efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
2646efd51863SBarry Smith   snes->gridsequence = steps;
2647efd51863SBarry Smith   PetscFunctionReturn(0);
2648efd51863SBarry Smith }
2649efd51863SBarry Smith 
2650efd51863SBarry Smith #undef __FUNCT__
2651a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
2652a8054027SBarry Smith /*@
2653a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
2654a8054027SBarry Smith 
26553f9fe445SBarry Smith    Not Collective
2656a8054027SBarry Smith 
2657a8054027SBarry Smith    Input Parameter:
2658a8054027SBarry Smith .  snes - the SNES context
2659a8054027SBarry Smith 
2660a8054027SBarry Smith    Output Parameter:
2661a8054027SBarry 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
26623b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2663a8054027SBarry Smith 
2664a8054027SBarry Smith    Options Database Keys:
2665a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2666a8054027SBarry Smith 
2667a8054027SBarry Smith    Notes:
2668a8054027SBarry Smith    The default is 1
2669a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2670a8054027SBarry Smith 
2671a8054027SBarry Smith    Level: intermediate
2672a8054027SBarry Smith 
2673a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2674a8054027SBarry Smith 
2675a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
2676a8054027SBarry Smith 
2677a8054027SBarry Smith @*/
26787087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
2679a8054027SBarry Smith {
2680a8054027SBarry Smith   PetscFunctionBegin;
26810700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2682a8054027SBarry Smith   *lag = snes->lagpreconditioner;
2683a8054027SBarry Smith   PetscFunctionReturn(0);
2684a8054027SBarry Smith }
2685a8054027SBarry Smith 
2686a8054027SBarry Smith #undef __FUNCT__
2687e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
2688e35cf81dSBarry Smith /*@
2689e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
2690e35cf81dSBarry Smith      often the preconditioner is rebuilt.
2691e35cf81dSBarry Smith 
26923f9fe445SBarry Smith    Logically Collective on SNES
2693e35cf81dSBarry Smith 
2694e35cf81dSBarry Smith    Input Parameters:
2695e35cf81dSBarry Smith +  snes - the SNES context
2696e35cf81dSBarry 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
2697fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
2698e35cf81dSBarry Smith 
2699e35cf81dSBarry Smith    Options Database Keys:
2700e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2701e35cf81dSBarry Smith 
2702e35cf81dSBarry Smith    Notes:
2703e35cf81dSBarry Smith    The default is 1
2704e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2705fe3ffe1eSBarry 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
2706fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
2707e35cf81dSBarry Smith 
2708e35cf81dSBarry Smith    Level: intermediate
2709e35cf81dSBarry Smith 
2710e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2711e35cf81dSBarry Smith 
2712e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
2713e35cf81dSBarry Smith 
2714e35cf81dSBarry Smith @*/
27157087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
2716e35cf81dSBarry Smith {
2717e35cf81dSBarry Smith   PetscFunctionBegin;
27180700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2719e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2720e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2721c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2722e35cf81dSBarry Smith   snes->lagjacobian = lag;
2723e35cf81dSBarry Smith   PetscFunctionReturn(0);
2724e35cf81dSBarry Smith }
2725e35cf81dSBarry Smith 
2726e35cf81dSBarry Smith #undef __FUNCT__
2727e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
2728e35cf81dSBarry Smith /*@
2729e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
2730e35cf81dSBarry Smith 
27313f9fe445SBarry Smith    Not Collective
2732e35cf81dSBarry Smith 
2733e35cf81dSBarry Smith    Input Parameter:
2734e35cf81dSBarry Smith .  snes - the SNES context
2735e35cf81dSBarry Smith 
2736e35cf81dSBarry Smith    Output Parameter:
2737e35cf81dSBarry 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
2738e35cf81dSBarry Smith          the Jacobian is built etc.
2739e35cf81dSBarry Smith 
2740e35cf81dSBarry Smith    Options Database Keys:
2741e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2742e35cf81dSBarry Smith 
2743e35cf81dSBarry Smith    Notes:
2744e35cf81dSBarry Smith    The default is 1
2745e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2746e35cf81dSBarry Smith 
2747e35cf81dSBarry Smith    Level: intermediate
2748e35cf81dSBarry Smith 
2749e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2750e35cf81dSBarry Smith 
2751e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
2752e35cf81dSBarry Smith 
2753e35cf81dSBarry Smith @*/
27547087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
2755e35cf81dSBarry Smith {
2756e35cf81dSBarry Smith   PetscFunctionBegin;
27570700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2758e35cf81dSBarry Smith   *lag = snes->lagjacobian;
2759e35cf81dSBarry Smith   PetscFunctionReturn(0);
2760e35cf81dSBarry Smith }
2761e35cf81dSBarry Smith 
2762e35cf81dSBarry Smith #undef __FUNCT__
27634a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
27649b94acceSBarry Smith /*@
2765d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
27669b94acceSBarry Smith 
27673f9fe445SBarry Smith    Logically Collective on SNES
2768c7afd0dbSLois Curfman McInnes 
27699b94acceSBarry Smith    Input Parameters:
2770c7afd0dbSLois Curfman McInnes +  snes - the SNES context
277170441072SBarry Smith .  abstol - absolute convergence tolerance
277233174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
277333174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
277433174efeSLois Curfman McInnes            of the change in the solution between steps
277533174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2776c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2777fee21e36SBarry Smith 
277833174efeSLois Curfman McInnes    Options Database Keys:
277970441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
2780c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
2781c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
2782c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
2783c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
27849b94acceSBarry Smith 
2785d7a720efSLois Curfman McInnes    Notes:
27869b94acceSBarry Smith    The default maximum number of iterations is 50.
27879b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
27889b94acceSBarry Smith 
278936851e7fSLois Curfman McInnes    Level: intermediate
279036851e7fSLois Curfman McInnes 
279133174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
27929b94acceSBarry Smith 
27932492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
27949b94acceSBarry Smith @*/
27957087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
27969b94acceSBarry Smith {
27973a40ed3dSBarry Smith   PetscFunctionBegin;
27980700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2799c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
2800c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
2801c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
2802c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
2803c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
2804c5eb9154SBarry Smith 
2805ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
2806ab54825eSJed Brown     if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol);
2807ab54825eSJed Brown     snes->abstol = abstol;
2808ab54825eSJed Brown   }
2809ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
2810ab54825eSJed 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);
2811ab54825eSJed Brown     snes->rtol = rtol;
2812ab54825eSJed Brown   }
2813ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
2814ab54825eSJed Brown     if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol);
2815c60f73f4SPeter Brune     snes->stol = stol;
2816ab54825eSJed Brown   }
2817ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
2818ab54825eSJed Brown     if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
2819ab54825eSJed Brown     snes->max_its = maxit;
2820ab54825eSJed Brown   }
2821ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
2822ab54825eSJed Brown     if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
2823ab54825eSJed Brown     snes->max_funcs = maxf;
2824ab54825eSJed Brown   }
282588976e71SPeter Brune   snes->tolerancesset = PETSC_TRUE;
28263a40ed3dSBarry Smith   PetscFunctionReturn(0);
28279b94acceSBarry Smith }
28289b94acceSBarry Smith 
28294a2ae208SSatish Balay #undef __FUNCT__
28304a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
28319b94acceSBarry Smith /*@
283233174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
283333174efeSLois Curfman McInnes 
2834c7afd0dbSLois Curfman McInnes    Not Collective
2835c7afd0dbSLois Curfman McInnes 
283633174efeSLois Curfman McInnes    Input Parameters:
2837c7afd0dbSLois Curfman McInnes +  snes - the SNES context
283885385478SLisandro Dalcin .  atol - absolute convergence tolerance
283933174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
284033174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
284133174efeSLois Curfman McInnes            of the change in the solution between steps
284233174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2843c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2844fee21e36SBarry Smith 
284533174efeSLois Curfman McInnes    Notes:
284633174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
284733174efeSLois Curfman McInnes 
284836851e7fSLois Curfman McInnes    Level: intermediate
284936851e7fSLois Curfman McInnes 
285033174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
285133174efeSLois Curfman McInnes 
285233174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
285333174efeSLois Curfman McInnes @*/
28547087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
285533174efeSLois Curfman McInnes {
28563a40ed3dSBarry Smith   PetscFunctionBegin;
28570700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
285885385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
285933174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
2860c60f73f4SPeter Brune   if (stol)  *stol  = snes->stol;
286133174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
286233174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
28633a40ed3dSBarry Smith   PetscFunctionReturn(0);
286433174efeSLois Curfman McInnes }
286533174efeSLois Curfman McInnes 
28664a2ae208SSatish Balay #undef __FUNCT__
28674a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
286833174efeSLois Curfman McInnes /*@
28699b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
28709b94acceSBarry Smith 
28713f9fe445SBarry Smith    Logically Collective on SNES
2872fee21e36SBarry Smith 
2873c7afd0dbSLois Curfman McInnes    Input Parameters:
2874c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2875c7afd0dbSLois Curfman McInnes -  tol - tolerance
2876c7afd0dbSLois Curfman McInnes 
28779b94acceSBarry Smith    Options Database Key:
2878c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
28799b94acceSBarry Smith 
288036851e7fSLois Curfman McInnes    Level: intermediate
288136851e7fSLois Curfman McInnes 
28829b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
28839b94acceSBarry Smith 
28842492ecdbSBarry Smith .seealso: SNESSetTolerances()
28859b94acceSBarry Smith @*/
28867087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
28879b94acceSBarry Smith {
28883a40ed3dSBarry Smith   PetscFunctionBegin;
28890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2890c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
28919b94acceSBarry Smith   snes->deltatol = tol;
28923a40ed3dSBarry Smith   PetscFunctionReturn(0);
28939b94acceSBarry Smith }
28949b94acceSBarry Smith 
2895df9fa365SBarry Smith /*
2896df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
2897df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
2898df9fa365SBarry Smith    macros instead of functions
2899df9fa365SBarry Smith */
29004a2ae208SSatish Balay #undef __FUNCT__
2901a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
29027087cfbeSBarry Smith PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2903ce1608b8SBarry Smith {
2904dfbe8321SBarry Smith   PetscErrorCode ierr;
2905ce1608b8SBarry Smith 
2906ce1608b8SBarry Smith   PetscFunctionBegin;
29070700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2908a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
2909ce1608b8SBarry Smith   PetscFunctionReturn(0);
2910ce1608b8SBarry Smith }
2911ce1608b8SBarry Smith 
29124a2ae208SSatish Balay #undef __FUNCT__
2913a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
29147087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2915df9fa365SBarry Smith {
2916dfbe8321SBarry Smith   PetscErrorCode ierr;
2917df9fa365SBarry Smith 
2918df9fa365SBarry Smith   PetscFunctionBegin;
2919a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2920df9fa365SBarry Smith   PetscFunctionReturn(0);
2921df9fa365SBarry Smith }
2922df9fa365SBarry Smith 
29234a2ae208SSatish Balay #undef __FUNCT__
2924a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
29256bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
2926df9fa365SBarry Smith {
2927dfbe8321SBarry Smith   PetscErrorCode ierr;
2928df9fa365SBarry Smith 
2929df9fa365SBarry Smith   PetscFunctionBegin;
2930a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2931df9fa365SBarry Smith   PetscFunctionReturn(0);
2932df9fa365SBarry Smith }
2933df9fa365SBarry Smith 
29347087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
2935b271bb04SBarry Smith #undef __FUNCT__
2936b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
29377087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2938b271bb04SBarry Smith {
2939b271bb04SBarry Smith   PetscDrawLG      lg;
2940b271bb04SBarry Smith   PetscErrorCode   ierr;
2941b271bb04SBarry Smith   PetscReal        x,y,per;
2942b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
2943b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
2944b271bb04SBarry Smith   PetscDraw        draw;
2945b271bb04SBarry Smith   PetscFunctionBegin;
2946b271bb04SBarry Smith   if (!monctx) {
2947b271bb04SBarry Smith     MPI_Comm    comm;
2948b271bb04SBarry Smith 
2949b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2950b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
2951b271bb04SBarry Smith   }
2952b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
2953b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2954b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2955b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
2956b271bb04SBarry Smith   x = (PetscReal) n;
2957b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
2958b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2959b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2960b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2961b271bb04SBarry Smith   }
2962b271bb04SBarry Smith 
2963b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
2964b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2965b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2966b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
2967b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
2968b271bb04SBarry Smith   x = (PetscReal) n;
2969b271bb04SBarry Smith   y = 100.0*per;
2970b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2971b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2972b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2973b271bb04SBarry Smith   }
2974b271bb04SBarry Smith 
2975b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
2976b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2977b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2978b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
2979b271bb04SBarry Smith   x = (PetscReal) n;
2980b271bb04SBarry Smith   y = (prev - rnorm)/prev;
2981b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2982b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2983b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2984b271bb04SBarry Smith   }
2985b271bb04SBarry Smith 
2986b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
2987b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2988b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2989b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
2990b271bb04SBarry Smith   x = (PetscReal) n;
2991b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
2992b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
2993b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2994b271bb04SBarry Smith   }
2995b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2996b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2997b271bb04SBarry Smith   }
2998b271bb04SBarry Smith   prev = rnorm;
2999b271bb04SBarry Smith   PetscFunctionReturn(0);
3000b271bb04SBarry Smith }
3001b271bb04SBarry Smith 
3002b271bb04SBarry Smith #undef __FUNCT__
3003b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
30047087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
3005b271bb04SBarry Smith {
3006b271bb04SBarry Smith   PetscErrorCode ierr;
3007b271bb04SBarry Smith 
3008b271bb04SBarry Smith   PetscFunctionBegin;
3009b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
3010b271bb04SBarry Smith   PetscFunctionReturn(0);
3011b271bb04SBarry Smith }
3012b271bb04SBarry Smith 
3013b271bb04SBarry Smith #undef __FUNCT__
3014b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
30156bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG *draw)
3016b271bb04SBarry Smith {
3017b271bb04SBarry Smith   PetscErrorCode ierr;
3018b271bb04SBarry Smith 
3019b271bb04SBarry Smith   PetscFunctionBegin;
3020b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
3021b271bb04SBarry Smith   PetscFunctionReturn(0);
3022b271bb04SBarry Smith }
3023b271bb04SBarry Smith 
30247a03ce2fSLisandro Dalcin #undef __FUNCT__
30257a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
3026228d79bcSJed Brown /*@
3027228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
3028228d79bcSJed Brown 
3029228d79bcSJed Brown    Collective on SNES
3030228d79bcSJed Brown 
3031228d79bcSJed Brown    Input Parameters:
3032228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
3033228d79bcSJed Brown .  iter - iteration number
3034228d79bcSJed Brown -  rnorm - relative norm of the residual
3035228d79bcSJed Brown 
3036228d79bcSJed Brown    Notes:
3037228d79bcSJed Brown    This routine is called by the SNES implementations.
3038228d79bcSJed Brown    It does not typically need to be called by the user.
3039228d79bcSJed Brown 
3040228d79bcSJed Brown    Level: developer
3041228d79bcSJed Brown 
3042228d79bcSJed Brown .seealso: SNESMonitorSet()
3043228d79bcSJed Brown @*/
30447a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
30457a03ce2fSLisandro Dalcin {
30467a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
30477a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
30487a03ce2fSLisandro Dalcin 
30497a03ce2fSLisandro Dalcin   PetscFunctionBegin;
30507a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
30517a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
30527a03ce2fSLisandro Dalcin   }
30537a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
30547a03ce2fSLisandro Dalcin }
30557a03ce2fSLisandro Dalcin 
30569b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
30579b94acceSBarry Smith 
30584a2ae208SSatish Balay #undef __FUNCT__
3059a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
30609b94acceSBarry Smith /*@C
3061a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
30629b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
30639b94acceSBarry Smith    progress.
30649b94acceSBarry Smith 
30653f9fe445SBarry Smith    Logically Collective on SNES
3066fee21e36SBarry Smith 
3067c7afd0dbSLois Curfman McInnes    Input Parameters:
3068c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3069c7afd0dbSLois Curfman McInnes .  func - monitoring routine
3070b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
3071e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
3072b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
3073b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
30749b94acceSBarry Smith 
3075c7afd0dbSLois Curfman McInnes    Calling sequence of func:
3076a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
3077c7afd0dbSLois Curfman McInnes 
3078c7afd0dbSLois Curfman McInnes +    snes - the SNES context
3079c7afd0dbSLois Curfman McInnes .    its - iteration number
3080c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
308140a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
30829b94acceSBarry Smith 
30839665c990SLois Curfman McInnes    Options Database Keys:
3084a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
3085a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
3086a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
3087cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
3088c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
3089a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
3090c7afd0dbSLois Curfman McInnes                             does not cancel those set via
3091c7afd0dbSLois Curfman McInnes                             the options database.
30929665c990SLois Curfman McInnes 
3093639f9d9dSBarry Smith    Notes:
30946bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
3095a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
30966bc08f3fSLois Curfman McInnes    order in which they were set.
3097639f9d9dSBarry Smith 
3098025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
3099025f1a04SBarry Smith 
310036851e7fSLois Curfman McInnes    Level: intermediate
310136851e7fSLois Curfman McInnes 
31029b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
31039b94acceSBarry Smith 
3104a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
31059b94acceSBarry Smith @*/
3106c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
31079b94acceSBarry Smith {
3108b90d0a6eSBarry Smith   PetscInt       i;
3109649052a6SBarry Smith   PetscErrorCode ierr;
3110b90d0a6eSBarry Smith 
31113a40ed3dSBarry Smith   PetscFunctionBegin;
31120700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
311317186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
3114b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
3115649052a6SBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
3116649052a6SBarry Smith       if (monitordestroy) {
3117c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
3118649052a6SBarry Smith       }
3119b90d0a6eSBarry Smith       PetscFunctionReturn(0);
3120b90d0a6eSBarry Smith     }
3121b90d0a6eSBarry Smith   }
3122b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
3123b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
3124639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
31253a40ed3dSBarry Smith   PetscFunctionReturn(0);
31269b94acceSBarry Smith }
31279b94acceSBarry Smith 
31284a2ae208SSatish Balay #undef __FUNCT__
3129a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
31305cd90555SBarry Smith /*@C
3131a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
31325cd90555SBarry Smith 
31333f9fe445SBarry Smith    Logically Collective on SNES
3134c7afd0dbSLois Curfman McInnes 
31355cd90555SBarry Smith    Input Parameters:
31365cd90555SBarry Smith .  snes - the SNES context
31375cd90555SBarry Smith 
31381a480d89SAdministrator    Options Database Key:
3139a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
3140a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
3141c7afd0dbSLois Curfman McInnes     set via the options database
31425cd90555SBarry Smith 
31435cd90555SBarry Smith    Notes:
31445cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
31455cd90555SBarry Smith 
314636851e7fSLois Curfman McInnes    Level: intermediate
314736851e7fSLois Curfman McInnes 
31485cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
31495cd90555SBarry Smith 
3150a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
31515cd90555SBarry Smith @*/
31527087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
31535cd90555SBarry Smith {
3154d952e501SBarry Smith   PetscErrorCode ierr;
3155d952e501SBarry Smith   PetscInt       i;
3156d952e501SBarry Smith 
31575cd90555SBarry Smith   PetscFunctionBegin;
31580700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3159d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
3160d952e501SBarry Smith     if (snes->monitordestroy[i]) {
31613c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
3162d952e501SBarry Smith     }
3163d952e501SBarry Smith   }
31645cd90555SBarry Smith   snes->numbermonitors = 0;
31655cd90555SBarry Smith   PetscFunctionReturn(0);
31665cd90555SBarry Smith }
31675cd90555SBarry Smith 
31684a2ae208SSatish Balay #undef __FUNCT__
31694a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
31709b94acceSBarry Smith /*@C
31719b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
31729b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
31739b94acceSBarry Smith 
31743f9fe445SBarry Smith    Logically Collective on SNES
3175fee21e36SBarry Smith 
3176c7afd0dbSLois Curfman McInnes    Input Parameters:
3177c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3178c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
31797f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
31807f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
31819b94acceSBarry Smith 
3182c7afd0dbSLois Curfman McInnes    Calling sequence of func:
318306ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
3184c7afd0dbSLois Curfman McInnes 
3185c7afd0dbSLois Curfman McInnes +    snes - the SNES context
318606ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
3187c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
3188184914b5SBarry Smith .    reason - reason for convergence/divergence
3189c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
31904b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
31914b27c08aSLois Curfman McInnes -    f - 2-norm of function
31929b94acceSBarry Smith 
319336851e7fSLois Curfman McInnes    Level: advanced
319436851e7fSLois Curfman McInnes 
31959b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
31969b94acceSBarry Smith 
319785385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
31989b94acceSBarry Smith @*/
31997087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
32009b94acceSBarry Smith {
32017f7931b9SBarry Smith   PetscErrorCode ierr;
32027f7931b9SBarry Smith 
32033a40ed3dSBarry Smith   PetscFunctionBegin;
32040700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
320585385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
32067f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
32077f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
32087f7931b9SBarry Smith   }
320985385478SLisandro Dalcin   snes->ops->converged        = func;
32107f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
321185385478SLisandro Dalcin   snes->cnvP                  = cctx;
32123a40ed3dSBarry Smith   PetscFunctionReturn(0);
32139b94acceSBarry Smith }
32149b94acceSBarry Smith 
32154a2ae208SSatish Balay #undef __FUNCT__
32164a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
321752baeb72SSatish Balay /*@
3218184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
3219184914b5SBarry Smith 
3220184914b5SBarry Smith    Not Collective
3221184914b5SBarry Smith 
3222184914b5SBarry Smith    Input Parameter:
3223184914b5SBarry Smith .  snes - the SNES context
3224184914b5SBarry Smith 
3225184914b5SBarry Smith    Output Parameter:
32264d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
3227184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
3228184914b5SBarry Smith 
3229184914b5SBarry Smith    Level: intermediate
3230184914b5SBarry Smith 
3231184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
3232184914b5SBarry Smith 
3233184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
3234184914b5SBarry Smith 
323585385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
3236184914b5SBarry Smith @*/
32377087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
3238184914b5SBarry Smith {
3239184914b5SBarry Smith   PetscFunctionBegin;
32400700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
32414482741eSBarry Smith   PetscValidPointer(reason,2);
3242184914b5SBarry Smith   *reason = snes->reason;
3243184914b5SBarry Smith   PetscFunctionReturn(0);
3244184914b5SBarry Smith }
3245184914b5SBarry Smith 
32464a2ae208SSatish Balay #undef __FUNCT__
32474a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
3248c9005455SLois Curfman McInnes /*@
3249c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
3250c9005455SLois Curfman McInnes 
32513f9fe445SBarry Smith    Logically Collective on SNES
3252fee21e36SBarry Smith 
3253c7afd0dbSLois Curfman McInnes    Input Parameters:
3254c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
32558c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
3256cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
3257758f92a0SBarry Smith .  na  - size of a and its
325864731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
3259758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
3260c7afd0dbSLois Curfman McInnes 
3261308dcc3eSBarry Smith    Notes:
3262308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
3263308dcc3eSBarry Smith    default array of length 10000 is allocated.
3264308dcc3eSBarry Smith 
3265c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
3266c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
3267c9005455SLois Curfman McInnes    during the section of code that is being timed.
3268c9005455SLois Curfman McInnes 
326936851e7fSLois Curfman McInnes    Level: intermediate
327036851e7fSLois Curfman McInnes 
3271c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
3272758f92a0SBarry Smith 
327308405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
3274758f92a0SBarry Smith 
3275c9005455SLois Curfman McInnes @*/
32767087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
3277c9005455SLois Curfman McInnes {
3278308dcc3eSBarry Smith   PetscErrorCode ierr;
3279308dcc3eSBarry Smith 
32803a40ed3dSBarry Smith   PetscFunctionBegin;
32810700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
32824482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
3283a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
3284308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
3285308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
3286308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
3287308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
3288308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
3289308dcc3eSBarry Smith   }
3290c9005455SLois Curfman McInnes   snes->conv_hist       = a;
3291758f92a0SBarry Smith   snes->conv_hist_its   = its;
3292758f92a0SBarry Smith   snes->conv_hist_max   = na;
3293a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
3294758f92a0SBarry Smith   snes->conv_hist_reset = reset;
3295758f92a0SBarry Smith   PetscFunctionReturn(0);
3296758f92a0SBarry Smith }
3297758f92a0SBarry Smith 
3298308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3299c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
3300c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
3301308dcc3eSBarry Smith EXTERN_C_BEGIN
3302308dcc3eSBarry Smith #undef __FUNCT__
3303308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
3304308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
3305308dcc3eSBarry Smith {
3306308dcc3eSBarry Smith   mxArray        *mat;
3307308dcc3eSBarry Smith   PetscInt       i;
3308308dcc3eSBarry Smith   PetscReal      *ar;
3309308dcc3eSBarry Smith 
3310308dcc3eSBarry Smith   PetscFunctionBegin;
3311308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
3312308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
3313308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
3314308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
3315308dcc3eSBarry Smith   }
3316308dcc3eSBarry Smith   PetscFunctionReturn(mat);
3317308dcc3eSBarry Smith }
3318308dcc3eSBarry Smith EXTERN_C_END
3319308dcc3eSBarry Smith #endif
3320308dcc3eSBarry Smith 
3321308dcc3eSBarry Smith 
33224a2ae208SSatish Balay #undef __FUNCT__
33234a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
33240c4c9dddSBarry Smith /*@C
3325758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
3326758f92a0SBarry Smith 
33273f9fe445SBarry Smith    Not Collective
3328758f92a0SBarry Smith 
3329758f92a0SBarry Smith    Input Parameter:
3330758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
3331758f92a0SBarry Smith 
3332758f92a0SBarry Smith    Output Parameters:
3333758f92a0SBarry Smith .  a   - array to hold history
3334758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
3335758f92a0SBarry Smith          negative if not converged) for each solve.
3336758f92a0SBarry Smith -  na  - size of a and its
3337758f92a0SBarry Smith 
3338758f92a0SBarry Smith    Notes:
3339758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
3340758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
3341758f92a0SBarry Smith 
3342758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
3343758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
3344758f92a0SBarry Smith    during the section of code that is being timed.
3345758f92a0SBarry Smith 
3346758f92a0SBarry Smith    Level: intermediate
3347758f92a0SBarry Smith 
3348758f92a0SBarry Smith .keywords: SNES, get, convergence, history
3349758f92a0SBarry Smith 
3350758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
3351758f92a0SBarry Smith 
3352758f92a0SBarry Smith @*/
33537087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3354758f92a0SBarry Smith {
3355758f92a0SBarry Smith   PetscFunctionBegin;
33560700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3357758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
3358758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
3359758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
33603a40ed3dSBarry Smith   PetscFunctionReturn(0);
3361c9005455SLois Curfman McInnes }
3362c9005455SLois Curfman McInnes 
3363e74ef692SMatthew Knepley #undef __FUNCT__
3364e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
3365ac226902SBarry Smith /*@C
336676b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
3367eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
33687e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
336976b2cf59SMatthew Knepley 
33703f9fe445SBarry Smith   Logically Collective on SNES
337176b2cf59SMatthew Knepley 
337276b2cf59SMatthew Knepley   Input Parameters:
337376b2cf59SMatthew Knepley . snes - The nonlinear solver context
337476b2cf59SMatthew Knepley . func - The function
337576b2cf59SMatthew Knepley 
337676b2cf59SMatthew Knepley   Calling sequence of func:
3377b5d30489SBarry Smith . func (SNES snes, PetscInt step);
337876b2cf59SMatthew Knepley 
337976b2cf59SMatthew Knepley . step - The current step of the iteration
338076b2cf59SMatthew Knepley 
3381fe97e370SBarry Smith   Level: advanced
3382fe97e370SBarry Smith 
3383fe97e370SBarry 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()
3384fe97e370SBarry Smith         This is not used by most users.
338576b2cf59SMatthew Knepley 
338676b2cf59SMatthew Knepley .keywords: SNES, update
3387b5d30489SBarry Smith 
338885385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
338976b2cf59SMatthew Knepley @*/
33907087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
339176b2cf59SMatthew Knepley {
339276b2cf59SMatthew Knepley   PetscFunctionBegin;
33930700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
3394e7788613SBarry Smith   snes->ops->update = func;
339576b2cf59SMatthew Knepley   PetscFunctionReturn(0);
339676b2cf59SMatthew Knepley }
339776b2cf59SMatthew Knepley 
3398e74ef692SMatthew Knepley #undef __FUNCT__
3399e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
340076b2cf59SMatthew Knepley /*@
340176b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
340276b2cf59SMatthew Knepley 
340376b2cf59SMatthew Knepley   Not collective
340476b2cf59SMatthew Knepley 
340576b2cf59SMatthew Knepley   Input Parameters:
340676b2cf59SMatthew Knepley . snes - The nonlinear solver context
340776b2cf59SMatthew Knepley . step - The current step of the iteration
340876b2cf59SMatthew Knepley 
3409205452f4SMatthew Knepley   Level: intermediate
3410205452f4SMatthew Knepley 
341176b2cf59SMatthew Knepley .keywords: SNES, update
3412a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
341376b2cf59SMatthew Knepley @*/
34147087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
341576b2cf59SMatthew Knepley {
341676b2cf59SMatthew Knepley   PetscFunctionBegin;
341776b2cf59SMatthew Knepley   PetscFunctionReturn(0);
341876b2cf59SMatthew Knepley }
341976b2cf59SMatthew Knepley 
34204a2ae208SSatish Balay #undef __FUNCT__
34214a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
34229b94acceSBarry Smith /*
34239b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
34249b94acceSBarry Smith    positive parameter delta.
34259b94acceSBarry Smith 
34269b94acceSBarry Smith     Input Parameters:
3427c7afd0dbSLois Curfman McInnes +   snes - the SNES context
34289b94acceSBarry Smith .   y - approximate solution of linear system
34299b94acceSBarry Smith .   fnorm - 2-norm of current function
3430c7afd0dbSLois Curfman McInnes -   delta - trust region size
34319b94acceSBarry Smith 
34329b94acceSBarry Smith     Output Parameters:
3433c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
34349b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
34359b94acceSBarry Smith     region, and exceeds zero otherwise.
3436c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
34379b94acceSBarry Smith 
34389b94acceSBarry Smith     Note:
34394b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
34409b94acceSBarry Smith     is set to be the maximum allowable step size.
34419b94acceSBarry Smith 
34429b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
34439b94acceSBarry Smith */
3444dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
34459b94acceSBarry Smith {
3446064f8208SBarry Smith   PetscReal      nrm;
3447ea709b57SSatish Balay   PetscScalar    cnorm;
3448dfbe8321SBarry Smith   PetscErrorCode ierr;
34493a40ed3dSBarry Smith 
34503a40ed3dSBarry Smith   PetscFunctionBegin;
34510700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
34520700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3453c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
3454184914b5SBarry Smith 
3455064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
3456064f8208SBarry Smith   if (nrm > *delta) {
3457064f8208SBarry Smith      nrm = *delta/nrm;
3458064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
3459064f8208SBarry Smith      cnorm = nrm;
34602dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
34619b94acceSBarry Smith      *ynorm = *delta;
34629b94acceSBarry Smith   } else {
34639b94acceSBarry Smith      *gpnorm = 0.0;
3464064f8208SBarry Smith      *ynorm = nrm;
34659b94acceSBarry Smith   }
34663a40ed3dSBarry Smith   PetscFunctionReturn(0);
34679b94acceSBarry Smith }
34689b94acceSBarry Smith 
34694a2ae208SSatish Balay #undef __FUNCT__
34704a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
34716ce558aeSBarry Smith /*@C
3472f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
3473f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
34749b94acceSBarry Smith 
3475c7afd0dbSLois Curfman McInnes    Collective on SNES
3476c7afd0dbSLois Curfman McInnes 
3477b2002411SLois Curfman McInnes    Input Parameters:
3478c7afd0dbSLois Curfman McInnes +  snes - the SNES context
34793cebf274SJed Brown .  b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero.
348085385478SLisandro Dalcin -  x - the solution vector.
34819b94acceSBarry Smith 
3482b2002411SLois Curfman McInnes    Notes:
34838ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
34848ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
34858ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
34868ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
34878ddd3da0SLois Curfman McInnes 
348836851e7fSLois Curfman McInnes    Level: beginner
348936851e7fSLois Curfman McInnes 
34909b94acceSBarry Smith .keywords: SNES, nonlinear, solve
34919b94acceSBarry Smith 
3492c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
34939b94acceSBarry Smith @*/
34947087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
34959b94acceSBarry Smith {
3496dfbe8321SBarry Smith   PetscErrorCode ierr;
3497ace3abfcSBarry Smith   PetscBool      flg;
3498eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
3499eabae89aSBarry Smith   PetscViewer    viewer;
3500efd51863SBarry Smith   PetscInt       grid;
3501a69afd8bSBarry Smith   Vec            xcreated = PETSC_NULL;
3502caa4e7f2SJed Brown   DM             dm;
3503052efed2SBarry Smith 
35043a40ed3dSBarry Smith   PetscFunctionBegin;
35050700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3506a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3507a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
35080700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
350985385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
351085385478SLisandro Dalcin 
3511caa4e7f2SJed Brown   if (!x) {
3512caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3513caa4e7f2SJed Brown     ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr);
3514a69afd8bSBarry Smith     x    = xcreated;
3515a69afd8bSBarry Smith   }
3516a69afd8bSBarry Smith 
3517a8248277SBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);}
3518efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
3519efd51863SBarry Smith 
352085385478SLisandro Dalcin     /* set solution vector */
3521efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
35226bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
352385385478SLisandro Dalcin     snes->vec_sol = x;
3524caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3525caa4e7f2SJed Brown 
3526caa4e7f2SJed Brown     /* set affine vector if provided */
352785385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
35286bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
352985385478SLisandro Dalcin     snes->vec_rhs = b;
353085385478SLisandro Dalcin 
353170e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
35323f149594SLisandro Dalcin 
35337eee914bSBarry Smith     if (!grid) {
35347eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
3535d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
3536dd568438SSatish Balay       } else if (snes->dm) {
3537dd568438SSatish Balay         PetscBool ig;
3538dd568438SSatish Balay         ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr);
3539dd568438SSatish Balay         if (ig) {
35407eee914bSBarry Smith           ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr);
35417eee914bSBarry Smith         }
3542d25893d9SBarry Smith       }
3543dd568438SSatish Balay     }
3544d25893d9SBarry Smith 
3545abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
354650ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
3547d5e45103SBarry Smith 
35483f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
35494936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
355085385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
35514936397dSBarry Smith     if (snes->domainerror){
35524936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
35534936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
35544936397dSBarry Smith     }
355517186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
35563f149594SLisandro Dalcin 
355790d69ab7SBarry Smith     flg  = PETSC_FALSE;
3558acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
3559da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
35605968eb51SBarry Smith     if (snes->printreason) {
3561a8248277SBarry Smith       ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
35625968eb51SBarry Smith       if (snes->reason > 0) {
3563c7e7b494SJed 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);
35645968eb51SBarry Smith       } else {
3565c7e7b494SJed 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);
35665968eb51SBarry Smith       }
3567a8248277SBarry Smith       ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
35685968eb51SBarry Smith     }
35695968eb51SBarry Smith 
3570e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
3571efd51863SBarry Smith     if (grid <  snes->gridsequence) {
3572efd51863SBarry Smith       DM  fine;
3573efd51863SBarry Smith       Vec xnew;
3574efd51863SBarry Smith       Mat interp;
3575efd51863SBarry Smith 
3576efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
3577c5c77316SJed Brown       if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
3578e727c939SJed Brown       ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
3579efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
3580efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
3581c833c3b5SJed Brown       ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr);
3582efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
3583efd51863SBarry Smith       x    = xnew;
3584efd51863SBarry Smith 
3585efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
3586efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
3587efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
3588a8248277SBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);
3589efd51863SBarry Smith     }
3590efd51863SBarry Smith   }
35913f7e2da0SPeter Brune   /* monitoring and viewing */
35923f7e2da0SPeter Brune   flg = PETSC_FALSE;
35933f7e2da0SPeter Brune   ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
35943f7e2da0SPeter Brune   if (flg && !PetscPreLoadingOn) {
35953f7e2da0SPeter Brune     ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
35963f7e2da0SPeter Brune     ierr = SNESView(snes,viewer);CHKERRQ(ierr);
35973f7e2da0SPeter Brune     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
35983f7e2da0SPeter Brune   }
35993f7e2da0SPeter Brune 
36003f7e2da0SPeter Brune   flg = PETSC_FALSE;
36013f7e2da0SPeter Brune   ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
36023f7e2da0SPeter Brune   if (flg) {
36033f7e2da0SPeter Brune     PetscViewer viewer;
36043f7e2da0SPeter Brune     ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
36053f7e2da0SPeter Brune     ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr);
36063f7e2da0SPeter Brune     ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr);
36073f7e2da0SPeter Brune     ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr);
36083f7e2da0SPeter Brune     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
36093f7e2da0SPeter Brune   }
36103f7e2da0SPeter Brune 
3611a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
36123a40ed3dSBarry Smith   PetscFunctionReturn(0);
36139b94acceSBarry Smith }
36149b94acceSBarry Smith 
36159b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
36169b94acceSBarry Smith 
36174a2ae208SSatish Balay #undef __FUNCT__
36184a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
361982bf6240SBarry Smith /*@C
36204b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
36219b94acceSBarry Smith 
3622fee21e36SBarry Smith    Collective on SNES
3623fee21e36SBarry Smith 
3624c7afd0dbSLois Curfman McInnes    Input Parameters:
3625c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3626454a90a3SBarry Smith -  type - a known method
3627c7afd0dbSLois Curfman McInnes 
3628c7afd0dbSLois Curfman McInnes    Options Database Key:
3629454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
3630c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
3631ae12b187SLois Curfman McInnes 
36329b94acceSBarry Smith    Notes:
3633e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
36344b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
3635c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
36364b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
3637c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
36389b94acceSBarry Smith 
3639ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
3640ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
3641ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
3642ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
3643ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
3644ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
3645ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
3646ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
3647ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
3648b0a32e0cSBarry Smith   appropriate method.
364936851e7fSLois Curfman McInnes 
365036851e7fSLois Curfman McInnes   Level: intermediate
3651a703fe33SLois Curfman McInnes 
3652454a90a3SBarry Smith .keywords: SNES, set, type
3653435da068SBarry Smith 
3654435da068SBarry Smith .seealso: SNESType, SNESCreate()
3655435da068SBarry Smith 
36569b94acceSBarry Smith @*/
36577087cfbeSBarry Smith PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
36589b94acceSBarry Smith {
3659dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
3660ace3abfcSBarry Smith   PetscBool      match;
36613a40ed3dSBarry Smith 
36623a40ed3dSBarry Smith   PetscFunctionBegin;
36630700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36644482741eSBarry Smith   PetscValidCharPointer(type,2);
366582bf6240SBarry Smith 
3666251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
36670f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
366892ff6ae8SBarry Smith 
36694b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
3670e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
367175396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
3672b5c23020SJed Brown   if (snes->ops->destroy) {
3673b5c23020SJed Brown     ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
3674b5c23020SJed Brown     snes->ops->destroy = PETSC_NULL;
3675b5c23020SJed Brown   }
367675396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
367775396ef9SLisandro Dalcin   snes->ops->setup          = 0;
367875396ef9SLisandro Dalcin   snes->ops->solve          = 0;
367975396ef9SLisandro Dalcin   snes->ops->view           = 0;
368075396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
368175396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
368275396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
368375396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
3684454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
368503bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
36869fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
36879fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
36889fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
36899fb22e1aSBarry Smith   }
36909fb22e1aSBarry Smith #endif
36913a40ed3dSBarry Smith   PetscFunctionReturn(0);
36929b94acceSBarry Smith }
36939b94acceSBarry Smith 
3694a847f771SSatish Balay 
36959b94acceSBarry Smith /* --------------------------------------------------------------------- */
36964a2ae208SSatish Balay #undef __FUNCT__
36974a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
369852baeb72SSatish Balay /*@
36999b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
3700f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
37019b94acceSBarry Smith 
3702fee21e36SBarry Smith    Not Collective
3703fee21e36SBarry Smith 
370436851e7fSLois Curfman McInnes    Level: advanced
370536851e7fSLois Curfman McInnes 
37069b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
37079b94acceSBarry Smith 
37089b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
37099b94acceSBarry Smith @*/
37107087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
37119b94acceSBarry Smith {
3712dfbe8321SBarry Smith   PetscErrorCode ierr;
371382bf6240SBarry Smith 
37143a40ed3dSBarry Smith   PetscFunctionBegin;
37151441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
37164c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
37173a40ed3dSBarry Smith   PetscFunctionReturn(0);
37189b94acceSBarry Smith }
37199b94acceSBarry Smith 
37204a2ae208SSatish Balay #undef __FUNCT__
37214a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
37229b94acceSBarry Smith /*@C
37239a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
37249b94acceSBarry Smith 
3725c7afd0dbSLois Curfman McInnes    Not Collective
3726c7afd0dbSLois Curfman McInnes 
37279b94acceSBarry Smith    Input Parameter:
37284b0e389bSBarry Smith .  snes - nonlinear solver context
37299b94acceSBarry Smith 
37309b94acceSBarry Smith    Output Parameter:
37313a7fca6bSBarry Smith .  type - SNES method (a character string)
37329b94acceSBarry Smith 
373336851e7fSLois Curfman McInnes    Level: intermediate
373436851e7fSLois Curfman McInnes 
3735454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
37369b94acceSBarry Smith @*/
37377087cfbeSBarry Smith PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
37389b94acceSBarry Smith {
37393a40ed3dSBarry Smith   PetscFunctionBegin;
37400700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37414482741eSBarry Smith   PetscValidPointer(type,2);
37427adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
37433a40ed3dSBarry Smith   PetscFunctionReturn(0);
37449b94acceSBarry Smith }
37459b94acceSBarry Smith 
37464a2ae208SSatish Balay #undef __FUNCT__
37474a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
374852baeb72SSatish Balay /*@
37499b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
3750c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
37519b94acceSBarry Smith 
3752c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3753c7afd0dbSLois Curfman McInnes 
37549b94acceSBarry Smith    Input Parameter:
37559b94acceSBarry Smith .  snes - the SNES context
37569b94acceSBarry Smith 
37579b94acceSBarry Smith    Output Parameter:
37589b94acceSBarry Smith .  x - the solution
37599b94acceSBarry Smith 
376070e92668SMatthew Knepley    Level: intermediate
376136851e7fSLois Curfman McInnes 
37629b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
37639b94acceSBarry Smith 
376485385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
37659b94acceSBarry Smith @*/
37667087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
37679b94acceSBarry Smith {
37683a40ed3dSBarry Smith   PetscFunctionBegin;
37690700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37704482741eSBarry Smith   PetscValidPointer(x,2);
377185385478SLisandro Dalcin   *x = snes->vec_sol;
377270e92668SMatthew Knepley   PetscFunctionReturn(0);
377370e92668SMatthew Knepley }
377470e92668SMatthew Knepley 
377570e92668SMatthew Knepley #undef __FUNCT__
37764a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
377752baeb72SSatish Balay /*@
37789b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
37799b94acceSBarry Smith    stored.
37809b94acceSBarry Smith 
3781c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3782c7afd0dbSLois Curfman McInnes 
37839b94acceSBarry Smith    Input Parameter:
37849b94acceSBarry Smith .  snes - the SNES context
37859b94acceSBarry Smith 
37869b94acceSBarry Smith    Output Parameter:
37879b94acceSBarry Smith .  x - the solution update
37889b94acceSBarry Smith 
378936851e7fSLois Curfman McInnes    Level: advanced
379036851e7fSLois Curfman McInnes 
37919b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
37929b94acceSBarry Smith 
379385385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
37949b94acceSBarry Smith @*/
37957087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
37969b94acceSBarry Smith {
37973a40ed3dSBarry Smith   PetscFunctionBegin;
37980700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37994482741eSBarry Smith   PetscValidPointer(x,2);
380085385478SLisandro Dalcin   *x = snes->vec_sol_update;
38013a40ed3dSBarry Smith   PetscFunctionReturn(0);
38029b94acceSBarry Smith }
38039b94acceSBarry Smith 
38044a2ae208SSatish Balay #undef __FUNCT__
38054a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
38069b94acceSBarry Smith /*@C
38073638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
38089b94acceSBarry Smith 
3809a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
3810c7afd0dbSLois Curfman McInnes 
38119b94acceSBarry Smith    Input Parameter:
38129b94acceSBarry Smith .  snes - the SNES context
38139b94acceSBarry Smith 
38149b94acceSBarry Smith    Output Parameter:
38157bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
381670e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
381770e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
38189b94acceSBarry Smith 
381936851e7fSLois Curfman McInnes    Level: advanced
382036851e7fSLois Curfman McInnes 
3821a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
38229b94acceSBarry Smith 
38234b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
38249b94acceSBarry Smith @*/
38257087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
38269b94acceSBarry Smith {
3827a63bb30eSJed Brown   PetscErrorCode ierr;
38286cab3a1bSJed Brown   DM             dm;
3829a63bb30eSJed Brown 
38303a40ed3dSBarry Smith   PetscFunctionBegin;
38310700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3832a63bb30eSJed Brown   if (r) {
3833a63bb30eSJed Brown     if (!snes->vec_func) {
3834a63bb30eSJed Brown       if (snes->vec_rhs) {
3835a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
3836a63bb30eSJed Brown       } else if (snes->vec_sol) {
3837a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
3838a63bb30eSJed Brown       } else if (snes->dm) {
3839a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
3840a63bb30eSJed Brown       }
3841a63bb30eSJed Brown     }
3842a63bb30eSJed Brown     *r = snes->vec_func;
3843a63bb30eSJed Brown   }
38446cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
38456cab3a1bSJed Brown   ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr);
38463a40ed3dSBarry Smith   PetscFunctionReturn(0);
38479b94acceSBarry Smith }
38489b94acceSBarry Smith 
3849c79ef259SPeter Brune /*@C
3850c79ef259SPeter Brune    SNESGetGS - Returns the GS function and context.
3851c79ef259SPeter Brune 
3852c79ef259SPeter Brune    Input Parameter:
3853c79ef259SPeter Brune .  snes - the SNES context
3854c79ef259SPeter Brune 
3855c79ef259SPeter Brune    Output Parameter:
3856c79ef259SPeter Brune +  gsfunc - the function (or PETSC_NULL)
3857c79ef259SPeter Brune -  ctx    - the function context (or PETSC_NULL)
3858c79ef259SPeter Brune 
3859c79ef259SPeter Brune    Level: advanced
3860c79ef259SPeter Brune 
3861c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
3862c79ef259SPeter Brune 
3863c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction()
3864c79ef259SPeter Brune @*/
3865c79ef259SPeter Brune 
38664a2ae208SSatish Balay #undef __FUNCT__
3867646217ecSPeter Brune #define __FUNCT__ "SNESGetGS"
3868646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx)
3869646217ecSPeter Brune {
38706cab3a1bSJed Brown   PetscErrorCode ierr;
38716cab3a1bSJed Brown   DM             dm;
38726cab3a1bSJed Brown 
3873646217ecSPeter Brune   PetscFunctionBegin;
3874646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
38756cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
38766cab3a1bSJed Brown   ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr);
3877646217ecSPeter Brune   PetscFunctionReturn(0);
3878646217ecSPeter Brune }
3879646217ecSPeter Brune 
38804a2ae208SSatish Balay #undef __FUNCT__
38814a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
38823c7409f5SSatish Balay /*@C
38833c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
3884d850072dSLois Curfman McInnes    SNES options in the database.
38853c7409f5SSatish Balay 
38863f9fe445SBarry Smith    Logically Collective on SNES
3887fee21e36SBarry Smith 
3888c7afd0dbSLois Curfman McInnes    Input Parameter:
3889c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3890c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3891c7afd0dbSLois Curfman McInnes 
3892d850072dSLois Curfman McInnes    Notes:
3893a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3894c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3895d850072dSLois Curfman McInnes 
389636851e7fSLois Curfman McInnes    Level: advanced
389736851e7fSLois Curfman McInnes 
38983c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
3899a86d99e1SLois Curfman McInnes 
3900a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
39013c7409f5SSatish Balay @*/
39027087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
39033c7409f5SSatish Balay {
3904dfbe8321SBarry Smith   PetscErrorCode ierr;
39053c7409f5SSatish Balay 
39063a40ed3dSBarry Smith   PetscFunctionBegin;
39070700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3908639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
39091cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
391094b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
39113a40ed3dSBarry Smith   PetscFunctionReturn(0);
39123c7409f5SSatish Balay }
39133c7409f5SSatish Balay 
39144a2ae208SSatish Balay #undef __FUNCT__
39154a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
39163c7409f5SSatish Balay /*@C
3917f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
3918d850072dSLois Curfman McInnes    SNES options in the database.
39193c7409f5SSatish Balay 
39203f9fe445SBarry Smith    Logically Collective on SNES
3921fee21e36SBarry Smith 
3922c7afd0dbSLois Curfman McInnes    Input Parameters:
3923c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3924c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3925c7afd0dbSLois Curfman McInnes 
3926d850072dSLois Curfman McInnes    Notes:
3927a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3928c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3929d850072dSLois Curfman McInnes 
393036851e7fSLois Curfman McInnes    Level: advanced
393136851e7fSLois Curfman McInnes 
39323c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
3933a86d99e1SLois Curfman McInnes 
3934a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
39353c7409f5SSatish Balay @*/
39367087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
39373c7409f5SSatish Balay {
3938dfbe8321SBarry Smith   PetscErrorCode ierr;
39393c7409f5SSatish Balay 
39403a40ed3dSBarry Smith   PetscFunctionBegin;
39410700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3942639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
39431cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
394494b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
39453a40ed3dSBarry Smith   PetscFunctionReturn(0);
39463c7409f5SSatish Balay }
39473c7409f5SSatish Balay 
39484a2ae208SSatish Balay #undef __FUNCT__
39494a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
39509ab63eb5SSatish Balay /*@C
39513c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
39523c7409f5SSatish Balay    SNES options in the database.
39533c7409f5SSatish Balay 
3954c7afd0dbSLois Curfman McInnes    Not Collective
3955c7afd0dbSLois Curfman McInnes 
39563c7409f5SSatish Balay    Input Parameter:
39573c7409f5SSatish Balay .  snes - the SNES context
39583c7409f5SSatish Balay 
39593c7409f5SSatish Balay    Output Parameter:
39603c7409f5SSatish Balay .  prefix - pointer to the prefix string used
39613c7409f5SSatish Balay 
39624ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
39639ab63eb5SSatish Balay    sufficient length to hold the prefix.
39649ab63eb5SSatish Balay 
396536851e7fSLois Curfman McInnes    Level: advanced
396636851e7fSLois Curfman McInnes 
39673c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
3968a86d99e1SLois Curfman McInnes 
3969a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
39703c7409f5SSatish Balay @*/
39717087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
39723c7409f5SSatish Balay {
3973dfbe8321SBarry Smith   PetscErrorCode ierr;
39743c7409f5SSatish Balay 
39753a40ed3dSBarry Smith   PetscFunctionBegin;
39760700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3977639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
39783a40ed3dSBarry Smith   PetscFunctionReturn(0);
39793c7409f5SSatish Balay }
39803c7409f5SSatish Balay 
3981b2002411SLois Curfman McInnes 
39824a2ae208SSatish Balay #undef __FUNCT__
39834a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
39843cea93caSBarry Smith /*@C
39853cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
39863cea93caSBarry Smith 
39877f6c08e0SMatthew Knepley   Level: advanced
39883cea93caSBarry Smith @*/
39897087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
3990b2002411SLois Curfman McInnes {
3991e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
3992dfbe8321SBarry Smith   PetscErrorCode ierr;
3993b2002411SLois Curfman McInnes 
3994b2002411SLois Curfman McInnes   PetscFunctionBegin;
3995b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3996c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3997b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
3998b2002411SLois Curfman McInnes }
3999da9b6338SBarry Smith 
4000da9b6338SBarry Smith #undef __FUNCT__
4001da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
40027087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
4003da9b6338SBarry Smith {
4004dfbe8321SBarry Smith   PetscErrorCode ierr;
400577431f27SBarry Smith   PetscInt       N,i,j;
4006da9b6338SBarry Smith   Vec            u,uh,fh;
4007da9b6338SBarry Smith   PetscScalar    value;
4008da9b6338SBarry Smith   PetscReal      norm;
4009da9b6338SBarry Smith 
4010da9b6338SBarry Smith   PetscFunctionBegin;
4011da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
4012da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
4013da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
4014da9b6338SBarry Smith 
4015da9b6338SBarry Smith   /* currently only works for sequential */
4016da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
4017da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
4018da9b6338SBarry Smith   for (i=0; i<N; i++) {
4019da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
402077431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
4021da9b6338SBarry Smith     for (j=-10; j<11; j++) {
4022ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
4023da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
40243ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
4025da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
402677431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
4027da9b6338SBarry Smith       value = -value;
4028da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
4029da9b6338SBarry Smith     }
4030da9b6338SBarry Smith   }
40316bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
40326bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
4033da9b6338SBarry Smith   PetscFunctionReturn(0);
4034da9b6338SBarry Smith }
403571f87433Sdalcinl 
403671f87433Sdalcinl #undef __FUNCT__
4037fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
403871f87433Sdalcinl /*@
4039fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
404071f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
404171f87433Sdalcinl    Newton method.
404271f87433Sdalcinl 
40433f9fe445SBarry Smith    Logically Collective on SNES
404471f87433Sdalcinl 
404571f87433Sdalcinl    Input Parameters:
404671f87433Sdalcinl +  snes - SNES context
404771f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
404871f87433Sdalcinl 
404964ba62caSBarry Smith     Options Database:
405064ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
405164ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
405264ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
405364ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
405464ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
405564ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
405664ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
405764ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
405864ba62caSBarry Smith 
405971f87433Sdalcinl    Notes:
406071f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
406171f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
406271f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
406371f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
406471f87433Sdalcinl    solver.
406571f87433Sdalcinl 
406671f87433Sdalcinl    Level: advanced
406771f87433Sdalcinl 
406871f87433Sdalcinl    Reference:
406971f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
407071f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
407171f87433Sdalcinl 
407271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
407371f87433Sdalcinl 
4074fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
407571f87433Sdalcinl @*/
40767087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
407771f87433Sdalcinl {
407871f87433Sdalcinl   PetscFunctionBegin;
40790700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4080acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
408171f87433Sdalcinl   snes->ksp_ewconv = flag;
408271f87433Sdalcinl   PetscFunctionReturn(0);
408371f87433Sdalcinl }
408471f87433Sdalcinl 
408571f87433Sdalcinl #undef __FUNCT__
4086fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
408771f87433Sdalcinl /*@
4088fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
408971f87433Sdalcinl    for computing relative tolerance for linear solvers within an
409071f87433Sdalcinl    inexact Newton method.
409171f87433Sdalcinl 
409271f87433Sdalcinl    Not Collective
409371f87433Sdalcinl 
409471f87433Sdalcinl    Input Parameter:
409571f87433Sdalcinl .  snes - SNES context
409671f87433Sdalcinl 
409771f87433Sdalcinl    Output Parameter:
409871f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
409971f87433Sdalcinl 
410071f87433Sdalcinl    Notes:
410171f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
410271f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
410371f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
410471f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
410571f87433Sdalcinl    solver.
410671f87433Sdalcinl 
410771f87433Sdalcinl    Level: advanced
410871f87433Sdalcinl 
410971f87433Sdalcinl    Reference:
411071f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
411171f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
411271f87433Sdalcinl 
411371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
411471f87433Sdalcinl 
4115fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
411671f87433Sdalcinl @*/
41177087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
411871f87433Sdalcinl {
411971f87433Sdalcinl   PetscFunctionBegin;
41200700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
412171f87433Sdalcinl   PetscValidPointer(flag,2);
412271f87433Sdalcinl   *flag = snes->ksp_ewconv;
412371f87433Sdalcinl   PetscFunctionReturn(0);
412471f87433Sdalcinl }
412571f87433Sdalcinl 
412671f87433Sdalcinl #undef __FUNCT__
4127fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
412871f87433Sdalcinl /*@
4129fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
413071f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
413171f87433Sdalcinl    Newton method.
413271f87433Sdalcinl 
41333f9fe445SBarry Smith    Logically Collective on SNES
413471f87433Sdalcinl 
413571f87433Sdalcinl    Input Parameters:
413671f87433Sdalcinl +    snes - SNES context
413771f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
413871f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
413971f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
414071f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
414171f87433Sdalcinl              (0 <= gamma2 <= 1)
414271f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
414371f87433Sdalcinl .    alpha2 - power for safeguard
414471f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
414571f87433Sdalcinl 
414671f87433Sdalcinl    Note:
414771f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
414871f87433Sdalcinl 
414971f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
415071f87433Sdalcinl 
415171f87433Sdalcinl    Level: advanced
415271f87433Sdalcinl 
415371f87433Sdalcinl    Reference:
415471f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
415571f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
415671f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
415771f87433Sdalcinl 
415871f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
415971f87433Sdalcinl 
4160fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
416171f87433Sdalcinl @*/
41627087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
416371f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
416471f87433Sdalcinl {
4165fa9f3622SBarry Smith   SNESKSPEW *kctx;
416671f87433Sdalcinl   PetscFunctionBegin;
41670700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4168fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4169e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
4170c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
4171c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
4172c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
4173c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
4174c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
4175c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
4176c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
417771f87433Sdalcinl 
417871f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
417971f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
418071f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
418171f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
418271f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
418371f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
418471f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
418571f87433Sdalcinl 
418671f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
4187e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
418871f87433Sdalcinl   }
418971f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
4190e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
419171f87433Sdalcinl   }
419271f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
4193e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
419471f87433Sdalcinl   }
419571f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
4196e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
419771f87433Sdalcinl   }
419871f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
4199e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
420071f87433Sdalcinl   }
420171f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
4202e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
420371f87433Sdalcinl   }
420471f87433Sdalcinl   PetscFunctionReturn(0);
420571f87433Sdalcinl }
420671f87433Sdalcinl 
420771f87433Sdalcinl #undef __FUNCT__
4208fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
420971f87433Sdalcinl /*@
4210fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
421171f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
421271f87433Sdalcinl    Newton method.
421371f87433Sdalcinl 
421471f87433Sdalcinl    Not Collective
421571f87433Sdalcinl 
421671f87433Sdalcinl    Input Parameters:
421771f87433Sdalcinl      snes - SNES context
421871f87433Sdalcinl 
421971f87433Sdalcinl    Output Parameters:
422071f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
422171f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
422271f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
422371f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
422471f87433Sdalcinl              (0 <= gamma2 <= 1)
422571f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
422671f87433Sdalcinl .    alpha2 - power for safeguard
422771f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
422871f87433Sdalcinl 
422971f87433Sdalcinl    Level: advanced
423071f87433Sdalcinl 
423171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
423271f87433Sdalcinl 
4233fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
423471f87433Sdalcinl @*/
42357087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
423671f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
423771f87433Sdalcinl {
4238fa9f3622SBarry Smith   SNESKSPEW *kctx;
423971f87433Sdalcinl   PetscFunctionBegin;
42400700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4241fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4242e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
424371f87433Sdalcinl   if(version)   *version   = kctx->version;
424471f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
424571f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
424671f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
424771f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
424871f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
424971f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
425071f87433Sdalcinl   PetscFunctionReturn(0);
425171f87433Sdalcinl }
425271f87433Sdalcinl 
425371f87433Sdalcinl #undef __FUNCT__
4254fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
4255fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
425671f87433Sdalcinl {
425771f87433Sdalcinl   PetscErrorCode ierr;
4258fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
425971f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
426071f87433Sdalcinl 
426171f87433Sdalcinl   PetscFunctionBegin;
4262e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
426371f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
426471f87433Sdalcinl     rtol = kctx->rtol_0;
426571f87433Sdalcinl   } else {
426671f87433Sdalcinl     if (kctx->version == 1) {
426771f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
426871f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
426971f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
427071f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
427171f87433Sdalcinl     } else if (kctx->version == 2) {
427271f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
427371f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
427471f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
427571f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
427671f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
427771f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
427871f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
427971f87433Sdalcinl       stol = PetscMax(rtol,stol);
428071f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
428171f87433Sdalcinl       /* safeguard: avoid oversolving */
428271f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
428371f87433Sdalcinl       stol = PetscMax(rtol,stol);
428471f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
4285e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
428671f87433Sdalcinl   }
428771f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
428871f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
428971f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
429071f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
429171f87433Sdalcinl   PetscFunctionReturn(0);
429271f87433Sdalcinl }
429371f87433Sdalcinl 
429471f87433Sdalcinl #undef __FUNCT__
4295fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
4296fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
429771f87433Sdalcinl {
429871f87433Sdalcinl   PetscErrorCode ierr;
4299fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
430071f87433Sdalcinl   PCSide         pcside;
430171f87433Sdalcinl   Vec            lres;
430271f87433Sdalcinl 
430371f87433Sdalcinl   PetscFunctionBegin;
4304e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
430571f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
430671f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
430771f87433Sdalcinl   if (kctx->version == 1) {
4308b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
430971f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
431071f87433Sdalcinl       /* KSP residual is true linear residual */
431171f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
431271f87433Sdalcinl     } else {
431371f87433Sdalcinl       /* KSP residual is preconditioned residual */
431471f87433Sdalcinl       /* compute true linear residual norm */
431571f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
431671f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
431771f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
431871f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
43196bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
432071f87433Sdalcinl     }
432171f87433Sdalcinl   }
432271f87433Sdalcinl   PetscFunctionReturn(0);
432371f87433Sdalcinl }
432471f87433Sdalcinl 
432571f87433Sdalcinl #undef __FUNCT__
432671f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
432771f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
432871f87433Sdalcinl {
432971f87433Sdalcinl   PetscErrorCode ierr;
433071f87433Sdalcinl 
433171f87433Sdalcinl   PetscFunctionBegin;
4332fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
433371f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
4334fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
433571f87433Sdalcinl   PetscFunctionReturn(0);
433671f87433Sdalcinl }
43376c699258SBarry Smith 
43386c699258SBarry Smith #undef __FUNCT__
43396c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
43406c699258SBarry Smith /*@
43416c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
43426c699258SBarry Smith 
43433f9fe445SBarry Smith    Logically Collective on SNES
43446c699258SBarry Smith 
43456c699258SBarry Smith    Input Parameters:
43466c699258SBarry Smith +  snes - the preconditioner context
43476c699258SBarry Smith -  dm - the dm
43486c699258SBarry Smith 
43496c699258SBarry Smith    Level: intermediate
43506c699258SBarry Smith 
43516c699258SBarry Smith 
43526c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
43536c699258SBarry Smith @*/
43547087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
43556c699258SBarry Smith {
43566c699258SBarry Smith   PetscErrorCode ierr;
4357345fed2cSBarry Smith   KSP            ksp;
43586cab3a1bSJed Brown   SNESDM         sdm;
43596c699258SBarry Smith 
43606c699258SBarry Smith   PetscFunctionBegin;
43610700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4362d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
43636cab3a1bSJed Brown   if (snes->dm) {               /* Move the SNESDM context over to the new DM unless the new DM already has one */
43646cab3a1bSJed Brown     PetscContainer oldcontainer,container;
43656cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr);
43666cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr);
43676cab3a1bSJed Brown     if (oldcontainer && !container) {
43686cab3a1bSJed Brown       ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr);
43696cab3a1bSJed Brown       ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr);
43706cab3a1bSJed Brown       if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */
43716cab3a1bSJed Brown         sdm->originaldm = dm;
43726cab3a1bSJed Brown       }
43736cab3a1bSJed Brown     }
43746bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
43756cab3a1bSJed Brown   }
43766c699258SBarry Smith   snes->dm = dm;
4377345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4378345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4379f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
43802c155ee1SBarry Smith   if (snes->pc) {
43812c155ee1SBarry Smith     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
43822c155ee1SBarry Smith   }
43836c699258SBarry Smith   PetscFunctionReturn(0);
43846c699258SBarry Smith }
43856c699258SBarry Smith 
43866c699258SBarry Smith #undef __FUNCT__
43876c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
43886c699258SBarry Smith /*@
43896c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
43906c699258SBarry Smith 
43913f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
43926c699258SBarry Smith 
43936c699258SBarry Smith    Input Parameter:
43946c699258SBarry Smith . snes - the preconditioner context
43956c699258SBarry Smith 
43966c699258SBarry Smith    Output Parameter:
43976c699258SBarry Smith .  dm - the dm
43986c699258SBarry Smith 
43996c699258SBarry Smith    Level: intermediate
44006c699258SBarry Smith 
44016c699258SBarry Smith 
44026c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
44036c699258SBarry Smith @*/
44047087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
44056c699258SBarry Smith {
44066cab3a1bSJed Brown   PetscErrorCode ierr;
44076cab3a1bSJed Brown 
44086c699258SBarry Smith   PetscFunctionBegin;
44090700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
44106cab3a1bSJed Brown   if (!snes->dm) {
44116cab3a1bSJed Brown     ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr);
44126cab3a1bSJed Brown   }
44136c699258SBarry Smith   *dm = snes->dm;
44146c699258SBarry Smith   PetscFunctionReturn(0);
44156c699258SBarry Smith }
44160807856dSBarry Smith 
441731823bd8SMatthew G Knepley #undef __FUNCT__
441831823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
441931823bd8SMatthew G Knepley /*@
4420fd4b34e9SJed Brown   SNESSetPC - Sets the nonlinear preconditioner to be used.
442131823bd8SMatthew G Knepley 
442231823bd8SMatthew G Knepley   Collective on SNES
442331823bd8SMatthew G Knepley 
442431823bd8SMatthew G Knepley   Input Parameters:
442531823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
442631823bd8SMatthew G Knepley - pc   - the preconditioner object
442731823bd8SMatthew G Knepley 
442831823bd8SMatthew G Knepley   Notes:
442931823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
443031823bd8SMatthew G Knepley   to configure it using the API).
443131823bd8SMatthew G Knepley 
443231823bd8SMatthew G Knepley   Level: developer
443331823bd8SMatthew G Knepley 
443431823bd8SMatthew G Knepley .keywords: SNES, set, precondition
443531823bd8SMatthew G Knepley .seealso: SNESGetPC()
443631823bd8SMatthew G Knepley @*/
443731823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
443831823bd8SMatthew G Knepley {
443931823bd8SMatthew G Knepley   PetscErrorCode ierr;
444031823bd8SMatthew G Knepley 
444131823bd8SMatthew G Knepley   PetscFunctionBegin;
444231823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
444331823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
444431823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
444531823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4446bf11d3b6SBarry Smith   ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr);
444731823bd8SMatthew G Knepley   snes->pc = pc;
444831823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
444931823bd8SMatthew G Knepley   PetscFunctionReturn(0);
445031823bd8SMatthew G Knepley }
445131823bd8SMatthew G Knepley 
445231823bd8SMatthew G Knepley #undef __FUNCT__
445331823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
445431823bd8SMatthew G Knepley /*@
4455fd4b34e9SJed Brown   SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().
445631823bd8SMatthew G Knepley 
445731823bd8SMatthew G Knepley   Not Collective
445831823bd8SMatthew G Knepley 
445931823bd8SMatthew G Knepley   Input Parameter:
446031823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
446131823bd8SMatthew G Knepley 
446231823bd8SMatthew G Knepley   Output Parameter:
446331823bd8SMatthew G Knepley . pc - preconditioner context
446431823bd8SMatthew G Knepley 
446531823bd8SMatthew G Knepley   Level: developer
446631823bd8SMatthew G Knepley 
446731823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
446831823bd8SMatthew G Knepley .seealso: SNESSetPC()
446931823bd8SMatthew G Knepley @*/
447031823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
447131823bd8SMatthew G Knepley {
447231823bd8SMatthew G Knepley   PetscErrorCode              ierr;
4473a64e098fSPeter Brune   const char                  *optionsprefix;
447431823bd8SMatthew G Knepley 
447531823bd8SMatthew G Knepley   PetscFunctionBegin;
447631823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
447731823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
447831823bd8SMatthew G Knepley   if (!snes->pc) {
447931823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm,&snes->pc);CHKERRQ(ierr);
44804a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);CHKERRQ(ierr);
448131823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes,snes->pc);CHKERRQ(ierr);
4482a64e098fSPeter Brune     ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr);
4483a64e098fSPeter Brune     ierr = SNESSetOptionsPrefix(snes->pc,optionsprefix);CHKERRQ(ierr);
4484a64e098fSPeter Brune     ierr = SNESAppendOptionsPrefix(snes->pc,"npc_");CHKERRQ(ierr);
448531823bd8SMatthew G Knepley   }
448631823bd8SMatthew G Knepley   *pc = snes->pc;
448731823bd8SMatthew G Knepley   PetscFunctionReturn(0);
448831823bd8SMatthew G Knepley }
448931823bd8SMatthew G Knepley 
44909e764e56SPeter Brune #undef __FUNCT__
4491f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch"
44929e764e56SPeter Brune /*@
44938141a3b9SPeter Brune   SNESSetSNESLineSearch - Sets the linesearch on the SNES instance.
44949e764e56SPeter Brune 
44959e764e56SPeter Brune   Collective on SNES
44969e764e56SPeter Brune 
44979e764e56SPeter Brune   Input Parameters:
44989e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
44999e764e56SPeter Brune - linesearch   - the linesearch object
45009e764e56SPeter Brune 
45019e764e56SPeter Brune   Notes:
4502f1c6b773SPeter Brune   Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example,
45039e764e56SPeter Brune   to configure it using the API).
45049e764e56SPeter Brune 
45059e764e56SPeter Brune   Level: developer
45069e764e56SPeter Brune 
45079e764e56SPeter Brune .keywords: SNES, set, linesearch
4508f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch()
45099e764e56SPeter Brune @*/
4510f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch)
45119e764e56SPeter Brune {
45129e764e56SPeter Brune   PetscErrorCode ierr;
45139e764e56SPeter Brune 
45149e764e56SPeter Brune   PetscFunctionBegin;
45159e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4516f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
45179e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
45189e764e56SPeter Brune   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
4519f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
45209e764e56SPeter Brune   snes->linesearch = linesearch;
45219e764e56SPeter Brune   ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
45229e764e56SPeter Brune   PetscFunctionReturn(0);
45239e764e56SPeter Brune }
45249e764e56SPeter Brune 
45259e764e56SPeter Brune #undef __FUNCT__
4526f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch"
4527ea5d4fccSPeter Brune /*@C
45288141a3b9SPeter Brune   SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch()
45298141a3b9SPeter Brune   or creates a default line search instance associated with the SNES and returns it.
45309e764e56SPeter Brune 
45319e764e56SPeter Brune   Not Collective
45329e764e56SPeter Brune 
45339e764e56SPeter Brune   Input Parameter:
45349e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
45359e764e56SPeter Brune 
45369e764e56SPeter Brune   Output Parameter:
45379e764e56SPeter Brune . linesearch - linesearch context
45389e764e56SPeter Brune 
45399e764e56SPeter Brune   Level: developer
45409e764e56SPeter Brune 
45419e764e56SPeter Brune .keywords: SNES, get, linesearch
4542f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch()
45439e764e56SPeter Brune @*/
4544f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch)
45459e764e56SPeter Brune {
45469e764e56SPeter Brune   PetscErrorCode ierr;
45479e764e56SPeter Brune   const char     *optionsprefix;
45489e764e56SPeter Brune 
45499e764e56SPeter Brune   PetscFunctionBegin;
45509e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
45519e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
45529e764e56SPeter Brune   if (!snes->linesearch) {
45539e764e56SPeter Brune     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
4554f1c6b773SPeter Brune     ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr);
4555f1c6b773SPeter Brune     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
4556b1dca40bSPeter Brune     ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr);
45579e764e56SPeter Brune     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
45589e764e56SPeter Brune     ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
45599e764e56SPeter Brune   }
45609e764e56SPeter Brune   *linesearch = snes->linesearch;
45619e764e56SPeter Brune   PetscFunctionReturn(0);
45629e764e56SPeter Brune }
45639e764e56SPeter Brune 
456469b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4565c6db04a5SJed Brown #include <mex.h>
456669b4f73cSBarry Smith 
45678f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
45688f6e6473SBarry Smith 
45690807856dSBarry Smith #undef __FUNCT__
45700807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
45710807856dSBarry Smith /*
45720807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
45730807856dSBarry Smith                          SNESSetFunctionMatlab().
45740807856dSBarry Smith 
45750807856dSBarry Smith    Collective on SNES
45760807856dSBarry Smith 
45770807856dSBarry Smith    Input Parameters:
45780807856dSBarry Smith +  snes - the SNES context
45790807856dSBarry Smith -  x - input vector
45800807856dSBarry Smith 
45810807856dSBarry Smith    Output Parameter:
45820807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
45830807856dSBarry Smith 
45840807856dSBarry Smith    Notes:
45850807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
45860807856dSBarry Smith    implementations, so most users would not generally call this routine
45870807856dSBarry Smith    themselves.
45880807856dSBarry Smith 
45890807856dSBarry Smith    Level: developer
45900807856dSBarry Smith 
45910807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
45920807856dSBarry Smith 
45930807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
459461b2408cSBarry Smith */
45957087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
45960807856dSBarry Smith {
4597e650e774SBarry Smith   PetscErrorCode    ierr;
45988f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
45998f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
46008f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
460191621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
4602e650e774SBarry Smith 
46030807856dSBarry Smith   PetscFunctionBegin;
46040807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
46050807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
46060807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
46070807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
46080807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
46090807856dSBarry Smith 
46100807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
4611e650e774SBarry Smith 
461291621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4613e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4614e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
461591621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
461691621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
461791621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
46188f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
46198f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
4620b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
4621e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4622e650e774SBarry Smith   mxDestroyArray(prhs[0]);
4623e650e774SBarry Smith   mxDestroyArray(prhs[1]);
4624e650e774SBarry Smith   mxDestroyArray(prhs[2]);
46258f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
4626e650e774SBarry Smith   mxDestroyArray(plhs[0]);
46270807856dSBarry Smith   PetscFunctionReturn(0);
46280807856dSBarry Smith }
46290807856dSBarry Smith 
46300807856dSBarry Smith 
46310807856dSBarry Smith #undef __FUNCT__
46320807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
463361b2408cSBarry Smith /*
46340807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
46350807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4636e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
46370807856dSBarry Smith 
46380807856dSBarry Smith    Logically Collective on SNES
46390807856dSBarry Smith 
46400807856dSBarry Smith    Input Parameters:
46410807856dSBarry Smith +  snes - the SNES context
46420807856dSBarry Smith .  r - vector to store function value
46430807856dSBarry Smith -  func - function evaluation routine
46440807856dSBarry Smith 
46450807856dSBarry Smith    Calling sequence of func:
464661b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
46470807856dSBarry Smith 
46480807856dSBarry Smith 
46490807856dSBarry Smith    Notes:
46500807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
46510807856dSBarry Smith $      f'(x) x = -f(x),
46520807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
46530807856dSBarry Smith 
46540807856dSBarry Smith    Level: beginner
46550807856dSBarry Smith 
46560807856dSBarry Smith .keywords: SNES, nonlinear, set, function
46570807856dSBarry Smith 
46580807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
465961b2408cSBarry Smith */
46607087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
46610807856dSBarry Smith {
46620807856dSBarry Smith   PetscErrorCode    ierr;
46638f6e6473SBarry Smith   SNESMatlabContext *sctx;
46640807856dSBarry Smith 
46650807856dSBarry Smith   PetscFunctionBegin;
46668f6e6473SBarry Smith   /* currently sctx is memory bleed */
46678f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
46688f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
46698f6e6473SBarry Smith   /*
46708f6e6473SBarry Smith      This should work, but it doesn't
46718f6e6473SBarry Smith   sctx->ctx = ctx;
46728f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
46738f6e6473SBarry Smith   */
46748f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
46758f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
46760807856dSBarry Smith   PetscFunctionReturn(0);
46770807856dSBarry Smith }
467869b4f73cSBarry Smith 
467961b2408cSBarry Smith #undef __FUNCT__
468061b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
468161b2408cSBarry Smith /*
468261b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
468361b2408cSBarry Smith                          SNESSetJacobianMatlab().
468461b2408cSBarry Smith 
468561b2408cSBarry Smith    Collective on SNES
468661b2408cSBarry Smith 
468761b2408cSBarry Smith    Input Parameters:
468861b2408cSBarry Smith +  snes - the SNES context
468961b2408cSBarry Smith .  x - input vector
469061b2408cSBarry Smith .  A, B - the matrices
469161b2408cSBarry Smith -  ctx - user context
469261b2408cSBarry Smith 
469361b2408cSBarry Smith    Output Parameter:
469461b2408cSBarry Smith .  flag - structure of the matrix
469561b2408cSBarry Smith 
469661b2408cSBarry Smith    Level: developer
469761b2408cSBarry Smith 
469861b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
469961b2408cSBarry Smith 
470061b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
470161b2408cSBarry Smith @*/
47027087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
470361b2408cSBarry Smith {
470461b2408cSBarry Smith   PetscErrorCode    ierr;
470561b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
470661b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
470761b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
470861b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
470961b2408cSBarry Smith 
471061b2408cSBarry Smith   PetscFunctionBegin;
471161b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
471261b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
471361b2408cSBarry Smith 
471461b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
471561b2408cSBarry Smith 
471661b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
471761b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
471861b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
471961b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
472061b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
472161b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
472261b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
472361b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
472461b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
472561b2408cSBarry Smith   prhs[5] =  sctx->ctx;
4726b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
472761b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
472861b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
472961b2408cSBarry Smith   mxDestroyArray(prhs[0]);
473061b2408cSBarry Smith   mxDestroyArray(prhs[1]);
473161b2408cSBarry Smith   mxDestroyArray(prhs[2]);
473261b2408cSBarry Smith   mxDestroyArray(prhs[3]);
473361b2408cSBarry Smith   mxDestroyArray(prhs[4]);
473461b2408cSBarry Smith   mxDestroyArray(plhs[0]);
473561b2408cSBarry Smith   mxDestroyArray(plhs[1]);
473661b2408cSBarry Smith   PetscFunctionReturn(0);
473761b2408cSBarry Smith }
473861b2408cSBarry Smith 
473961b2408cSBarry Smith 
474061b2408cSBarry Smith #undef __FUNCT__
474161b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
474261b2408cSBarry Smith /*
474361b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
474461b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4745e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
474661b2408cSBarry Smith 
474761b2408cSBarry Smith    Logically Collective on SNES
474861b2408cSBarry Smith 
474961b2408cSBarry Smith    Input Parameters:
475061b2408cSBarry Smith +  snes - the SNES context
475161b2408cSBarry Smith .  A,B - Jacobian matrices
475261b2408cSBarry Smith .  func - function evaluation routine
475361b2408cSBarry Smith -  ctx - user context
475461b2408cSBarry Smith 
475561b2408cSBarry Smith    Calling sequence of func:
475661b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
475761b2408cSBarry Smith 
475861b2408cSBarry Smith 
475961b2408cSBarry Smith    Level: developer
476061b2408cSBarry Smith 
476161b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
476261b2408cSBarry Smith 
476361b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
476461b2408cSBarry Smith */
47657087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
476661b2408cSBarry Smith {
476761b2408cSBarry Smith   PetscErrorCode    ierr;
476861b2408cSBarry Smith   SNESMatlabContext *sctx;
476961b2408cSBarry Smith 
477061b2408cSBarry Smith   PetscFunctionBegin;
477161b2408cSBarry Smith   /* currently sctx is memory bleed */
477261b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
477361b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
477461b2408cSBarry Smith   /*
477561b2408cSBarry Smith      This should work, but it doesn't
477661b2408cSBarry Smith   sctx->ctx = ctx;
477761b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
477861b2408cSBarry Smith   */
477961b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
478061b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
478161b2408cSBarry Smith   PetscFunctionReturn(0);
478261b2408cSBarry Smith }
478369b4f73cSBarry Smith 
4784f9eb7ae2SShri Abhyankar #undef __FUNCT__
4785f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
4786f9eb7ae2SShri Abhyankar /*
4787f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
4788f9eb7ae2SShri Abhyankar 
4789f9eb7ae2SShri Abhyankar    Collective on SNES
4790f9eb7ae2SShri Abhyankar 
4791f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
4792f9eb7ae2SShri Abhyankar @*/
47937087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
4794f9eb7ae2SShri Abhyankar {
4795f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
479648f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
4797f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
4798f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
4799f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
4800f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
4801f9eb7ae2SShri Abhyankar 
4802f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4803f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4804f9eb7ae2SShri Abhyankar 
4805f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4806f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4807f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
4808f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
4809f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
4810f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
4811f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
4812f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
4813f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
4814f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4815f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
4816f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
4817f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
4818f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
4819f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
4820f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
4821f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4822f9eb7ae2SShri Abhyankar }
4823f9eb7ae2SShri Abhyankar 
4824f9eb7ae2SShri Abhyankar 
4825f9eb7ae2SShri Abhyankar #undef __FUNCT__
4826f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
4827f9eb7ae2SShri Abhyankar /*
4828e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
4829f9eb7ae2SShri Abhyankar 
4830f9eb7ae2SShri Abhyankar    Level: developer
4831f9eb7ae2SShri Abhyankar 
4832f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
4833f9eb7ae2SShri Abhyankar 
4834f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
4835f9eb7ae2SShri Abhyankar */
48367087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
4837f9eb7ae2SShri Abhyankar {
4838f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
4839f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
4840f9eb7ae2SShri Abhyankar 
4841f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4842f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
4843f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
4844f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4845f9eb7ae2SShri Abhyankar   /*
4846f9eb7ae2SShri Abhyankar      This should work, but it doesn't
4847f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
4848f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
4849f9eb7ae2SShri Abhyankar   */
4850f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
4851f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4852f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4853f9eb7ae2SShri Abhyankar }
4854f9eb7ae2SShri Abhyankar 
485569b4f73cSBarry Smith #endif
4856