xref: /petsc/src/snes/interface/snes.c (revision 06f20277a5f718197c199b43a0fc3e6fc6fa4714)
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);
1919b94acceSBarry Smith     if (snes->ksp_ewconv) {
192fa9f3622SBarry Smith       kctx = (SNESKSPEW *)snes->kspconvctx;
1939b94acceSBarry Smith       if (kctx) {
19477431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr);
195a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr);
196a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr);
1979b94acceSBarry Smith       }
1989b94acceSBarry Smith     }
199eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
200eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");CHKERRQ(ierr);
201eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
202eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr);
203eb1f6c34SBarry Smith     }
204eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
205eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");CHKERRQ(ierr);
206eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
20742f4f86dSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr);
208eb1f6c34SBarry Smith     }
2090f5bd95cSBarry Smith   } else if (isstring) {
210317d6ea6SBarry Smith     const char *type;
211454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
212b0a32e0cSBarry Smith     ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr);
21319bcc07fSBarry Smith   }
21442f4f86dSBarry Smith   if (snes->pc && snes->usespc) {
2154a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2164a0c5b0cSMatthew G Knepley     ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr);
2174a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2184a0c5b0cSMatthew G Knepley   }
2192c155ee1SBarry Smith   if (snes->usesksp) {
2202c155ee1SBarry Smith     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
221b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
22294b7f48cSBarry Smith     ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
223b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2242c155ee1SBarry Smith   }
2257f1410a3SPeter Brune   if (snes->linesearch) {
2267f1410a3SPeter Brune     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2277f1410a3SPeter Brune     ierr = SNESGetSNESLineSearch(snes, &linesearch);CHKERRQ(ierr);
2287f1410a3SPeter Brune     ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr);
2297f1410a3SPeter Brune     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2307f1410a3SPeter Brune   }
2313a40ed3dSBarry Smith   PetscFunctionReturn(0);
2329b94acceSBarry Smith }
2339b94acceSBarry Smith 
23476b2cf59SMatthew Knepley /*
23576b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
23676b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
23776b2cf59SMatthew Knepley */
23876b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
239a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
2406849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
24176b2cf59SMatthew Knepley 
242e74ef692SMatthew Knepley #undef __FUNCT__
243e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker"
244ac226902SBarry Smith /*@C
24576b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
24676b2cf59SMatthew Knepley 
24776b2cf59SMatthew Knepley   Not Collective
24876b2cf59SMatthew Knepley 
24976b2cf59SMatthew Knepley   Input Parameter:
25076b2cf59SMatthew Knepley . snescheck - function that checks for options
25176b2cf59SMatthew Knepley 
25276b2cf59SMatthew Knepley   Level: developer
25376b2cf59SMatthew Knepley 
25476b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
25576b2cf59SMatthew Knepley @*/
2567087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
25776b2cf59SMatthew Knepley {
25876b2cf59SMatthew Knepley   PetscFunctionBegin;
25976b2cf59SMatthew Knepley   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
260e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
26176b2cf59SMatthew Knepley   }
26276b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
26376b2cf59SMatthew Knepley   PetscFunctionReturn(0);
26476b2cf59SMatthew Knepley }
26576b2cf59SMatthew Knepley 
2667087cfbeSBarry Smith extern PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
267aa3661deSLisandro Dalcin 
268aa3661deSLisandro Dalcin #undef __FUNCT__
269aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private"
270ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool  hasOperator, PetscInt version)
271aa3661deSLisandro Dalcin {
272aa3661deSLisandro Dalcin   Mat            J;
273aa3661deSLisandro Dalcin   KSP            ksp;
274aa3661deSLisandro Dalcin   PC             pc;
275ace3abfcSBarry Smith   PetscBool      match;
276aa3661deSLisandro Dalcin   PetscErrorCode ierr;
277aa3661deSLisandro Dalcin 
278aa3661deSLisandro Dalcin   PetscFunctionBegin;
2790700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
280aa3661deSLisandro Dalcin 
28198613b67SLisandro Dalcin   if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
28298613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
28398613b67SLisandro Dalcin     ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr);
28498613b67SLisandro Dalcin   }
28598613b67SLisandro Dalcin 
286aa3661deSLisandro Dalcin   if (version == 1) {
287aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
28898613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
2899c6ac3b3SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
290aa3661deSLisandro Dalcin   } else if (version == 2) {
291e32f2f54SBarry Smith     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
29282a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
293aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
294aa3661deSLisandro Dalcin #else
295e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
296aa3661deSLisandro Dalcin #endif
297a8248277SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
298aa3661deSLisandro Dalcin 
299aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
300d3462f78SMatthew Knepley   if (hasOperator) {
301aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
302aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
303aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
304aa3661deSLisandro Dalcin   } else {
305aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
306aa3661deSLisandro Dalcin        provided preconditioner matrix with the default matrix free version. */
3076cab3a1bSJed Brown     void *functx;
3086cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
3096cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
310aa3661deSLisandro Dalcin     /* Force no preconditioner */
311aa3661deSLisandro Dalcin     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
312aa3661deSLisandro Dalcin     ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
313251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
314aa3661deSLisandro Dalcin     if (!match) {
315aa3661deSLisandro Dalcin       ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
316aa3661deSLisandro Dalcin       ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
317aa3661deSLisandro Dalcin     }
318aa3661deSLisandro Dalcin   }
3196bf464f9SBarry Smith   ierr = MatDestroy(&J);CHKERRQ(ierr);
320aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
321aa3661deSLisandro Dalcin }
322aa3661deSLisandro Dalcin 
3234a2ae208SSatish Balay #undef __FUNCT__
324dfe15315SJed Brown #define __FUNCT__ "DMRestrictHook_SNESVecSol"
325dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx)
326dfe15315SJed Brown {
327dfe15315SJed Brown   SNES snes = (SNES)ctx;
328dfe15315SJed Brown   PetscErrorCode ierr;
329dfe15315SJed Brown   Vec Xfine,Xfine_named = PETSC_NULL,Xcoarse;
330dfe15315SJed Brown 
331dfe15315SJed Brown   PetscFunctionBegin;
332dfe15315SJed Brown   if (dmfine == snes->dm) Xfine = snes->vec_sol;
333dfe15315SJed Brown   else {
334dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);
335dfe15315SJed Brown     Xfine = Xfine_named;
336dfe15315SJed Brown   }
337dfe15315SJed Brown   ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
338dfe15315SJed Brown   ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr);
339dfe15315SJed Brown   ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr);
340dfe15315SJed Brown   ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
341dfe15315SJed Brown   if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);}
342dfe15315SJed Brown   PetscFunctionReturn(0);
343dfe15315SJed Brown }
344dfe15315SJed Brown 
345dfe15315SJed Brown #undef __FUNCT__
346caa4e7f2SJed Brown #define __FUNCT__ "KSPComputeOperators_SNES"
347a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can
348a6950cb2SJed Brown  * safely call SNESGetDM() in their residual evaluation routine. */
349caa4e7f2SJed Brown static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,MatStructure *mstruct,void *ctx)
350caa4e7f2SJed Brown {
351caa4e7f2SJed Brown   SNES snes = (SNES)ctx;
352caa4e7f2SJed Brown   PetscErrorCode ierr;
353caa4e7f2SJed Brown   Mat Asave = A,Bsave = B;
354dfe15315SJed Brown   Vec X,Xnamed = PETSC_NULL;
355dfe15315SJed Brown   DM dmsave;
356caa4e7f2SJed Brown 
357caa4e7f2SJed Brown   PetscFunctionBegin;
358dfe15315SJed Brown   dmsave = snes->dm;
359dfe15315SJed Brown   ierr = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr);
360dfe15315SJed Brown   if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */
361dfe15315SJed Brown   else {                                     /* We are on a coarser level, this vec was initialized using a DM restrict hook */
362dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
363dfe15315SJed Brown     X = Xnamed;
364dfe15315SJed Brown   }
365dfe15315SJed Brown   ierr = SNESComputeJacobian(snes,X,&A,&B,mstruct);CHKERRQ(ierr);
366caa4e7f2SJed Brown   if (A != Asave || B != Bsave) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_SUP,"No support for changing matrices at this time");
367dfe15315SJed Brown   if (Xnamed) {
368dfe15315SJed Brown     ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
369dfe15315SJed Brown   }
370dfe15315SJed Brown   snes->dm = dmsave;
371caa4e7f2SJed Brown   PetscFunctionReturn(0);
372caa4e7f2SJed Brown }
373caa4e7f2SJed Brown 
374caa4e7f2SJed Brown #undef __FUNCT__
3756cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices"
3766cab3a1bSJed Brown /*@
3776cab3a1bSJed Brown    SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX()
3786cab3a1bSJed Brown 
3796cab3a1bSJed Brown    Collective
3806cab3a1bSJed Brown 
3816cab3a1bSJed Brown    Input Arguments:
3826cab3a1bSJed Brown .  snes - snes to configure
3836cab3a1bSJed Brown 
3846cab3a1bSJed Brown    Level: developer
3856cab3a1bSJed Brown 
3866cab3a1bSJed Brown .seealso: SNESSetUp()
3876cab3a1bSJed Brown @*/
3886cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes)
3896cab3a1bSJed Brown {
3906cab3a1bSJed Brown   PetscErrorCode ierr;
3916cab3a1bSJed Brown   DM             dm;
3926cab3a1bSJed Brown   SNESDM         sdm;
3936cab3a1bSJed Brown 
3946cab3a1bSJed Brown   PetscFunctionBegin;
3956cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3966cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
397caa4e7f2SJed Brown   if (!sdm->computejacobian) {
3986cab3a1bSJed Brown     Mat J,B;
399*06f20277SJed Brown     void *functx;
4006cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4016cab3a1bSJed Brown     if (snes->mf_operator) {
4026cab3a1bSJed Brown       ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4036cab3a1bSJed Brown       ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4046cab3a1bSJed Brown       ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4056cab3a1bSJed Brown     } else {
4066cab3a1bSJed Brown       J = B;
4076cab3a1bSJed Brown       ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
4086cab3a1bSJed Brown     }
409*06f20277SJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
410*06f20277SJed Brown     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,functx);CHKERRQ(ierr);
4116cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
4126cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
4136cab3a1bSJed Brown   } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) {
4146cab3a1bSJed Brown     Mat J;
4156cab3a1bSJed Brown     void *functx;
4166cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4176cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4186cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4196cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
4206cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
4216cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
422caa4e7f2SJed Brown   } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
4236cab3a1bSJed Brown     Mat J,B;
4246cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4256cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4266cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4276cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
428*06f20277SJed Brown     /* sdm->computejacobian was already set to reach here */
429*06f20277SJed Brown     ierr = SNESSetJacobian(snes,J,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
4306cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
4316cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
432caa4e7f2SJed Brown   } else if (!snes->jacobian_pre) {
4336cab3a1bSJed Brown     Mat J,B;
4346cab3a1bSJed Brown     J = snes->jacobian;
4356cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4366cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
4376cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
4386cab3a1bSJed Brown   }
439caa4e7f2SJed Brown   {
44060a3618bSJed Brown     PetscBool flg = PETSC_FALSE;
441caa4e7f2SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_kspcompute",&flg,PETSC_NULL);CHKERRQ(ierr);
442caa4e7f2SJed Brown     if (flg) {                  /* Plan to transition to this model */
443caa4e7f2SJed Brown       KSP ksp;
444caa4e7f2SJed Brown       ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
445caa4e7f2SJed Brown       ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr);
446dfe15315SJed Brown       ierr = DMCoarsenHookAdd(snes->dm,PETSC_NULL,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr);
447caa4e7f2SJed Brown     }
448caa4e7f2SJed Brown   }
4496cab3a1bSJed Brown   PetscFunctionReturn(0);
4506cab3a1bSJed Brown }
4516cab3a1bSJed Brown 
4526cab3a1bSJed Brown #undef __FUNCT__
4534a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions"
4549b94acceSBarry Smith /*@
45594b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
4569b94acceSBarry Smith 
457c7afd0dbSLois Curfman McInnes    Collective on SNES
458c7afd0dbSLois Curfman McInnes 
4599b94acceSBarry Smith    Input Parameter:
4609b94acceSBarry Smith .  snes - the SNES context
4619b94acceSBarry Smith 
46236851e7fSLois Curfman McInnes    Options Database Keys:
463ea630c6eSPeter Brune +  -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas
46482738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
46582738288SBarry Smith                 of the change in the solution between steps
46670441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
467b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
468b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
469b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
4704839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
471ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
472a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
473e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
474b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
4752492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
47682738288SBarry Smith                                solver; hence iterations will continue until max_it
4771fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
47882738288SBarry Smith                                of convergence test
479e8105e01SRichard Katz .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
480e8105e01SRichard Katz                                        filename given prints to stdout
481a6570f20SBarry Smith .  -snes_monitor_solution - plots solution at each iteration
482a6570f20SBarry Smith .  -snes_monitor_residual - plots residual (not its norm) at each iteration
483a6570f20SBarry Smith .  -snes_monitor_solution_update - plots update to solution at each iteration
484a6570f20SBarry Smith .  -snes_monitor_draw - plots residual norm at each iteration
485e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
4865968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
487fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
48882738288SBarry Smith 
48982738288SBarry Smith     Options Database for Eisenstat-Walker method:
490fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
4914b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
49236851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
49336851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
49436851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
49536851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
49636851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
49736851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
49882738288SBarry Smith 
49911ca99fdSLois Curfman McInnes    Notes:
50011ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
5010598bfebSBarry Smith    the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>.
50283e2fdc7SBarry Smith 
50336851e7fSLois Curfman McInnes    Level: beginner
50436851e7fSLois Curfman McInnes 
5059b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
5069b94acceSBarry Smith 
50769ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
5089b94acceSBarry Smith @*/
5097087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
5109b94acceSBarry Smith {
511872b6db9SPeter Brune   PetscBool               flg,mf,mf_operator,pcset;
512efd51863SBarry Smith   PetscInt                i,indx,lag,mf_version,grids;
513aa3661deSLisandro Dalcin   MatStructure            matflag;
51485385478SLisandro Dalcin   const char              *deft = SNESLS;
51585385478SLisandro Dalcin   const char              *convtests[] = {"default","skip"};
51685385478SLisandro Dalcin   SNESKSPEW               *kctx = NULL;
517e8105e01SRichard Katz   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
518649052a6SBarry Smith   PetscViewer             monviewer;
51985385478SLisandro Dalcin   PetscErrorCode          ierr;
520a64e098fSPeter Brune   const char              *optionsprefix;
5219b94acceSBarry Smith 
5223a40ed3dSBarry Smith   PetscFunctionBegin;
5230700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
524ca161407SBarry Smith 
525186905e3SBarry Smith   if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
5263194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
5277adad957SLisandro Dalcin     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
528b0a32e0cSBarry Smith     ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
529d64ed03dSBarry Smith     if (flg) {
530186905e3SBarry Smith       ierr = SNESSetType(snes,type);CHKERRQ(ierr);
5317adad957SLisandro Dalcin     } else if (!((PetscObject)snes)->type_name) {
532186905e3SBarry Smith       ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
533d64ed03dSBarry Smith     }
53490d69ab7SBarry Smith     /* not used here, but called so will go into help messaage */
535909c8a9fSBarry Smith     ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr);
53693c39befSBarry Smith 
537c60f73f4SPeter Brune     ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);CHKERRQ(ierr);
53857034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr);
539186905e3SBarry Smith 
54057034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr);
541b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr);
542b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr);
54324254dc1SJed Brown     ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr);
544ddf469c8SBarry Smith     ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr);
545acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr);
54685385478SLisandro Dalcin 
547a8054027SBarry Smith     ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
548a8054027SBarry Smith     if (flg) {
549a8054027SBarry Smith       ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
550a8054027SBarry Smith     }
551e35cf81dSBarry Smith     ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
552e35cf81dSBarry Smith     if (flg) {
553e35cf81dSBarry Smith       ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
554e35cf81dSBarry Smith     }
555efd51863SBarry Smith     ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
556efd51863SBarry Smith     if (flg) {
557efd51863SBarry Smith       ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
558efd51863SBarry Smith     }
559a8054027SBarry Smith 
56085385478SLisandro Dalcin     ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
56185385478SLisandro Dalcin     if (flg) {
56285385478SLisandro Dalcin       switch (indx) {
5637f7931b9SBarry Smith       case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break;
5647f7931b9SBarry Smith       case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);    break;
56585385478SLisandro Dalcin       }
56685385478SLisandro Dalcin     }
56785385478SLisandro Dalcin 
568acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr);
569186905e3SBarry Smith 
570fdacfa88SPeter Brune     ierr = PetscOptionsEList("-snes_norm_type","SNES Norm type","SNESSetNormType",SNESNormTypes,5,"function",&indx,&flg);CHKERRQ(ierr);
571fdacfa88SPeter Brune     if (flg) { ierr = SNESSetNormType(snes,(SNESNormType)indx);CHKERRQ(ierr); }
572fdacfa88SPeter Brune 
57385385478SLisandro Dalcin     kctx = (SNESKSPEW *)snes->kspconvctx;
57485385478SLisandro Dalcin 
575acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr);
576186905e3SBarry Smith 
577fa9f3622SBarry Smith     ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr);
578fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr);
579fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr);
580fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr);
581fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr);
582fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr);
583fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr);
584186905e3SBarry Smith 
58590d69ab7SBarry Smith     flg  = PETSC_FALSE;
586acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
587a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
588eabae89aSBarry Smith 
589a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
590e8105e01SRichard Katz     if (flg) {
591649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
592649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
593e8105e01SRichard Katz     }
594eabae89aSBarry Smith 
595b271bb04SBarry Smith     ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
596b271bb04SBarry Smith     if (flg) {
597b271bb04SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr);
598b271bb04SBarry Smith     }
599b271bb04SBarry Smith 
600a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
601eabae89aSBarry Smith     if (flg) {
602649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
603f1bef1bcSMatthew Knepley       ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr);
604e8105e01SRichard Katz     }
605eabae89aSBarry Smith 
606a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
607eabae89aSBarry Smith     if (flg) {
608649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
609649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
610eabae89aSBarry Smith     }
611eabae89aSBarry Smith 
6125180491cSLisandro Dalcin     ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
6135180491cSLisandro Dalcin     if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);}
6145180491cSLisandro Dalcin 
61590d69ab7SBarry Smith     flg  = PETSC_FALSE;
616acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
617a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
61890d69ab7SBarry Smith     flg  = PETSC_FALSE;
619acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
620a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
62190d69ab7SBarry Smith     flg  = PETSC_FALSE;
622acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
623a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
62490d69ab7SBarry Smith     flg  = PETSC_FALSE;
625acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
626a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
62790d69ab7SBarry Smith     flg  = PETSC_FALSE;
628acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
629b271bb04SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
630e24b481bSBarry Smith 
63190d69ab7SBarry Smith     flg  = PETSC_FALSE;
632acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
6334b27c08aSLois Curfman McInnes     if (flg) {
6346cab3a1bSJed Brown       void *functx;
6356cab3a1bSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
6366cab3a1bSJed Brown       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr);
637ae15b995SBarry Smith       ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
6389b94acceSBarry Smith     }
639639f9d9dSBarry Smith 
640aa3661deSLisandro Dalcin     mf = mf_operator = PETSC_FALSE;
641aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
642acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr);
643a8248277SBarry Smith     if (flg && mf_operator) {
644a8248277SBarry Smith       snes->mf_operator = PETSC_TRUE;
645a8248277SBarry Smith       mf = PETSC_TRUE;
646a8248277SBarry Smith     }
647aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
648acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr);
649aa3661deSLisandro Dalcin     if (!flg && mf_operator) mf = PETSC_TRUE;
650aa3661deSLisandro Dalcin     mf_version = 1;
651aa3661deSLisandro Dalcin     ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr);
652aa3661deSLisandro Dalcin 
653d28543b3SPeter Brune 
65489b92e6fSPeter Brune     /* GS Options */
65589b92e6fSPeter Brune     ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr);
65689b92e6fSPeter Brune 
65776b2cf59SMatthew Knepley     for(i = 0; i < numberofsetfromoptions; i++) {
65876b2cf59SMatthew Knepley       ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
65976b2cf59SMatthew Knepley     }
66076b2cf59SMatthew Knepley 
661e7788613SBarry Smith     if (snes->ops->setfromoptions) {
662e7788613SBarry Smith       ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr);
663639f9d9dSBarry Smith     }
6645d973c19SBarry Smith 
6655d973c19SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
6665d973c19SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr);
667b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
6684bbc92c1SBarry Smith 
669aa3661deSLisandro Dalcin   if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); }
6701cee3971SBarry Smith 
6711cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
672aa3661deSLisandro Dalcin   ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
673aa3661deSLisandro Dalcin   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr);
67485385478SLisandro Dalcin   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
67593993e2dSLois Curfman McInnes 
6769e764e56SPeter Brune   if (!snes->linesearch) {
677f1c6b773SPeter Brune     ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
6789e764e56SPeter Brune   }
679f1c6b773SPeter Brune   ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr);
6809e764e56SPeter Brune 
68151e86f29SPeter Brune   /* if someone has set the SNES PC type, create it. */
68251e86f29SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
68351e86f29SPeter Brune   ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr);
68451e86f29SPeter Brune   if (pcset && (!snes->pc)) {
68551e86f29SPeter Brune     ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr);
68651e86f29SPeter Brune   }
6873a40ed3dSBarry Smith   PetscFunctionReturn(0);
6889b94acceSBarry Smith }
6899b94acceSBarry Smith 
690d25893d9SBarry Smith #undef __FUNCT__
691d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext"
692d25893d9SBarry Smith /*@
693d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
694d25893d9SBarry Smith    the nonlinear solvers.
695d25893d9SBarry Smith 
696d25893d9SBarry Smith    Logically Collective on SNES
697d25893d9SBarry Smith 
698d25893d9SBarry Smith    Input Parameters:
699d25893d9SBarry Smith +  snes - the SNES context
700d25893d9SBarry Smith .  compute - function to compute the context
701d25893d9SBarry Smith -  destroy - function to destroy the context
702d25893d9SBarry Smith 
703d25893d9SBarry Smith    Level: intermediate
704d25893d9SBarry Smith 
705d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
706d25893d9SBarry Smith 
707d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
708d25893d9SBarry Smith @*/
709d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
710d25893d9SBarry Smith {
711d25893d9SBarry Smith   PetscFunctionBegin;
712d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
713d25893d9SBarry Smith   snes->ops->usercompute = compute;
714d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
715d25893d9SBarry Smith   PetscFunctionReturn(0);
716d25893d9SBarry Smith }
717a847f771SSatish Balay 
7184a2ae208SSatish Balay #undef __FUNCT__
7194a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
720b07ff414SBarry Smith /*@
7219b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
7229b94acceSBarry Smith    the nonlinear solvers.
7239b94acceSBarry Smith 
7243f9fe445SBarry Smith    Logically Collective on SNES
725fee21e36SBarry Smith 
726c7afd0dbSLois Curfman McInnes    Input Parameters:
727c7afd0dbSLois Curfman McInnes +  snes - the SNES context
728c7afd0dbSLois Curfman McInnes -  usrP - optional user context
729c7afd0dbSLois Curfman McInnes 
73036851e7fSLois Curfman McInnes    Level: intermediate
73136851e7fSLois Curfman McInnes 
7329b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
7339b94acceSBarry Smith 
734ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext()
7359b94acceSBarry Smith @*/
7367087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
7379b94acceSBarry Smith {
7381b2093e4SBarry Smith   PetscErrorCode ierr;
739b07ff414SBarry Smith   KSP            ksp;
7401b2093e4SBarry Smith 
7413a40ed3dSBarry Smith   PetscFunctionBegin;
7420700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
743b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
744b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
7459b94acceSBarry Smith   snes->user = usrP;
7463a40ed3dSBarry Smith   PetscFunctionReturn(0);
7479b94acceSBarry Smith }
74874679c65SBarry Smith 
7494a2ae208SSatish Balay #undef __FUNCT__
7504a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
751b07ff414SBarry Smith /*@
7529b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
7539b94acceSBarry Smith    nonlinear solvers.
7549b94acceSBarry Smith 
755c7afd0dbSLois Curfman McInnes    Not Collective
756c7afd0dbSLois Curfman McInnes 
7579b94acceSBarry Smith    Input Parameter:
7589b94acceSBarry Smith .  snes - SNES context
7599b94acceSBarry Smith 
7609b94acceSBarry Smith    Output Parameter:
7619b94acceSBarry Smith .  usrP - user context
7629b94acceSBarry Smith 
76336851e7fSLois Curfman McInnes    Level: intermediate
76436851e7fSLois Curfman McInnes 
7659b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
7669b94acceSBarry Smith 
7679b94acceSBarry Smith .seealso: SNESSetApplicationContext()
7689b94acceSBarry Smith @*/
769e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
7709b94acceSBarry Smith {
7713a40ed3dSBarry Smith   PetscFunctionBegin;
7720700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
773e71120c6SJed Brown   *(void**)usrP = snes->user;
7743a40ed3dSBarry Smith   PetscFunctionReturn(0);
7759b94acceSBarry Smith }
77674679c65SBarry Smith 
7774a2ae208SSatish Balay #undef __FUNCT__
7784a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
7799b94acceSBarry Smith /*@
780c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
781c8228a4eSBarry Smith    at this time.
7829b94acceSBarry Smith 
783c7afd0dbSLois Curfman McInnes    Not Collective
784c7afd0dbSLois Curfman McInnes 
7859b94acceSBarry Smith    Input Parameter:
7869b94acceSBarry Smith .  snes - SNES context
7879b94acceSBarry Smith 
7889b94acceSBarry Smith    Output Parameter:
7899b94acceSBarry Smith .  iter - iteration number
7909b94acceSBarry Smith 
791c8228a4eSBarry Smith    Notes:
792c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
793c8228a4eSBarry Smith 
794c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
79508405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
79608405cd6SLois Curfman McInnes .vb
79708405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
79808405cd6SLois Curfman McInnes       if (!(it % 2)) {
79908405cd6SLois Curfman McInnes         [compute Jacobian here]
80008405cd6SLois Curfman McInnes       }
80108405cd6SLois Curfman McInnes .ve
802c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
80308405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
804c8228a4eSBarry Smith 
80536851e7fSLois Curfman McInnes    Level: intermediate
80636851e7fSLois Curfman McInnes 
8072b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
8082b668275SBarry Smith 
809b850b91aSLisandro Dalcin .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
8109b94acceSBarry Smith @*/
8117087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
8129b94acceSBarry Smith {
8133a40ed3dSBarry Smith   PetscFunctionBegin;
8140700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8154482741eSBarry Smith   PetscValidIntPointer(iter,2);
8169b94acceSBarry Smith   *iter = snes->iter;
8173a40ed3dSBarry Smith   PetscFunctionReturn(0);
8189b94acceSBarry Smith }
81974679c65SBarry Smith 
8204a2ae208SSatish Balay #undef __FUNCT__
821360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber"
822360c497dSPeter Brune /*@
823360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
824360c497dSPeter Brune 
825360c497dSPeter Brune    Not Collective
826360c497dSPeter Brune 
827360c497dSPeter Brune    Input Parameter:
828360c497dSPeter Brune .  snes - SNES context
829360c497dSPeter Brune .  iter - iteration number
830360c497dSPeter Brune 
831360c497dSPeter Brune    Level: developer
832360c497dSPeter Brune 
833360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number,
834360c497dSPeter Brune 
835360c497dSPeter Brune .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
836360c497dSPeter Brune @*/
837360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
838360c497dSPeter Brune {
839360c497dSPeter Brune   PetscErrorCode ierr;
840360c497dSPeter Brune 
841360c497dSPeter Brune   PetscFunctionBegin;
842360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
843360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
844360c497dSPeter Brune   snes->iter = iter;
845360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
846360c497dSPeter Brune   PetscFunctionReturn(0);
847360c497dSPeter Brune }
848360c497dSPeter Brune 
849360c497dSPeter Brune #undef __FUNCT__
8504a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm"
8519b94acceSBarry Smith /*@
8529b94acceSBarry Smith    SNESGetFunctionNorm - Gets the norm of the current function that was set
8539b94acceSBarry Smith    with SNESSSetFunction().
8549b94acceSBarry Smith 
855c7afd0dbSLois Curfman McInnes    Collective on SNES
856c7afd0dbSLois Curfman McInnes 
8579b94acceSBarry Smith    Input Parameter:
8589b94acceSBarry Smith .  snes - SNES context
8599b94acceSBarry Smith 
8609b94acceSBarry Smith    Output Parameter:
8619b94acceSBarry Smith .  fnorm - 2-norm of function
8629b94acceSBarry Smith 
86336851e7fSLois Curfman McInnes    Level: intermediate
86436851e7fSLois Curfman McInnes 
8659b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm
866a86d99e1SLois Curfman McInnes 
867b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
8689b94acceSBarry Smith @*/
8697087cfbeSBarry Smith PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
8709b94acceSBarry Smith {
8713a40ed3dSBarry Smith   PetscFunctionBegin;
8720700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8734482741eSBarry Smith   PetscValidScalarPointer(fnorm,2);
8749b94acceSBarry Smith   *fnorm = snes->norm;
8753a40ed3dSBarry Smith   PetscFunctionReturn(0);
8769b94acceSBarry Smith }
87774679c65SBarry Smith 
878360c497dSPeter Brune 
879360c497dSPeter Brune #undef __FUNCT__
880360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm"
881360c497dSPeter Brune /*@
882360c497dSPeter Brune    SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm().
883360c497dSPeter Brune 
884360c497dSPeter Brune    Collective on SNES
885360c497dSPeter Brune 
886360c497dSPeter Brune    Input Parameter:
887360c497dSPeter Brune .  snes - SNES context
888360c497dSPeter Brune .  fnorm - 2-norm of function
889360c497dSPeter Brune 
890360c497dSPeter Brune    Level: developer
891360c497dSPeter Brune 
892360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm
893360c497dSPeter Brune 
894360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm().
895360c497dSPeter Brune @*/
896360c497dSPeter Brune PetscErrorCode  SNESSetFunctionNorm(SNES snes,PetscReal fnorm)
897360c497dSPeter Brune {
898360c497dSPeter Brune 
899360c497dSPeter Brune   PetscErrorCode ierr;
900360c497dSPeter Brune 
901360c497dSPeter Brune   PetscFunctionBegin;
902360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
903360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
904360c497dSPeter Brune   snes->norm = fnorm;
905360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
906360c497dSPeter Brune   PetscFunctionReturn(0);
907360c497dSPeter Brune }
908360c497dSPeter Brune 
9094a2ae208SSatish Balay #undef __FUNCT__
910b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
9119b94acceSBarry Smith /*@
912b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
9139b94acceSBarry Smith    attempted by the nonlinear solver.
9149b94acceSBarry Smith 
915c7afd0dbSLois Curfman McInnes    Not Collective
916c7afd0dbSLois Curfman McInnes 
9179b94acceSBarry Smith    Input Parameter:
9189b94acceSBarry Smith .  snes - SNES context
9199b94acceSBarry Smith 
9209b94acceSBarry Smith    Output Parameter:
9219b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
9229b94acceSBarry Smith 
923c96a6f78SLois Curfman McInnes    Notes:
924c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
925c96a6f78SLois Curfman McInnes 
92636851e7fSLois Curfman McInnes    Level: intermediate
92736851e7fSLois Curfman McInnes 
9289b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
92958ebbce7SBarry Smith 
930e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
93158ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
9329b94acceSBarry Smith @*/
9337087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
9349b94acceSBarry Smith {
9353a40ed3dSBarry Smith   PetscFunctionBegin;
9360700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9374482741eSBarry Smith   PetscValidIntPointer(nfails,2);
93850ffb88aSMatthew Knepley   *nfails = snes->numFailures;
93950ffb88aSMatthew Knepley   PetscFunctionReturn(0);
94050ffb88aSMatthew Knepley }
94150ffb88aSMatthew Knepley 
94250ffb88aSMatthew Knepley #undef __FUNCT__
943b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
94450ffb88aSMatthew Knepley /*@
945b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
94650ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
94750ffb88aSMatthew Knepley 
94850ffb88aSMatthew Knepley    Not Collective
94950ffb88aSMatthew Knepley 
95050ffb88aSMatthew Knepley    Input Parameters:
95150ffb88aSMatthew Knepley +  snes     - SNES context
95250ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
95350ffb88aSMatthew Knepley 
95450ffb88aSMatthew Knepley    Level: intermediate
95550ffb88aSMatthew Knepley 
95650ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
95758ebbce7SBarry Smith 
958e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
95958ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
96050ffb88aSMatthew Knepley @*/
9617087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
96250ffb88aSMatthew Knepley {
96350ffb88aSMatthew Knepley   PetscFunctionBegin;
9640700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
96550ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
96650ffb88aSMatthew Knepley   PetscFunctionReturn(0);
96750ffb88aSMatthew Knepley }
96850ffb88aSMatthew Knepley 
96950ffb88aSMatthew Knepley #undef __FUNCT__
970b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
97150ffb88aSMatthew Knepley /*@
972b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
97350ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
97450ffb88aSMatthew Knepley 
97550ffb88aSMatthew Knepley    Not Collective
97650ffb88aSMatthew Knepley 
97750ffb88aSMatthew Knepley    Input Parameter:
97850ffb88aSMatthew Knepley .  snes     - SNES context
97950ffb88aSMatthew Knepley 
98050ffb88aSMatthew Knepley    Output Parameter:
98150ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
98250ffb88aSMatthew Knepley 
98350ffb88aSMatthew Knepley    Level: intermediate
98450ffb88aSMatthew Knepley 
98550ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
98658ebbce7SBarry Smith 
987e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
98858ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
98958ebbce7SBarry Smith 
99050ffb88aSMatthew Knepley @*/
9917087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
99250ffb88aSMatthew Knepley {
99350ffb88aSMatthew Knepley   PetscFunctionBegin;
9940700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9954482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
99650ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
9973a40ed3dSBarry Smith   PetscFunctionReturn(0);
9989b94acceSBarry Smith }
999a847f771SSatish Balay 
10004a2ae208SSatish Balay #undef __FUNCT__
10012541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
10022541af92SBarry Smith /*@
10032541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
10042541af92SBarry Smith      done by SNES.
10052541af92SBarry Smith 
10062541af92SBarry Smith    Not Collective
10072541af92SBarry Smith 
10082541af92SBarry Smith    Input Parameter:
10092541af92SBarry Smith .  snes     - SNES context
10102541af92SBarry Smith 
10112541af92SBarry Smith    Output Parameter:
10122541af92SBarry Smith .  nfuncs - number of evaluations
10132541af92SBarry Smith 
10142541af92SBarry Smith    Level: intermediate
10152541af92SBarry Smith 
10162541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
101758ebbce7SBarry Smith 
1018e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
10192541af92SBarry Smith @*/
10207087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
10212541af92SBarry Smith {
10222541af92SBarry Smith   PetscFunctionBegin;
10230700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10242541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
10252541af92SBarry Smith   *nfuncs = snes->nfuncs;
10262541af92SBarry Smith   PetscFunctionReturn(0);
10272541af92SBarry Smith }
10282541af92SBarry Smith 
10292541af92SBarry Smith #undef __FUNCT__
10303d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
10313d4c4710SBarry Smith /*@
10323d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
10333d4c4710SBarry Smith    linear solvers.
10343d4c4710SBarry Smith 
10353d4c4710SBarry Smith    Not Collective
10363d4c4710SBarry Smith 
10373d4c4710SBarry Smith    Input Parameter:
10383d4c4710SBarry Smith .  snes - SNES context
10393d4c4710SBarry Smith 
10403d4c4710SBarry Smith    Output Parameter:
10413d4c4710SBarry Smith .  nfails - number of failed solves
10423d4c4710SBarry Smith 
10433d4c4710SBarry Smith    Notes:
10443d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
10453d4c4710SBarry Smith 
10463d4c4710SBarry Smith    Level: intermediate
10473d4c4710SBarry Smith 
10483d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
104958ebbce7SBarry Smith 
1050e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
10513d4c4710SBarry Smith @*/
10527087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
10533d4c4710SBarry Smith {
10543d4c4710SBarry Smith   PetscFunctionBegin;
10550700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10563d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
10573d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
10583d4c4710SBarry Smith   PetscFunctionReturn(0);
10593d4c4710SBarry Smith }
10603d4c4710SBarry Smith 
10613d4c4710SBarry Smith #undef __FUNCT__
10623d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
10633d4c4710SBarry Smith /*@
10643d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
10653d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
10663d4c4710SBarry Smith 
10673f9fe445SBarry Smith    Logically Collective on SNES
10683d4c4710SBarry Smith 
10693d4c4710SBarry Smith    Input Parameters:
10703d4c4710SBarry Smith +  snes     - SNES context
10713d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
10723d4c4710SBarry Smith 
10733d4c4710SBarry Smith    Level: intermediate
10743d4c4710SBarry Smith 
1075a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
10763d4c4710SBarry Smith 
10773d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
10783d4c4710SBarry Smith 
107958ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
10803d4c4710SBarry Smith @*/
10817087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
10823d4c4710SBarry Smith {
10833d4c4710SBarry Smith   PetscFunctionBegin;
10840700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1085c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
10863d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
10873d4c4710SBarry Smith   PetscFunctionReturn(0);
10883d4c4710SBarry Smith }
10893d4c4710SBarry Smith 
10903d4c4710SBarry Smith #undef __FUNCT__
10913d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
10923d4c4710SBarry Smith /*@
10933d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
10943d4c4710SBarry Smith      are allowed before SNES terminates
10953d4c4710SBarry Smith 
10963d4c4710SBarry Smith    Not Collective
10973d4c4710SBarry Smith 
10983d4c4710SBarry Smith    Input Parameter:
10993d4c4710SBarry Smith .  snes     - SNES context
11003d4c4710SBarry Smith 
11013d4c4710SBarry Smith    Output Parameter:
11023d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
11033d4c4710SBarry Smith 
11043d4c4710SBarry Smith    Level: intermediate
11053d4c4710SBarry Smith 
11063d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
11073d4c4710SBarry Smith 
11083d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
11093d4c4710SBarry Smith 
1110e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
11113d4c4710SBarry Smith @*/
11127087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
11133d4c4710SBarry Smith {
11143d4c4710SBarry Smith   PetscFunctionBegin;
11150700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11163d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
11173d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
11183d4c4710SBarry Smith   PetscFunctionReturn(0);
11193d4c4710SBarry Smith }
11203d4c4710SBarry Smith 
11213d4c4710SBarry Smith #undef __FUNCT__
1122b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
1123c96a6f78SLois Curfman McInnes /*@
1124b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1125c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1126c96a6f78SLois Curfman McInnes 
1127c7afd0dbSLois Curfman McInnes    Not Collective
1128c7afd0dbSLois Curfman McInnes 
1129c96a6f78SLois Curfman McInnes    Input Parameter:
1130c96a6f78SLois Curfman McInnes .  snes - SNES context
1131c96a6f78SLois Curfman McInnes 
1132c96a6f78SLois Curfman McInnes    Output Parameter:
1133c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1134c96a6f78SLois Curfman McInnes 
1135c96a6f78SLois Curfman McInnes    Notes:
1136c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1137c96a6f78SLois Curfman McInnes 
113836851e7fSLois Curfman McInnes    Level: intermediate
113936851e7fSLois Curfman McInnes 
1140c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
11412b668275SBarry Smith 
11428c7482ecSBarry Smith .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
1143c96a6f78SLois Curfman McInnes @*/
11447087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
1145c96a6f78SLois Curfman McInnes {
11463a40ed3dSBarry Smith   PetscFunctionBegin;
11470700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11484482741eSBarry Smith   PetscValidIntPointer(lits,2);
1149c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
11503a40ed3dSBarry Smith   PetscFunctionReturn(0);
1151c96a6f78SLois Curfman McInnes }
1152c96a6f78SLois Curfman McInnes 
11534a2ae208SSatish Balay #undef __FUNCT__
115494b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP"
115552baeb72SSatish Balay /*@
115694b7f48cSBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
11579b94acceSBarry Smith 
115894b7f48cSBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
1159c7afd0dbSLois Curfman McInnes 
11609b94acceSBarry Smith    Input Parameter:
11619b94acceSBarry Smith .  snes - the SNES context
11629b94acceSBarry Smith 
11639b94acceSBarry Smith    Output Parameter:
116494b7f48cSBarry Smith .  ksp - the KSP context
11659b94acceSBarry Smith 
11669b94acceSBarry Smith    Notes:
116794b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
11689b94acceSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
11692999313aSBarry Smith    PC contexts as well.
11709b94acceSBarry Smith 
117136851e7fSLois Curfman McInnes    Level: beginner
117236851e7fSLois Curfman McInnes 
117394b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
11749b94acceSBarry Smith 
11752999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
11769b94acceSBarry Smith @*/
11777087cfbeSBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
11789b94acceSBarry Smith {
11791cee3971SBarry Smith   PetscErrorCode ierr;
11801cee3971SBarry Smith 
11813a40ed3dSBarry Smith   PetscFunctionBegin;
11820700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11834482741eSBarry Smith   PetscValidPointer(ksp,2);
11841cee3971SBarry Smith 
11851cee3971SBarry Smith   if (!snes->ksp) {
11861cee3971SBarry Smith     ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr);
11871cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
11881cee3971SBarry Smith     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
11891cee3971SBarry Smith   }
119094b7f48cSBarry Smith   *ksp = snes->ksp;
11913a40ed3dSBarry Smith   PetscFunctionReturn(0);
11929b94acceSBarry Smith }
119382bf6240SBarry Smith 
11944a2ae208SSatish Balay #undef __FUNCT__
11952999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
11962999313aSBarry Smith /*@
11972999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
11982999313aSBarry Smith 
11992999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
12002999313aSBarry Smith 
12012999313aSBarry Smith    Input Parameters:
12022999313aSBarry Smith +  snes - the SNES context
12032999313aSBarry Smith -  ksp - the KSP context
12042999313aSBarry Smith 
12052999313aSBarry Smith    Notes:
12062999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
12072999313aSBarry Smith    so this routine is rarely needed.
12082999313aSBarry Smith 
12092999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
12102999313aSBarry Smith    decreased by one.
12112999313aSBarry Smith 
12122999313aSBarry Smith    Level: developer
12132999313aSBarry Smith 
12142999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
12152999313aSBarry Smith 
12162999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
12172999313aSBarry Smith @*/
12187087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
12192999313aSBarry Smith {
12202999313aSBarry Smith   PetscErrorCode ierr;
12212999313aSBarry Smith 
12222999313aSBarry Smith   PetscFunctionBegin;
12230700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12240700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
12252999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
12267dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1227906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
12282999313aSBarry Smith   snes->ksp = ksp;
12292999313aSBarry Smith   PetscFunctionReturn(0);
12302999313aSBarry Smith }
12312999313aSBarry Smith 
12327adad957SLisandro Dalcin #if 0
12332999313aSBarry Smith #undef __FUNCT__
12344a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc"
12356849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
1236e24b481bSBarry Smith {
1237e24b481bSBarry Smith   PetscFunctionBegin;
1238e24b481bSBarry Smith   PetscFunctionReturn(0);
1239e24b481bSBarry Smith }
12407adad957SLisandro Dalcin #endif
1241e24b481bSBarry Smith 
12429b94acceSBarry Smith /* -----------------------------------------------------------*/
12434a2ae208SSatish Balay #undef __FUNCT__
12444a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
124552baeb72SSatish Balay /*@
12469b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
12479b94acceSBarry Smith 
1248c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1249c7afd0dbSLois Curfman McInnes 
1250c7afd0dbSLois Curfman McInnes    Input Parameters:
1251906ed7ccSBarry Smith .  comm - MPI communicator
12529b94acceSBarry Smith 
12539b94acceSBarry Smith    Output Parameter:
12549b94acceSBarry Smith .  outsnes - the new SNES context
12559b94acceSBarry Smith 
1256c7afd0dbSLois Curfman McInnes    Options Database Keys:
1257c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1258c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1259c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1260c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1261c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1262c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1263c1f60f51SBarry Smith 
126436851e7fSLois Curfman McInnes    Level: beginner
126536851e7fSLois Curfman McInnes 
12669b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
12679b94acceSBarry Smith 
1268a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1269a8054027SBarry Smith 
12709b94acceSBarry Smith @*/
12717087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
12729b94acceSBarry Smith {
1273dfbe8321SBarry Smith   PetscErrorCode      ierr;
12749b94acceSBarry Smith   SNES                snes;
1275fa9f3622SBarry Smith   SNESKSPEW           *kctx;
127637fcc0dbSBarry Smith 
12773a40ed3dSBarry Smith   PetscFunctionBegin;
1278ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
12798ba1e511SMatthew Knepley   *outsnes = PETSC_NULL;
12808ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
12818ba1e511SMatthew Knepley   ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr);
12828ba1e511SMatthew Knepley #endif
12838ba1e511SMatthew Knepley 
12843194b578SJed Brown   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
12857adad957SLisandro Dalcin 
128685385478SLisandro Dalcin   snes->ops->converged    = SNESDefaultConverged;
12872c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
128888976e71SPeter Brune   snes->tolerancesset     = PETSC_FALSE;
12899b94acceSBarry Smith   snes->max_its           = 50;
12909750a799SBarry Smith   snes->max_funcs         = 10000;
12919b94acceSBarry Smith   snes->norm              = 0.0;
1292fdacfa88SPeter Brune   snes->normtype          = SNES_NORM_FUNCTION;
1293b4874afaSBarry Smith   snes->rtol              = 1.e-8;
1294b4874afaSBarry Smith   snes->ttol              = 0.0;
129570441072SBarry Smith   snes->abstol            = 1.e-50;
1296c60f73f4SPeter Brune   snes->stol              = 1.e-8;
12974b27c08aSLois Curfman McInnes   snes->deltatol          = 1.e-12;
12989b94acceSBarry Smith   snes->nfuncs            = 0;
129950ffb88aSMatthew Knepley   snes->numFailures       = 0;
130050ffb88aSMatthew Knepley   snes->maxFailures       = 1;
13017a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1302e35cf81dSBarry Smith   snes->lagjacobian       = 1;
1303a8054027SBarry Smith   snes->lagpreconditioner = 1;
1304639f9d9dSBarry Smith   snes->numbermonitors    = 0;
13059b94acceSBarry Smith   snes->data              = 0;
13064dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1307186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
13086f24a144SLois Curfman McInnes   snes->nwork             = 0;
130958c9b817SLisandro Dalcin   snes->work              = 0;
131058c9b817SLisandro Dalcin   snes->nvwork            = 0;
131158c9b817SLisandro Dalcin   snes->vwork             = 0;
1312758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1313758f92a0SBarry Smith   snes->conv_hist_max     = 0;
1314758f92a0SBarry Smith   snes->conv_hist         = PETSC_NULL;
1315758f92a0SBarry Smith   snes->conv_hist_its     = PETSC_NULL;
1316758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1317e4ed7901SPeter Brune   snes->vec_func_init_set = PETSC_FALSE;
1318e4ed7901SPeter Brune   snes->norm_init         = 0.;
1319e4ed7901SPeter Brune   snes->norm_init_set     = PETSC_FALSE;
1320184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
132189b92e6fSPeter Brune   snes->gssweeps          = 1;
13229b94acceSBarry Smith 
13233d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
13243d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
13253d4c4710SBarry Smith 
13269b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
132738f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr);
13289b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
13299b94acceSBarry Smith   kctx->version     = 2;
13309b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
13319b94acceSBarry Smith                              this was too large for some test cases */
133275567043SBarry Smith   kctx->rtol_last   = 0.0;
13339b94acceSBarry Smith   kctx->rtol_max    = .9;
13349b94acceSBarry Smith   kctx->gamma       = 1.0;
133562d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
133671f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
13379b94acceSBarry Smith   kctx->threshold   = .1;
133875567043SBarry Smith   kctx->lresid_last = 0.0;
133975567043SBarry Smith   kctx->norm_last   = 0.0;
13409b94acceSBarry Smith 
13419b94acceSBarry Smith   *outsnes = snes;
13423a40ed3dSBarry Smith   PetscFunctionReturn(0);
13439b94acceSBarry Smith }
13449b94acceSBarry Smith 
13454a2ae208SSatish Balay #undef __FUNCT__
13464a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
13479b94acceSBarry Smith /*@C
13489b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
13499b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
13509b94acceSBarry Smith    equations.
13519b94acceSBarry Smith 
13523f9fe445SBarry Smith    Logically Collective on SNES
1353fee21e36SBarry Smith 
1354c7afd0dbSLois Curfman McInnes    Input Parameters:
1355c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1356c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1357de044059SHong Zhang .  func - function evaluation routine
1358c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1359c7afd0dbSLois Curfman McInnes          function evaluation routine (may be PETSC_NULL)
13609b94acceSBarry Smith 
1361c7afd0dbSLois Curfman McInnes    Calling sequence of func:
13628d76a1e5SLois Curfman McInnes $    func (SNES snes,Vec x,Vec f,void *ctx);
1363c7afd0dbSLois Curfman McInnes 
1364c586c404SJed Brown +  snes - the SNES context
1365c586c404SJed Brown .  x - state at which to evaluate residual
1366c586c404SJed Brown .  f - vector to put residual
1367c7afd0dbSLois Curfman McInnes -  ctx - optional user-defined function context
13689b94acceSBarry Smith 
13699b94acceSBarry Smith    Notes:
13709b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
13719b94acceSBarry Smith $      f'(x) x = -f(x),
1372c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
13739b94acceSBarry Smith 
137436851e7fSLois Curfman McInnes    Level: beginner
137536851e7fSLois Curfman McInnes 
13769b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
13779b94acceSBarry Smith 
13788b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard()
13799b94acceSBarry Smith @*/
13807087cfbeSBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
13819b94acceSBarry Smith {
138285385478SLisandro Dalcin   PetscErrorCode ierr;
13836cab3a1bSJed Brown   DM             dm;
13846cab3a1bSJed Brown 
13853a40ed3dSBarry Smith   PetscFunctionBegin;
13860700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1387d2a683ecSLisandro Dalcin   if (r) {
1388d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1389d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
139085385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
13916bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
139285385478SLisandro Dalcin     snes->vec_func = r;
1393d2a683ecSLisandro Dalcin   }
13946cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
13956cab3a1bSJed Brown   ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr);
13963a40ed3dSBarry Smith   PetscFunctionReturn(0);
13979b94acceSBarry Smith }
13989b94acceSBarry Smith 
1399646217ecSPeter Brune 
1400646217ecSPeter Brune #undef __FUNCT__
1401e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction"
1402e4ed7901SPeter Brune /*@C
1403e4ed7901SPeter Brune    SNESSetInitialFunction - Sets the function vector to be used as the
1404e4ed7901SPeter Brune    function norm at the initialization of the method.  In some
1405e4ed7901SPeter Brune    instances, the user has precomputed the function before calling
1406e4ed7901SPeter Brune    SNESSolve.  This function allows one to avoid a redundant call
1407e4ed7901SPeter Brune    to SNESComputeFunction in that case.
1408e4ed7901SPeter Brune 
1409e4ed7901SPeter Brune    Logically Collective on SNES
1410e4ed7901SPeter Brune 
1411e4ed7901SPeter Brune    Input Parameters:
1412e4ed7901SPeter Brune +  snes - the SNES context
1413e4ed7901SPeter Brune -  f - vector to store function value
1414e4ed7901SPeter Brune 
1415e4ed7901SPeter Brune    Notes:
1416e4ed7901SPeter Brune    This should not be modified during the solution procedure.
1417e4ed7901SPeter Brune 
1418e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1419e4ed7901SPeter Brune 
1420e4ed7901SPeter Brune    Level: developer
1421e4ed7901SPeter Brune 
1422e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function
1423e4ed7901SPeter Brune 
1424e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm()
1425e4ed7901SPeter Brune @*/
1426e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunction(SNES snes, Vec f)
1427e4ed7901SPeter Brune {
1428e4ed7901SPeter Brune   PetscErrorCode ierr;
1429e4ed7901SPeter Brune   Vec            vec_func;
1430e4ed7901SPeter Brune 
1431e4ed7901SPeter Brune   PetscFunctionBegin;
1432e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1433e4ed7901SPeter Brune   PetscValidHeaderSpecific(f,VEC_CLASSID,2);
1434e4ed7901SPeter Brune   PetscCheckSameComm(snes,1,f,2);
1435e4ed7901SPeter Brune   ierr = SNESGetFunction(snes,&vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
1436e4ed7901SPeter Brune   ierr = VecCopy(f, vec_func);CHKERRQ(ierr);
1437217b9c2eSPeter Brune   snes->vec_func_init_set = PETSC_TRUE;
1438e4ed7901SPeter Brune   PetscFunctionReturn(0);
1439e4ed7901SPeter Brune }
1440e4ed7901SPeter Brune 
1441e4ed7901SPeter Brune 
1442e4ed7901SPeter Brune #undef __FUNCT__
1443e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunctionNorm"
1444e4ed7901SPeter Brune /*@C
1445e4ed7901SPeter Brune    SNESSetInitialFunctionNorm - Sets the function norm to be used as the function norm
1446e4ed7901SPeter Brune    at the initialization of the  method.  In some instances, the user has precomputed
1447e4ed7901SPeter Brune    the function and its norm before calling SNESSolve.  This function allows one to
1448e4ed7901SPeter Brune    avoid a redundant call to SNESComputeFunction() and VecNorm() in that case.
1449e4ed7901SPeter Brune 
1450e4ed7901SPeter Brune    Logically Collective on SNES
1451e4ed7901SPeter Brune 
1452e4ed7901SPeter Brune    Input Parameters:
1453e4ed7901SPeter Brune +  snes - the SNES context
1454e4ed7901SPeter Brune -  fnorm - the norm of F as set by SNESSetInitialFunction()
1455e4ed7901SPeter Brune 
1456e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1457e4ed7901SPeter Brune 
1458e4ed7901SPeter Brune    Level: developer
1459e4ed7901SPeter Brune 
1460e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function, norm
1461e4ed7901SPeter Brune 
1462e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction()
1463e4ed7901SPeter Brune @*/
1464e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm)
1465e4ed7901SPeter Brune {
1466e4ed7901SPeter Brune   PetscFunctionBegin;
1467e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1468e4ed7901SPeter Brune   snes->norm_init = fnorm;
1469e4ed7901SPeter Brune   snes->norm_init_set = PETSC_TRUE;
1470e4ed7901SPeter Brune   PetscFunctionReturn(0);
1471e4ed7901SPeter Brune }
1472e4ed7901SPeter Brune 
1473e4ed7901SPeter Brune #undef __FUNCT__
1474534ebe21SPeter Brune #define __FUNCT__ "SNESSetNormType"
1475534ebe21SPeter Brune /*@
1476534ebe21SPeter Brune    SNESSetNormType - Sets the SNESNormType used in covergence and monitoring
1477534ebe21SPeter Brune    of the SNES method.
1478534ebe21SPeter Brune 
1479534ebe21SPeter Brune    Logically Collective on SNES
1480534ebe21SPeter Brune 
1481534ebe21SPeter Brune    Input Parameters:
1482534ebe21SPeter Brune +  snes - the SNES context
1483534ebe21SPeter Brune -  normtype - the type of the norm used
1484534ebe21SPeter Brune 
1485534ebe21SPeter Brune    Notes:
1486534ebe21SPeter Brune    Only certain SNES methods support certain SNESNormTypes.  Most require evaluation
1487534ebe21SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
1488534ebe21SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1489534ebe21SPeter Brune    (SNESGS) and the like do not require the norm of the function to be computed, and therfore
1490534ebe21SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
1491534ebe21SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
1492534ebe21SPeter Brune    their solution.
1493534ebe21SPeter Brune 
1494534ebe21SPeter Brune    Level: developer
1495534ebe21SPeter Brune 
1496534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1497534ebe21SPeter Brune 
1498534ebe21SPeter Brune .seealso: SNESGetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType
1499534ebe21SPeter Brune @*/
1500534ebe21SPeter Brune PetscErrorCode  SNESSetNormType(SNES snes, SNESNormType normtype)
1501534ebe21SPeter Brune {
1502534ebe21SPeter Brune   PetscFunctionBegin;
1503534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1504534ebe21SPeter Brune   snes->normtype = normtype;
1505534ebe21SPeter Brune   PetscFunctionReturn(0);
1506534ebe21SPeter Brune }
1507534ebe21SPeter Brune 
1508534ebe21SPeter Brune 
1509534ebe21SPeter Brune #undef __FUNCT__
1510534ebe21SPeter Brune #define __FUNCT__ "SNESGetNormType"
1511534ebe21SPeter Brune /*@
1512534ebe21SPeter Brune    SNESGetNormType - Gets the SNESNormType used in covergence and monitoring
1513534ebe21SPeter Brune    of the SNES method.
1514534ebe21SPeter Brune 
1515534ebe21SPeter Brune    Logically Collective on SNES
1516534ebe21SPeter Brune 
1517534ebe21SPeter Brune    Input Parameters:
1518534ebe21SPeter Brune +  snes - the SNES context
1519534ebe21SPeter Brune -  normtype - the type of the norm used
1520534ebe21SPeter Brune 
1521534ebe21SPeter Brune    Level: advanced
1522534ebe21SPeter Brune 
1523534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1524534ebe21SPeter Brune 
1525534ebe21SPeter Brune .seealso: SNESSetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType
1526534ebe21SPeter Brune @*/
1527534ebe21SPeter Brune PetscErrorCode  SNESGetNormType(SNES snes, SNESNormType *normtype)
1528534ebe21SPeter Brune {
1529534ebe21SPeter Brune   PetscFunctionBegin;
1530534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1531534ebe21SPeter Brune   *normtype = snes->normtype;
1532534ebe21SPeter Brune   PetscFunctionReturn(0);
1533534ebe21SPeter Brune }
1534534ebe21SPeter Brune 
1535534ebe21SPeter Brune #undef __FUNCT__
1536646217ecSPeter Brune #define __FUNCT__ "SNESSetGS"
1537c79ef259SPeter Brune /*@C
1538c79ef259SPeter Brune    SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for
1539c79ef259SPeter Brune    use with composed nonlinear solvers.
1540c79ef259SPeter Brune 
1541c79ef259SPeter Brune    Input Parameters:
1542c79ef259SPeter Brune +  snes   - the SNES context
1543c79ef259SPeter Brune .  gsfunc - function evaluation routine
1544c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
1545c79ef259SPeter Brune             smoother evaluation routine (may be PETSC_NULL)
1546c79ef259SPeter Brune 
1547c79ef259SPeter Brune    Calling sequence of func:
1548c79ef259SPeter Brune $    func (SNES snes,Vec x,Vec b,void *ctx);
1549c79ef259SPeter Brune 
1550c79ef259SPeter Brune +  X   - solution vector
1551c79ef259SPeter Brune .  B   - RHS vector
1552d28543b3SPeter Brune -  ctx - optional user-defined Gauss-Seidel context
1553c79ef259SPeter Brune 
1554c79ef259SPeter Brune    Notes:
1555c79ef259SPeter Brune    The GS routines are used by the composed nonlinear solver to generate
1556c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
1557c79ef259SPeter Brune 
1558d28543b3SPeter Brune    Level: intermediate
1559c79ef259SPeter Brune 
1560d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel
1561c79ef259SPeter Brune 
1562c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS()
1563c79ef259SPeter Brune @*/
15646cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx)
15656cab3a1bSJed Brown {
15666cab3a1bSJed Brown   PetscErrorCode ierr;
15676cab3a1bSJed Brown   DM dm;
15686cab3a1bSJed Brown 
1569646217ecSPeter Brune   PetscFunctionBegin;
15706cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15716cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
15726cab3a1bSJed Brown   ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr);
1573646217ecSPeter Brune   PetscFunctionReturn(0);
1574646217ecSPeter Brune }
1575646217ecSPeter Brune 
1576d25893d9SBarry Smith #undef __FUNCT__
157789b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps"
157889b92e6fSPeter Brune /*@
157989b92e6fSPeter Brune    SNESSetGSSweeps - Sets the number of sweeps of GS to use.
158089b92e6fSPeter Brune 
158189b92e6fSPeter Brune    Input Parameters:
158289b92e6fSPeter Brune +  snes   - the SNES context
158389b92e6fSPeter Brune -  sweeps  - the number of sweeps of GS to perform.
158489b92e6fSPeter Brune 
158589b92e6fSPeter Brune    Level: intermediate
158689b92e6fSPeter Brune 
158789b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
158889b92e6fSPeter Brune 
158989b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps()
159089b92e6fSPeter Brune @*/
159189b92e6fSPeter Brune 
159289b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) {
159389b92e6fSPeter Brune   PetscFunctionBegin;
159489b92e6fSPeter Brune   snes->gssweeps = sweeps;
159589b92e6fSPeter Brune   PetscFunctionReturn(0);
159689b92e6fSPeter Brune }
159789b92e6fSPeter Brune 
159889b92e6fSPeter Brune 
159989b92e6fSPeter Brune #undef __FUNCT__
160089b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps"
160189b92e6fSPeter Brune /*@
160289b92e6fSPeter Brune    SNESGetGSSweeps - Gets the number of sweeps GS will use.
160389b92e6fSPeter Brune 
160489b92e6fSPeter Brune    Input Parameters:
160589b92e6fSPeter Brune .  snes   - the SNES context
160689b92e6fSPeter Brune 
160789b92e6fSPeter Brune    Output Parameters:
160889b92e6fSPeter Brune .  sweeps  - the number of sweeps of GS to perform.
160989b92e6fSPeter Brune 
161089b92e6fSPeter Brune    Level: intermediate
161189b92e6fSPeter Brune 
161289b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
161389b92e6fSPeter Brune 
161489b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps()
161589b92e6fSPeter Brune @*/
161689b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) {
161789b92e6fSPeter Brune   PetscFunctionBegin;
161889b92e6fSPeter Brune   *sweeps = snes->gssweeps;
161989b92e6fSPeter Brune   PetscFunctionReturn(0);
162089b92e6fSPeter Brune }
162189b92e6fSPeter Brune 
162289b92e6fSPeter Brune #undef __FUNCT__
16238b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction"
16248b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
16258b0a5094SBarry Smith {
16268b0a5094SBarry Smith   PetscErrorCode ierr;
16276cab3a1bSJed Brown   void *functx,*jacctx;
16286cab3a1bSJed Brown 
16298b0a5094SBarry Smith   PetscFunctionBegin;
16306cab3a1bSJed Brown   ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
16316cab3a1bSJed Brown   ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr);
16328b0a5094SBarry Smith   /*  A(x)*x - b(x) */
16336cab3a1bSJed Brown   ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr);
16346cab3a1bSJed Brown   ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr);
16358b0a5094SBarry Smith   ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
16368b0a5094SBarry Smith   ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
16378b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
16388b0a5094SBarry Smith   ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr);
16398b0a5094SBarry Smith   PetscFunctionReturn(0);
16408b0a5094SBarry Smith }
16418b0a5094SBarry Smith 
16428b0a5094SBarry Smith #undef __FUNCT__
16438b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian"
16448b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
16458b0a5094SBarry Smith {
16468b0a5094SBarry Smith   PetscFunctionBegin;
16478b0a5094SBarry Smith   *flag = snes->matstruct;
16488b0a5094SBarry Smith   PetscFunctionReturn(0);
16498b0a5094SBarry Smith }
16508b0a5094SBarry Smith 
16518b0a5094SBarry Smith #undef __FUNCT__
16528b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard"
16538b0a5094SBarry Smith /*@C
16540d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
16558b0a5094SBarry Smith 
16568b0a5094SBarry Smith    Logically Collective on SNES
16578b0a5094SBarry Smith 
16588b0a5094SBarry Smith    Input Parameters:
16598b0a5094SBarry Smith +  snes - the SNES context
16608b0a5094SBarry Smith .  r - vector to store function value
16618b0a5094SBarry Smith .  func - function evaluation routine
16628b0a5094SBarry 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)
16638b0a5094SBarry Smith .  mat - matrix to store A
16648b0a5094SBarry Smith .  mfunc  - function to compute matrix value
16658b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
16668b0a5094SBarry Smith          function evaluation routine (may be PETSC_NULL)
16678b0a5094SBarry Smith 
16688b0a5094SBarry Smith    Calling sequence of func:
16698b0a5094SBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
16708b0a5094SBarry Smith 
16718b0a5094SBarry Smith +  f - function vector
16728b0a5094SBarry Smith -  ctx - optional user-defined function context
16738b0a5094SBarry Smith 
16748b0a5094SBarry Smith    Calling sequence of mfunc:
16758b0a5094SBarry Smith $     mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx);
16768b0a5094SBarry Smith 
16778b0a5094SBarry Smith +  x - input vector
16788b0a5094SBarry 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(),
16798b0a5094SBarry Smith           normally just pass mat in this location
16808b0a5094SBarry Smith .  mat - form A(x) matrix
16818b0a5094SBarry Smith .  flag - flag indicating information about the preconditioner matrix
16828b0a5094SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
16838b0a5094SBarry Smith -  ctx - [optional] user-defined Jacobian context
16848b0a5094SBarry Smith 
16858b0a5094SBarry Smith    Notes:
16868b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
16878b0a5094SBarry Smith 
16888b0a5094SBarry 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}
16898b0a5094SBarry 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.
16908b0a5094SBarry Smith 
16918b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
16928b0a5094SBarry Smith 
16930d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
16940d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
16958b0a5094SBarry Smith 
16968b0a5094SBarry 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
16978b0a5094SBarry 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
16988b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
16998b0a5094SBarry Smith 
17008b0a5094SBarry Smith    Level: beginner
17018b0a5094SBarry Smith 
17028b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function
17038b0a5094SBarry Smith 
17040d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard()
17058b0a5094SBarry Smith @*/
17068b0a5094SBarry 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)
17078b0a5094SBarry Smith {
17088b0a5094SBarry Smith   PetscErrorCode ierr;
17098b0a5094SBarry Smith   PetscFunctionBegin;
17108b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
17118b0a5094SBarry Smith   snes->ops->computepfunction = func;
17128b0a5094SBarry Smith   snes->ops->computepjacobian = mfunc;
17138b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
17148b0a5094SBarry Smith   ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
17158b0a5094SBarry Smith   PetscFunctionReturn(0);
17168b0a5094SBarry Smith }
17178b0a5094SBarry Smith 
17188b0a5094SBarry Smith #undef __FUNCT__
1719d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess"
1720d25893d9SBarry Smith /*@C
1721d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1722d25893d9SBarry Smith 
1723d25893d9SBarry Smith    Logically Collective on SNES
1724d25893d9SBarry Smith 
1725d25893d9SBarry Smith    Input Parameters:
1726d25893d9SBarry Smith +  snes - the SNES context
1727d25893d9SBarry Smith .  func - function evaluation routine
1728d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
1729d25893d9SBarry Smith          function evaluation routine (may be PETSC_NULL)
1730d25893d9SBarry Smith 
1731d25893d9SBarry Smith    Calling sequence of func:
1732d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
1733d25893d9SBarry Smith 
1734d25893d9SBarry Smith .  f - function vector
1735d25893d9SBarry Smith -  ctx - optional user-defined function context
1736d25893d9SBarry Smith 
1737d25893d9SBarry Smith    Level: intermediate
1738d25893d9SBarry Smith 
1739d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
1740d25893d9SBarry Smith 
1741d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1742d25893d9SBarry Smith @*/
1743d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1744d25893d9SBarry Smith {
1745d25893d9SBarry Smith   PetscFunctionBegin;
1746d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1747d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
1748d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
1749d25893d9SBarry Smith   PetscFunctionReturn(0);
1750d25893d9SBarry Smith }
1751d25893d9SBarry Smith 
17523ab0aad5SBarry Smith /* --------------------------------------------------------------- */
17533ab0aad5SBarry Smith #undef __FUNCT__
17541096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
17551096aae1SMatthew Knepley /*@C
17561096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
17571096aae1SMatthew Knepley    it assumes a zero right hand side.
17581096aae1SMatthew Knepley 
17593f9fe445SBarry Smith    Logically Collective on SNES
17601096aae1SMatthew Knepley 
17611096aae1SMatthew Knepley    Input Parameter:
17621096aae1SMatthew Knepley .  snes - the SNES context
17631096aae1SMatthew Knepley 
17641096aae1SMatthew Knepley    Output Parameter:
1765bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
17661096aae1SMatthew Knepley 
17671096aae1SMatthew Knepley    Level: intermediate
17681096aae1SMatthew Knepley 
17691096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
17701096aae1SMatthew Knepley 
177185385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
17721096aae1SMatthew Knepley @*/
17737087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
17741096aae1SMatthew Knepley {
17751096aae1SMatthew Knepley   PetscFunctionBegin;
17760700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
17771096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
177885385478SLisandro Dalcin   *rhs = snes->vec_rhs;
17791096aae1SMatthew Knepley   PetscFunctionReturn(0);
17801096aae1SMatthew Knepley }
17811096aae1SMatthew Knepley 
17821096aae1SMatthew Knepley #undef __FUNCT__
17834a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
17849b94acceSBarry Smith /*@
178536851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
17869b94acceSBarry Smith                          SNESSetFunction().
17879b94acceSBarry Smith 
1788c7afd0dbSLois Curfman McInnes    Collective on SNES
1789c7afd0dbSLois Curfman McInnes 
17909b94acceSBarry Smith    Input Parameters:
1791c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1792c7afd0dbSLois Curfman McInnes -  x - input vector
17939b94acceSBarry Smith 
17949b94acceSBarry Smith    Output Parameter:
17953638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
17969b94acceSBarry Smith 
17971bffabb2SLois Curfman McInnes    Notes:
179836851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
179936851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
180036851e7fSLois Curfman McInnes    themselves.
180136851e7fSLois Curfman McInnes 
180236851e7fSLois Curfman McInnes    Level: developer
180336851e7fSLois Curfman McInnes 
18049b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
18059b94acceSBarry Smith 
1806a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
18079b94acceSBarry Smith @*/
18087087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
18099b94acceSBarry Smith {
1810dfbe8321SBarry Smith   PetscErrorCode ierr;
18116cab3a1bSJed Brown   DM             dm;
18126cab3a1bSJed Brown   SNESDM         sdm;
18139b94acceSBarry Smith 
18143a40ed3dSBarry Smith   PetscFunctionBegin;
18150700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
18160700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
18170700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
1818c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
1819c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
18204ec14c9cSBarry Smith   VecValidValues(x,2,PETSC_TRUE);
1821184914b5SBarry Smith 
18226cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
18236cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
1824d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
18256cab3a1bSJed Brown   if (sdm->computefunction) {
1826d64ed03dSBarry Smith     PetscStackPush("SNES user function");
18276cab3a1bSJed Brown     ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
1828d64ed03dSBarry Smith     PetscStackPop;
182973250ac0SBarry Smith   } else if (snes->dm) {
1830644e2e5bSBarry Smith     ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr);
1831c90fad12SPeter Brune   } else if (snes->vec_rhs) {
1832c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
1833644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
183485385478SLisandro Dalcin   if (snes->vec_rhs) {
183585385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
18363ab0aad5SBarry Smith   }
1837ae3c334cSLois Curfman McInnes   snes->nfuncs++;
1838d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
18394ec14c9cSBarry Smith   VecValidValues(y,3,PETSC_FALSE);
18403a40ed3dSBarry Smith   PetscFunctionReturn(0);
18419b94acceSBarry Smith }
18429b94acceSBarry Smith 
18434a2ae208SSatish Balay #undef __FUNCT__
1844646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS"
1845c79ef259SPeter Brune /*@
1846c79ef259SPeter Brune    SNESComputeGS - Calls the Gauss-Seidel function that has been set with
1847c79ef259SPeter Brune                    SNESSetGS().
1848c79ef259SPeter Brune 
1849c79ef259SPeter Brune    Collective on SNES
1850c79ef259SPeter Brune 
1851c79ef259SPeter Brune    Input Parameters:
1852c79ef259SPeter Brune +  snes - the SNES context
1853c79ef259SPeter Brune .  x - input vector
1854c79ef259SPeter Brune -  b - rhs vector
1855c79ef259SPeter Brune 
1856c79ef259SPeter Brune    Output Parameter:
1857c79ef259SPeter Brune .  x - new solution vector
1858c79ef259SPeter Brune 
1859c79ef259SPeter Brune    Notes:
1860c79ef259SPeter Brune    SNESComputeGS() is typically used within composed nonlinear solver
1861c79ef259SPeter Brune    implementations, so most users would not generally call this routine
1862c79ef259SPeter Brune    themselves.
1863c79ef259SPeter Brune 
1864c79ef259SPeter Brune    Level: developer
1865c79ef259SPeter Brune 
1866c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function
1867c79ef259SPeter Brune 
1868c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction()
1869c79ef259SPeter Brune @*/
1870646217ecSPeter Brune PetscErrorCode  SNESComputeGS(SNES snes,Vec b,Vec x)
1871646217ecSPeter Brune {
1872646217ecSPeter Brune   PetscErrorCode ierr;
187389b92e6fSPeter Brune   PetscInt i;
18746cab3a1bSJed Brown   DM dm;
18756cab3a1bSJed Brown   SNESDM sdm;
1876646217ecSPeter Brune 
1877646217ecSPeter Brune   PetscFunctionBegin;
1878646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1879646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
1880646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
1881646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
1882646217ecSPeter Brune   if(b) PetscCheckSameComm(snes,1,b,3);
18834ec14c9cSBarry Smith   if (b) VecValidValues(b,2,PETSC_TRUE);
1884701cf23dSPeter Brune   ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
18856cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
18866cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
18876cab3a1bSJed Brown   if (sdm->computegs) {
188889b92e6fSPeter Brune     for (i = 0; i < snes->gssweeps; i++) {
1889646217ecSPeter Brune       PetscStackPush("SNES user GS");
18906cab3a1bSJed Brown       ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
1891646217ecSPeter Brune       PetscStackPop;
189289b92e6fSPeter Brune     }
1893646217ecSPeter Brune   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve().");
1894701cf23dSPeter Brune   ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
18954ec14c9cSBarry Smith   VecValidValues(x,3,PETSC_FALSE);
1896646217ecSPeter Brune   PetscFunctionReturn(0);
1897646217ecSPeter Brune }
1898646217ecSPeter Brune 
1899646217ecSPeter Brune 
1900646217ecSPeter Brune #undef __FUNCT__
19014a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
190262fef451SLois Curfman McInnes /*@
190362fef451SLois Curfman McInnes    SNESComputeJacobian - Computes the Jacobian matrix that has been
190462fef451SLois Curfman McInnes    set with SNESSetJacobian().
190562fef451SLois Curfman McInnes 
1906c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
1907c7afd0dbSLois Curfman McInnes 
190862fef451SLois Curfman McInnes    Input Parameters:
1909c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1910c7afd0dbSLois Curfman McInnes -  x - input vector
191162fef451SLois Curfman McInnes 
191262fef451SLois Curfman McInnes    Output Parameters:
1913c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
191462fef451SLois Curfman McInnes .  B - optional preconditioning matrix
19152b668275SBarry Smith -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1916fee21e36SBarry Smith 
1917e35cf81dSBarry Smith   Options Database Keys:
1918e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
1919693365a8SJed Brown .    -snes_lag_jacobian <lag>
1920693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
1921693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
1922693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
19234c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
1924c01495d3SJed Brown .    -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference
1925c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
1926c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
1927c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
1928c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
19294c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
1930c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
1931c01495d3SJed Brown 
1932e35cf81dSBarry Smith 
193362fef451SLois Curfman McInnes    Notes:
193462fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
193562fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
193662fef451SLois Curfman McInnes 
193794b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the
1938dc5a77f8SLois Curfman McInnes    flag parameter.
193962fef451SLois Curfman McInnes 
194036851e7fSLois Curfman McInnes    Level: developer
194136851e7fSLois Curfman McInnes 
194262fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
194362fef451SLois Curfman McInnes 
1944e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
194562fef451SLois Curfman McInnes @*/
19467087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
19479b94acceSBarry Smith {
1948dfbe8321SBarry Smith   PetscErrorCode ierr;
1949ace3abfcSBarry Smith   PetscBool      flag;
19506cab3a1bSJed Brown   DM             dm;
19516cab3a1bSJed Brown   SNESDM         sdm;
19523a40ed3dSBarry Smith 
19533a40ed3dSBarry Smith   PetscFunctionBegin;
19540700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
19550700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
19564482741eSBarry Smith   PetscValidPointer(flg,5);
1957c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
19584ec14c9cSBarry Smith   VecValidValues(X,2,PETSC_TRUE);
19596cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
19606cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
19616cab3a1bSJed Brown   if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
1962ebd3b9afSBarry Smith 
1963ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
1964ebd3b9afSBarry Smith 
1965fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
1966fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
1967fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
1968fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
1969e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1970e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
1971251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1972ebd3b9afSBarry Smith     if (flag) {
1973ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1974ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1975ebd3b9afSBarry Smith     }
1976e35cf81dSBarry Smith     PetscFunctionReturn(0);
1977e35cf81dSBarry Smith   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
1978e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1979e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
1980251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1981ebd3b9afSBarry Smith     if (flag) {
1982ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1983ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1984ebd3b9afSBarry Smith     }
1985e35cf81dSBarry Smith     PetscFunctionReturn(0);
1986e35cf81dSBarry Smith   }
1987e35cf81dSBarry Smith 
1988c4fc05e7SBarry Smith   *flg = DIFFERENT_NONZERO_PATTERN;
1989e35cf81dSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1990d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
19916cab3a1bSJed Brown   ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr);
1992d64ed03dSBarry Smith   PetscStackPop;
1993d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1994a8054027SBarry Smith 
19953b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
19963b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
19973b4f5425SBarry Smith     snes->lagpreconditioner = -1;
19983b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
1999a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
2000a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
2001a8054027SBarry Smith   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
2002a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
2003a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
2004a8054027SBarry Smith   }
2005a8054027SBarry Smith 
20066d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
20070700a824SBarry Smith   /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
20080700a824SBarry Smith     PetscValidHeaderSpecific(*B,MAT_CLASSID,4);   */
2009693365a8SJed Brown   {
2010693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
2011693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr);
2012693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
2013693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
2014693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr);
2015693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
2016693365a8SJed Brown       Mat Bexp_mine = PETSC_NULL,Bexp,FDexp;
2017693365a8SJed Brown       MatStructure mstruct;
2018693365a8SJed Brown       PetscViewer vdraw,vstdout;
20196b3a5b13SJed Brown       PetscBool flg;
2020693365a8SJed Brown       if (flag_operator) {
2021693365a8SJed Brown         ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr);
2022693365a8SJed Brown         Bexp = Bexp_mine;
2023693365a8SJed Brown       } else {
2024693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
2025251f4c67SDmitry Karpeev         ierr = PetscObjectTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
2026693365a8SJed Brown         if (flg) Bexp = *B;
2027693365a8SJed Brown         else {
2028693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
2029693365a8SJed Brown           ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr);
2030693365a8SJed Brown           Bexp = Bexp_mine;
2031693365a8SJed Brown         }
2032693365a8SJed Brown       }
2033693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
2034693365a8SJed Brown       ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr);
2035693365a8SJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
2036693365a8SJed Brown       if (flag_draw || flag_contour) {
2037693365a8SJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
2038693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
2039693365a8SJed Brown       } else vdraw = PETSC_NULL;
2040693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr);
2041693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
2042693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
2043693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
2044693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2045693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
2046693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2047693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
2048693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2049693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
2050693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
2051693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
2052693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
2053693365a8SJed Brown       }
2054693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
2055693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
2056693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
2057693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
2058693365a8SJed Brown     }
2059693365a8SJed Brown   }
20604c30e9fbSJed Brown   {
20616719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
20626719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
20634c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr);
20646719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr);
20654c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
20664c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
20676719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr);
20686719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr);
20696719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr);
20706719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
20714c30e9fbSJed Brown       Mat Bfd;
20724c30e9fbSJed Brown       MatStructure mstruct;
20734c30e9fbSJed Brown       PetscViewer vdraw,vstdout;
20744c30e9fbSJed Brown       ISColoring iscoloring;
20754c30e9fbSJed Brown       MatFDColoring matfdcoloring;
20764c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
20774c30e9fbSJed Brown       void *funcctx;
20786719d8e4SJed Brown       PetscReal norm1,norm2,normmax;
20794c30e9fbSJed Brown 
20804c30e9fbSJed Brown       ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
20814c30e9fbSJed Brown       ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
20824c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
20834c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
20844c30e9fbSJed Brown 
20854c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
20864c30e9fbSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr);
20874c30e9fbSJed Brown       ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr);
20884c30e9fbSJed Brown       ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
20894c30e9fbSJed Brown       ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
20904c30e9fbSJed Brown       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
20914c30e9fbSJed Brown       ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr);
20924c30e9fbSJed Brown       ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
20934c30e9fbSJed Brown 
20944c30e9fbSJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
20954c30e9fbSJed Brown       if (flag_draw || flag_contour) {
20964c30e9fbSJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
20974c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
20984c30e9fbSJed Brown       } else vdraw = PETSC_NULL;
20994c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
21006719d8e4SJed Brown       if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);}
21014c30e9fbSJed Brown       if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);}
21024c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
21036719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
21044c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
21054c30e9fbSJed Brown       ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
21064c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
21076719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
21084c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
21096719d8e4SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr);
21106719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
21114c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
21124c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
21134c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
21144c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
21154c30e9fbSJed Brown       }
21164c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
21176719d8e4SJed Brown 
21186719d8e4SJed Brown       if (flag_threshold) {
21196719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
21206719d8e4SJed Brown         ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr);
21216719d8e4SJed Brown         ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr);
21226719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
21236719d8e4SJed Brown           const PetscScalar *ba,*ca;
21246719d8e4SJed Brown           const PetscInt *bj,*cj;
21256719d8e4SJed Brown           PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
21266719d8e4SJed Brown           PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0;
21276719d8e4SJed Brown           ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
21286719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
21296719d8e4SJed Brown           if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
21306719d8e4SJed Brown           for (j=0; j<bn; j++) {
21316719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
21326719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
21336719d8e4SJed Brown               maxentrycol = bj[j];
21346719d8e4SJed Brown               maxentry = PetscRealPart(ba[j]);
21356719d8e4SJed Brown             }
21366719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
21376719d8e4SJed Brown               maxdiffcol = bj[j];
21386719d8e4SJed Brown               maxdiff = PetscRealPart(ca[j]);
21396719d8e4SJed Brown             }
21406719d8e4SJed Brown             if (rdiff > maxrdiff) {
21416719d8e4SJed Brown               maxrdiffcol = bj[j];
21426719d8e4SJed Brown               maxrdiff = rdiff;
21436719d8e4SJed Brown             }
21446719d8e4SJed Brown           }
21456719d8e4SJed Brown           if (maxrdiff > 1) {
21466719d8e4SJed 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);
21476719d8e4SJed Brown             for (j=0; j<bn; j++) {
21486719d8e4SJed Brown               PetscReal rdiff;
21496719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
21506719d8e4SJed Brown               if (rdiff > 1) {
21516719d8e4SJed Brown                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr);
21526719d8e4SJed Brown               }
21536719d8e4SJed Brown             }
21546719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
21556719d8e4SJed Brown           }
21566719d8e4SJed Brown           ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
21576719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
21586719d8e4SJed Brown         }
21596719d8e4SJed Brown       }
21604c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
21614c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
21624c30e9fbSJed Brown     }
21634c30e9fbSJed Brown   }
21643a40ed3dSBarry Smith   PetscFunctionReturn(0);
21659b94acceSBarry Smith }
21669b94acceSBarry Smith 
21674a2ae208SSatish Balay #undef __FUNCT__
21684a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
21699b94acceSBarry Smith /*@C
21709b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2171044dda88SLois Curfman McInnes    location to store the matrix.
21729b94acceSBarry Smith 
21733f9fe445SBarry Smith    Logically Collective on SNES and Mat
2174c7afd0dbSLois Curfman McInnes 
21759b94acceSBarry Smith    Input Parameters:
2176c7afd0dbSLois Curfman McInnes +  snes - the SNES context
21779b94acceSBarry Smith .  A - Jacobian matrix
21789b94acceSBarry Smith .  B - preconditioner matrix (usually same as the Jacobian)
2179efd51863SBarry Smith .  func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value)
2180c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
2181efd51863SBarry Smith          Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value)
21829b94acceSBarry Smith 
21839b94acceSBarry Smith    Calling sequence of func:
21848d76a1e5SLois Curfman McInnes $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
21859b94acceSBarry Smith 
2186c7afd0dbSLois Curfman McInnes +  x - input vector
21879b94acceSBarry Smith .  A - Jacobian matrix
21889b94acceSBarry Smith .  B - preconditioner matrix, usually the same as A
2189ac21db08SLois Curfman McInnes .  flag - flag indicating information about the preconditioner matrix
21902b668275SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
2191c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined Jacobian context
21929b94acceSBarry Smith 
21939b94acceSBarry Smith    Notes:
219494b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the flag
21952cd2dfdcSLois Curfman McInnes    output parameter in the routine func().  Be sure to read this information!
2196ac21db08SLois Curfman McInnes 
2197ac21db08SLois Curfman McInnes    The routine func() takes Mat * as the matrix arguments rather than Mat.
21989b94acceSBarry Smith    This allows the Jacobian evaluation routine to replace A and/or B with a
21999b94acceSBarry Smith    completely new new matrix structure (not just different matrix elements)
22009b94acceSBarry Smith    when appropriate, for instance, if the nonzero structure is changing
22019b94acceSBarry Smith    throughout the global iterations.
22029b94acceSBarry Smith 
220316913363SBarry Smith    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
220416913363SBarry Smith    each matrix.
220516913363SBarry Smith 
2206a8a26c1eSJed Brown    If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument
2207a8a26c1eSJed Brown    must be a MatFDColoring.
2208a8a26c1eSJed Brown 
2209c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2210c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2211c3cc8fd1SJed Brown 
221236851e7fSLois Curfman McInnes    Level: beginner
221336851e7fSLois Curfman McInnes 
22149b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
22159b94acceSBarry Smith 
22163ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
22179b94acceSBarry Smith @*/
22187087cfbeSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
22199b94acceSBarry Smith {
2220dfbe8321SBarry Smith   PetscErrorCode ierr;
22216cab3a1bSJed Brown   DM             dm;
22223a7fca6bSBarry Smith 
22233a40ed3dSBarry Smith   PetscFunctionBegin;
22240700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
22250700a824SBarry Smith   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
22260700a824SBarry Smith   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
2227c9780b6fSBarry Smith   if (A) PetscCheckSameComm(snes,1,A,2);
222806975374SJed Brown   if (B) PetscCheckSameComm(snes,1,B,3);
22296cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
22306cab3a1bSJed Brown   ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr);
22313a7fca6bSBarry Smith   if (A) {
22327dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
22336bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
22349b94acceSBarry Smith     snes->jacobian = A;
22353a7fca6bSBarry Smith   }
22363a7fca6bSBarry Smith   if (B) {
22377dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
22386bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
22399b94acceSBarry Smith     snes->jacobian_pre = B;
22403a7fca6bSBarry Smith   }
22413a40ed3dSBarry Smith   PetscFunctionReturn(0);
22429b94acceSBarry Smith }
224362fef451SLois Curfman McInnes 
22444a2ae208SSatish Balay #undef __FUNCT__
22454a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
2246c2aafc4cSSatish Balay /*@C
2247b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2248b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2249b4fd4287SBarry Smith 
2250c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2251c7afd0dbSLois Curfman McInnes 
2252b4fd4287SBarry Smith    Input Parameter:
2253b4fd4287SBarry Smith .  snes - the nonlinear solver context
2254b4fd4287SBarry Smith 
2255b4fd4287SBarry Smith    Output Parameters:
2256c7afd0dbSLois Curfman McInnes +  A - location to stash Jacobian matrix (or PETSC_NULL)
2257b4fd4287SBarry Smith .  B - location to stash preconditioner matrix (or PETSC_NULL)
225870e92668SMatthew Knepley .  func - location to put Jacobian function (or PETSC_NULL)
225970e92668SMatthew Knepley -  ctx - location to stash Jacobian ctx (or PETSC_NULL)
2260fee21e36SBarry Smith 
226136851e7fSLois Curfman McInnes    Level: advanced
226236851e7fSLois Curfman McInnes 
2263b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian()
2264b4fd4287SBarry Smith @*/
22657087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
2266b4fd4287SBarry Smith {
22676cab3a1bSJed Brown   PetscErrorCode ierr;
22686cab3a1bSJed Brown   DM             dm;
22696cab3a1bSJed Brown   SNESDM         sdm;
22706cab3a1bSJed Brown 
22713a40ed3dSBarry Smith   PetscFunctionBegin;
22720700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2273b4fd4287SBarry Smith   if (A)    *A    = snes->jacobian;
2274b4fd4287SBarry Smith   if (B)    *B    = snes->jacobian_pre;
22756cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
22766cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
22776cab3a1bSJed Brown   if (func) *func = sdm->computejacobian;
22786cab3a1bSJed Brown   if (ctx)  *ctx  = sdm->jacobianctx;
22793a40ed3dSBarry Smith   PetscFunctionReturn(0);
2280b4fd4287SBarry Smith }
2281b4fd4287SBarry Smith 
22829b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
22839b94acceSBarry Smith 
22844a2ae208SSatish Balay #undef __FUNCT__
22854a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
22869b94acceSBarry Smith /*@
22879b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
2288272ac6f2SLois Curfman McInnes    of a nonlinear solver.
22899b94acceSBarry Smith 
2290fee21e36SBarry Smith    Collective on SNES
2291fee21e36SBarry Smith 
2292c7afd0dbSLois Curfman McInnes    Input Parameters:
229370e92668SMatthew Knepley .  snes - the SNES context
2294c7afd0dbSLois Curfman McInnes 
2295272ac6f2SLois Curfman McInnes    Notes:
2296272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
2297272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
2298272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
2299272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
2300272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
2301272ac6f2SLois Curfman McInnes 
230236851e7fSLois Curfman McInnes    Level: advanced
230336851e7fSLois Curfman McInnes 
23049b94acceSBarry Smith .keywords: SNES, nonlinear, setup
23059b94acceSBarry Smith 
23069b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
23079b94acceSBarry Smith @*/
23087087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
23099b94acceSBarry Smith {
2310dfbe8321SBarry Smith   PetscErrorCode ierr;
23116cab3a1bSJed Brown   DM             dm;
23126cab3a1bSJed Brown   SNESDM         sdm;
23136e2a1849SPeter Brune   SNESLineSearch              linesearch;
23146e2a1849SPeter Brune   SNESLineSearch              pclinesearch;
23156e2a1849SPeter Brune   void                        *lsprectx,*lspostctx;
23166e2a1849SPeter Brune   SNESLineSearchPreCheckFunc  lsprefunc;
23176e2a1849SPeter Brune   SNESLineSearchPostCheckFunc lspostfunc;
23186e2a1849SPeter Brune   PetscErrorCode              (*func)(SNES,Vec,Vec,void*);
23196e2a1849SPeter Brune   Vec                         f,fpc;
23206e2a1849SPeter Brune   void                        *funcctx;
23216e2a1849SPeter Brune   PetscErrorCode              (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*);
23226e2a1849SPeter Brune   void                        *jacctx;
23236e2a1849SPeter Brune   Mat                         A,B;
23243a40ed3dSBarry Smith 
23253a40ed3dSBarry Smith   PetscFunctionBegin;
23260700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
23274dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
23289b94acceSBarry Smith 
23297adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
233085385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
233185385478SLisandro Dalcin   }
233285385478SLisandro Dalcin 
2333a63bb30eSJed Brown   ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
233417186662SBarry Smith   if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
233558c9b817SLisandro Dalcin   if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
233658c9b817SLisandro Dalcin 
233758c9b817SLisandro Dalcin   if (!snes->vec_sol_update /* && snes->vec_sol */) {
233858c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
233958c9b817SLisandro Dalcin     ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr);
234058c9b817SLisandro Dalcin   }
234158c9b817SLisandro Dalcin 
23426cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
23436cab3a1bSJed Brown   ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */
23446cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
23456cab3a1bSJed Brown   if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc");
23466cab3a1bSJed Brown   if (!snes->vec_func) {
23476cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2348214df951SJed Brown   }
2349efd51863SBarry Smith 
2350b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
2351b710008aSBarry Smith 
2352f1c6b773SPeter Brune   if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);}
23539e764e56SPeter Brune 
2354d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
2355d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
2356d25893d9SBarry Smith   }
2357d25893d9SBarry Smith 
23586e2a1849SPeter Brune   if (snes->pc) {
23596e2a1849SPeter Brune     /* copy the DM over */
23606e2a1849SPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
23616e2a1849SPeter Brune     ierr = SNESSetDM(snes->pc,dm);CHKERRQ(ierr);
23626e2a1849SPeter Brune 
23636e2a1849SPeter Brune     /* copy the legacy SNES context not related to the DM over*/
23646e2a1849SPeter Brune     ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr);
23656e2a1849SPeter Brune     ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr);
23666e2a1849SPeter Brune     ierr = SNESSetFunction(snes->pc,fpc,func,funcctx);CHKERRQ(ierr);
23676e2a1849SPeter Brune     ierr = SNESGetJacobian(snes,&A,&B,&jac,&jacctx);CHKERRQ(ierr);
23686e2a1849SPeter Brune     ierr = SNESSetJacobian(snes->pc,A,B,jac,jacctx);CHKERRQ(ierr);
23696e2a1849SPeter Brune     ierr = VecDestroy(&fpc);CHKERRQ(ierr);
23706e2a1849SPeter Brune 
23716e2a1849SPeter Brune     /* copy the function pointers over */
23726e2a1849SPeter Brune     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr);
23736e2a1849SPeter Brune 
23746e2a1849SPeter Brune      /* default to 1 iteration */
23756e2a1849SPeter Brune     ierr = SNESSetTolerances(snes->pc, snes->pc->abstol, snes->pc->rtol, snes->pc->stol, 1, snes->pc->max_funcs);CHKERRQ(ierr);
23766e2a1849SPeter Brune     ierr = SNESSetNormType(snes->pc, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr);
23776e2a1849SPeter Brune     ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr);
23786e2a1849SPeter Brune 
23796e2a1849SPeter Brune     /* copy the line search context over */
23806e2a1849SPeter Brune     ierr = SNESGetSNESLineSearch(snes,&linesearch);CHKERRQ(ierr);
23816e2a1849SPeter Brune     ierr = SNESGetSNESLineSearch(snes->pc,&pclinesearch);CHKERRQ(ierr);
23826e2a1849SPeter Brune     ierr = SNESLineSearchGetPreCheck(linesearch,&lsprefunc,&lsprectx);CHKERRQ(ierr);
23836e2a1849SPeter Brune     ierr = SNESLineSearchGetPostCheck(linesearch,&lspostfunc,&lspostctx);CHKERRQ(ierr);
23846e2a1849SPeter Brune     ierr = SNESLineSearchSetPreCheck(pclinesearch,lsprefunc,lsprectx);CHKERRQ(ierr);
23856e2a1849SPeter Brune     ierr = SNESLineSearchSetPostCheck(pclinesearch,lspostfunc,lspostctx);CHKERRQ(ierr);
23866e2a1849SPeter Brune     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr);
23876e2a1849SPeter Brune   }
23886e2a1849SPeter Brune 
2389410397dcSLisandro Dalcin   if (snes->ops->setup) {
2390410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2391410397dcSLisandro Dalcin   }
239258c9b817SLisandro Dalcin 
23937aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
23943a40ed3dSBarry Smith   PetscFunctionReturn(0);
23959b94acceSBarry Smith }
23969b94acceSBarry Smith 
23974a2ae208SSatish Balay #undef __FUNCT__
239837596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
239937596af1SLisandro Dalcin /*@
240037596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
240137596af1SLisandro Dalcin 
240237596af1SLisandro Dalcin    Collective on SNES
240337596af1SLisandro Dalcin 
240437596af1SLisandro Dalcin    Input Parameter:
240537596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
240637596af1SLisandro Dalcin 
2407d25893d9SBarry Smith    Level: intermediate
2408d25893d9SBarry Smith 
2409d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
241037596af1SLisandro Dalcin 
241137596af1SLisandro Dalcin .keywords: SNES, destroy
241237596af1SLisandro Dalcin 
241337596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
241437596af1SLisandro Dalcin @*/
241537596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
241637596af1SLisandro Dalcin {
241737596af1SLisandro Dalcin   PetscErrorCode ierr;
241837596af1SLisandro Dalcin 
241937596af1SLisandro Dalcin   PetscFunctionBegin;
242037596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2421d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
2422d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
2423d25893d9SBarry Smith     snes->user = PETSC_NULL;
2424d25893d9SBarry Smith   }
24258a23116dSBarry Smith   if (snes->pc) {
24268a23116dSBarry Smith     ierr = SNESReset(snes->pc);CHKERRQ(ierr);
24278a23116dSBarry Smith   }
24288a23116dSBarry Smith 
242937596af1SLisandro Dalcin   if (snes->ops->reset) {
243037596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
243137596af1SLisandro Dalcin   }
24329e764e56SPeter Brune   if (snes->ksp) {
24339e764e56SPeter Brune     ierr = KSPReset(snes->ksp);CHKERRQ(ierr);
24349e764e56SPeter Brune   }
24359e764e56SPeter Brune 
24369e764e56SPeter Brune   if (snes->linesearch) {
2437f1c6b773SPeter Brune     ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr);
24389e764e56SPeter Brune   }
24399e764e56SPeter Brune 
24406bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
24416bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
24426bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
24436bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
24446bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
24456bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2446c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
2447c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
244837596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
244937596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
245037596af1SLisandro Dalcin   PetscFunctionReturn(0);
245137596af1SLisandro Dalcin }
245237596af1SLisandro Dalcin 
245337596af1SLisandro Dalcin #undef __FUNCT__
24544a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
245552baeb72SSatish Balay /*@
24569b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
24579b94acceSBarry Smith    with SNESCreate().
24589b94acceSBarry Smith 
2459c7afd0dbSLois Curfman McInnes    Collective on SNES
2460c7afd0dbSLois Curfman McInnes 
24619b94acceSBarry Smith    Input Parameter:
24629b94acceSBarry Smith .  snes - the SNES context
24639b94acceSBarry Smith 
246436851e7fSLois Curfman McInnes    Level: beginner
246536851e7fSLois Curfman McInnes 
24669b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
24679b94acceSBarry Smith 
246863a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
24699b94acceSBarry Smith @*/
24706bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
24719b94acceSBarry Smith {
24726849ba73SBarry Smith   PetscErrorCode ierr;
24733a40ed3dSBarry Smith 
24743a40ed3dSBarry Smith   PetscFunctionBegin;
24756bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
24766bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
24776bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2478d4bb536fSBarry Smith 
24796bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
24808a23116dSBarry Smith   ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr);
24816b8b9a38SLisandro Dalcin 
2482be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
24836bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
24846bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
24856d4c513bSLisandro Dalcin 
24866bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
24876bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
2488f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr);
24896b8b9a38SLisandro Dalcin 
24906bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
24916bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
24926bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
24936b8b9a38SLisandro Dalcin   }
24946bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
24956bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
24966bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
249758c9b817SLisandro Dalcin   }
24986bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2499a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
25003a40ed3dSBarry Smith  PetscFunctionReturn(0);
25019b94acceSBarry Smith }
25029b94acceSBarry Smith 
25039b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
25049b94acceSBarry Smith 
25054a2ae208SSatish Balay #undef __FUNCT__
2506a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
2507a8054027SBarry Smith /*@
2508a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2509a8054027SBarry Smith 
25103f9fe445SBarry Smith    Logically Collective on SNES
2511a8054027SBarry Smith 
2512a8054027SBarry Smith    Input Parameters:
2513a8054027SBarry Smith +  snes - the SNES context
2514a8054027SBarry 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
25153b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2516a8054027SBarry Smith 
2517a8054027SBarry Smith    Options Database Keys:
2518a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2519a8054027SBarry Smith 
2520a8054027SBarry Smith    Notes:
2521a8054027SBarry Smith    The default is 1
2522a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2523a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2524a8054027SBarry Smith 
2525a8054027SBarry Smith    Level: intermediate
2526a8054027SBarry Smith 
2527a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2528a8054027SBarry Smith 
2529e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2530a8054027SBarry Smith 
2531a8054027SBarry Smith @*/
25327087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2533a8054027SBarry Smith {
2534a8054027SBarry Smith   PetscFunctionBegin;
25350700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2536e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2537e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2538c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2539a8054027SBarry Smith   snes->lagpreconditioner = lag;
2540a8054027SBarry Smith   PetscFunctionReturn(0);
2541a8054027SBarry Smith }
2542a8054027SBarry Smith 
2543a8054027SBarry Smith #undef __FUNCT__
2544efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
2545efd51863SBarry Smith /*@
2546efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2547efd51863SBarry Smith 
2548efd51863SBarry Smith    Logically Collective on SNES
2549efd51863SBarry Smith 
2550efd51863SBarry Smith    Input Parameters:
2551efd51863SBarry Smith +  snes - the SNES context
2552efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
2553efd51863SBarry Smith 
2554efd51863SBarry Smith    Options Database Keys:
2555efd51863SBarry Smith .    -snes_grid_sequence <steps>
2556efd51863SBarry Smith 
2557efd51863SBarry Smith    Level: intermediate
2558efd51863SBarry Smith 
2559c0df2a02SJed Brown    Notes:
2560c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2561c0df2a02SJed Brown 
2562efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2563efd51863SBarry Smith 
2564efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2565efd51863SBarry Smith 
2566efd51863SBarry Smith @*/
2567efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2568efd51863SBarry Smith {
2569efd51863SBarry Smith   PetscFunctionBegin;
2570efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2571efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
2572efd51863SBarry Smith   snes->gridsequence = steps;
2573efd51863SBarry Smith   PetscFunctionReturn(0);
2574efd51863SBarry Smith }
2575efd51863SBarry Smith 
2576efd51863SBarry Smith #undef __FUNCT__
2577a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
2578a8054027SBarry Smith /*@
2579a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
2580a8054027SBarry Smith 
25813f9fe445SBarry Smith    Not Collective
2582a8054027SBarry Smith 
2583a8054027SBarry Smith    Input Parameter:
2584a8054027SBarry Smith .  snes - the SNES context
2585a8054027SBarry Smith 
2586a8054027SBarry Smith    Output Parameter:
2587a8054027SBarry 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
25883b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2589a8054027SBarry Smith 
2590a8054027SBarry Smith    Options Database Keys:
2591a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2592a8054027SBarry Smith 
2593a8054027SBarry Smith    Notes:
2594a8054027SBarry Smith    The default is 1
2595a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2596a8054027SBarry Smith 
2597a8054027SBarry Smith    Level: intermediate
2598a8054027SBarry Smith 
2599a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2600a8054027SBarry Smith 
2601a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
2602a8054027SBarry Smith 
2603a8054027SBarry Smith @*/
26047087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
2605a8054027SBarry Smith {
2606a8054027SBarry Smith   PetscFunctionBegin;
26070700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2608a8054027SBarry Smith   *lag = snes->lagpreconditioner;
2609a8054027SBarry Smith   PetscFunctionReturn(0);
2610a8054027SBarry Smith }
2611a8054027SBarry Smith 
2612a8054027SBarry Smith #undef __FUNCT__
2613e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
2614e35cf81dSBarry Smith /*@
2615e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
2616e35cf81dSBarry Smith      often the preconditioner is rebuilt.
2617e35cf81dSBarry Smith 
26183f9fe445SBarry Smith    Logically Collective on SNES
2619e35cf81dSBarry Smith 
2620e35cf81dSBarry Smith    Input Parameters:
2621e35cf81dSBarry Smith +  snes - the SNES context
2622e35cf81dSBarry 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
2623fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
2624e35cf81dSBarry Smith 
2625e35cf81dSBarry Smith    Options Database Keys:
2626e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2627e35cf81dSBarry Smith 
2628e35cf81dSBarry Smith    Notes:
2629e35cf81dSBarry Smith    The default is 1
2630e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2631fe3ffe1eSBarry 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
2632fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
2633e35cf81dSBarry Smith 
2634e35cf81dSBarry Smith    Level: intermediate
2635e35cf81dSBarry Smith 
2636e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2637e35cf81dSBarry Smith 
2638e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
2639e35cf81dSBarry Smith 
2640e35cf81dSBarry Smith @*/
26417087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
2642e35cf81dSBarry Smith {
2643e35cf81dSBarry Smith   PetscFunctionBegin;
26440700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2645e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2646e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2647c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2648e35cf81dSBarry Smith   snes->lagjacobian = lag;
2649e35cf81dSBarry Smith   PetscFunctionReturn(0);
2650e35cf81dSBarry Smith }
2651e35cf81dSBarry Smith 
2652e35cf81dSBarry Smith #undef __FUNCT__
2653e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
2654e35cf81dSBarry Smith /*@
2655e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
2656e35cf81dSBarry Smith 
26573f9fe445SBarry Smith    Not Collective
2658e35cf81dSBarry Smith 
2659e35cf81dSBarry Smith    Input Parameter:
2660e35cf81dSBarry Smith .  snes - the SNES context
2661e35cf81dSBarry Smith 
2662e35cf81dSBarry Smith    Output Parameter:
2663e35cf81dSBarry 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
2664e35cf81dSBarry Smith          the Jacobian is built etc.
2665e35cf81dSBarry Smith 
2666e35cf81dSBarry Smith    Options Database Keys:
2667e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2668e35cf81dSBarry Smith 
2669e35cf81dSBarry Smith    Notes:
2670e35cf81dSBarry Smith    The default is 1
2671e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2672e35cf81dSBarry Smith 
2673e35cf81dSBarry Smith    Level: intermediate
2674e35cf81dSBarry Smith 
2675e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2676e35cf81dSBarry Smith 
2677e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
2678e35cf81dSBarry Smith 
2679e35cf81dSBarry Smith @*/
26807087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
2681e35cf81dSBarry Smith {
2682e35cf81dSBarry Smith   PetscFunctionBegin;
26830700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2684e35cf81dSBarry Smith   *lag = snes->lagjacobian;
2685e35cf81dSBarry Smith   PetscFunctionReturn(0);
2686e35cf81dSBarry Smith }
2687e35cf81dSBarry Smith 
2688e35cf81dSBarry Smith #undef __FUNCT__
26894a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
26909b94acceSBarry Smith /*@
2691d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
26929b94acceSBarry Smith 
26933f9fe445SBarry Smith    Logically Collective on SNES
2694c7afd0dbSLois Curfman McInnes 
26959b94acceSBarry Smith    Input Parameters:
2696c7afd0dbSLois Curfman McInnes +  snes - the SNES context
269770441072SBarry Smith .  abstol - absolute convergence tolerance
269833174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
269933174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
270033174efeSLois Curfman McInnes            of the change in the solution between steps
270133174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2702c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2703fee21e36SBarry Smith 
270433174efeSLois Curfman McInnes    Options Database Keys:
270570441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
2706c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
2707c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
2708c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
2709c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
27109b94acceSBarry Smith 
2711d7a720efSLois Curfman McInnes    Notes:
27129b94acceSBarry Smith    The default maximum number of iterations is 50.
27139b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
27149b94acceSBarry Smith 
271536851e7fSLois Curfman McInnes    Level: intermediate
271636851e7fSLois Curfman McInnes 
271733174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
27189b94acceSBarry Smith 
27192492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
27209b94acceSBarry Smith @*/
27217087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
27229b94acceSBarry Smith {
27233a40ed3dSBarry Smith   PetscFunctionBegin;
27240700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2725c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
2726c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
2727c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
2728c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
2729c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
2730c5eb9154SBarry Smith 
2731ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
2732ab54825eSJed Brown     if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol);
2733ab54825eSJed Brown     snes->abstol = abstol;
2734ab54825eSJed Brown   }
2735ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
2736ab54825eSJed 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);
2737ab54825eSJed Brown     snes->rtol = rtol;
2738ab54825eSJed Brown   }
2739ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
2740ab54825eSJed Brown     if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol);
2741c60f73f4SPeter Brune     snes->stol = stol;
2742ab54825eSJed Brown   }
2743ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
2744ab54825eSJed Brown     if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
2745ab54825eSJed Brown     snes->max_its = maxit;
2746ab54825eSJed Brown   }
2747ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
2748ab54825eSJed Brown     if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
2749ab54825eSJed Brown     snes->max_funcs = maxf;
2750ab54825eSJed Brown   }
275188976e71SPeter Brune   snes->tolerancesset = PETSC_TRUE;
27523a40ed3dSBarry Smith   PetscFunctionReturn(0);
27539b94acceSBarry Smith }
27549b94acceSBarry Smith 
27554a2ae208SSatish Balay #undef __FUNCT__
27564a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
27579b94acceSBarry Smith /*@
275833174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
275933174efeSLois Curfman McInnes 
2760c7afd0dbSLois Curfman McInnes    Not Collective
2761c7afd0dbSLois Curfman McInnes 
276233174efeSLois Curfman McInnes    Input Parameters:
2763c7afd0dbSLois Curfman McInnes +  snes - the SNES context
276485385478SLisandro Dalcin .  atol - absolute convergence tolerance
276533174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
276633174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
276733174efeSLois Curfman McInnes            of the change in the solution between steps
276833174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2769c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2770fee21e36SBarry Smith 
277133174efeSLois Curfman McInnes    Notes:
277233174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
277333174efeSLois Curfman McInnes 
277436851e7fSLois Curfman McInnes    Level: intermediate
277536851e7fSLois Curfman McInnes 
277633174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
277733174efeSLois Curfman McInnes 
277833174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
277933174efeSLois Curfman McInnes @*/
27807087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
278133174efeSLois Curfman McInnes {
27823a40ed3dSBarry Smith   PetscFunctionBegin;
27830700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
278485385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
278533174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
2786c60f73f4SPeter Brune   if (stol)  *stol  = snes->stol;
278733174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
278833174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
27893a40ed3dSBarry Smith   PetscFunctionReturn(0);
279033174efeSLois Curfman McInnes }
279133174efeSLois Curfman McInnes 
27924a2ae208SSatish Balay #undef __FUNCT__
27934a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
279433174efeSLois Curfman McInnes /*@
27959b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
27969b94acceSBarry Smith 
27973f9fe445SBarry Smith    Logically Collective on SNES
2798fee21e36SBarry Smith 
2799c7afd0dbSLois Curfman McInnes    Input Parameters:
2800c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2801c7afd0dbSLois Curfman McInnes -  tol - tolerance
2802c7afd0dbSLois Curfman McInnes 
28039b94acceSBarry Smith    Options Database Key:
2804c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
28059b94acceSBarry Smith 
280636851e7fSLois Curfman McInnes    Level: intermediate
280736851e7fSLois Curfman McInnes 
28089b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
28099b94acceSBarry Smith 
28102492ecdbSBarry Smith .seealso: SNESSetTolerances()
28119b94acceSBarry Smith @*/
28127087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
28139b94acceSBarry Smith {
28143a40ed3dSBarry Smith   PetscFunctionBegin;
28150700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2816c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
28179b94acceSBarry Smith   snes->deltatol = tol;
28183a40ed3dSBarry Smith   PetscFunctionReturn(0);
28199b94acceSBarry Smith }
28209b94acceSBarry Smith 
2821df9fa365SBarry Smith /*
2822df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
2823df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
2824df9fa365SBarry Smith    macros instead of functions
2825df9fa365SBarry Smith */
28264a2ae208SSatish Balay #undef __FUNCT__
2827a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
28287087cfbeSBarry Smith PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2829ce1608b8SBarry Smith {
2830dfbe8321SBarry Smith   PetscErrorCode ierr;
2831ce1608b8SBarry Smith 
2832ce1608b8SBarry Smith   PetscFunctionBegin;
28330700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2834a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
2835ce1608b8SBarry Smith   PetscFunctionReturn(0);
2836ce1608b8SBarry Smith }
2837ce1608b8SBarry Smith 
28384a2ae208SSatish Balay #undef __FUNCT__
2839a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
28407087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2841df9fa365SBarry Smith {
2842dfbe8321SBarry Smith   PetscErrorCode ierr;
2843df9fa365SBarry Smith 
2844df9fa365SBarry Smith   PetscFunctionBegin;
2845a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2846df9fa365SBarry Smith   PetscFunctionReturn(0);
2847df9fa365SBarry Smith }
2848df9fa365SBarry Smith 
28494a2ae208SSatish Balay #undef __FUNCT__
2850a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
28516bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
2852df9fa365SBarry Smith {
2853dfbe8321SBarry Smith   PetscErrorCode ierr;
2854df9fa365SBarry Smith 
2855df9fa365SBarry Smith   PetscFunctionBegin;
2856a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2857df9fa365SBarry Smith   PetscFunctionReturn(0);
2858df9fa365SBarry Smith }
2859df9fa365SBarry Smith 
28607087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
2861b271bb04SBarry Smith #undef __FUNCT__
2862b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
28637087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2864b271bb04SBarry Smith {
2865b271bb04SBarry Smith   PetscDrawLG      lg;
2866b271bb04SBarry Smith   PetscErrorCode   ierr;
2867b271bb04SBarry Smith   PetscReal        x,y,per;
2868b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
2869b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
2870b271bb04SBarry Smith   PetscDraw        draw;
2871b271bb04SBarry Smith   PetscFunctionBegin;
2872b271bb04SBarry Smith   if (!monctx) {
2873b271bb04SBarry Smith     MPI_Comm    comm;
2874b271bb04SBarry Smith 
2875b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2876b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
2877b271bb04SBarry Smith   }
2878b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
2879b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2880b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2881b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
2882b271bb04SBarry Smith   x = (PetscReal) n;
2883b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
2884b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2885b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2886b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2887b271bb04SBarry Smith   }
2888b271bb04SBarry Smith 
2889b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
2890b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2891b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2892b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
2893b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
2894b271bb04SBarry Smith   x = (PetscReal) n;
2895b271bb04SBarry Smith   y = 100.0*per;
2896b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2897b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2898b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2899b271bb04SBarry Smith   }
2900b271bb04SBarry Smith 
2901b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
2902b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2903b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2904b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
2905b271bb04SBarry Smith   x = (PetscReal) n;
2906b271bb04SBarry Smith   y = (prev - rnorm)/prev;
2907b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2908b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2909b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2910b271bb04SBarry Smith   }
2911b271bb04SBarry Smith 
2912b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
2913b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2914b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2915b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
2916b271bb04SBarry Smith   x = (PetscReal) n;
2917b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
2918b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
2919b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2920b271bb04SBarry Smith   }
2921b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2922b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2923b271bb04SBarry Smith   }
2924b271bb04SBarry Smith   prev = rnorm;
2925b271bb04SBarry Smith   PetscFunctionReturn(0);
2926b271bb04SBarry Smith }
2927b271bb04SBarry Smith 
2928b271bb04SBarry Smith #undef __FUNCT__
2929b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
29307087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2931b271bb04SBarry Smith {
2932b271bb04SBarry Smith   PetscErrorCode ierr;
2933b271bb04SBarry Smith 
2934b271bb04SBarry Smith   PetscFunctionBegin;
2935b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2936b271bb04SBarry Smith   PetscFunctionReturn(0);
2937b271bb04SBarry Smith }
2938b271bb04SBarry Smith 
2939b271bb04SBarry Smith #undef __FUNCT__
2940b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
29416bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG *draw)
2942b271bb04SBarry Smith {
2943b271bb04SBarry Smith   PetscErrorCode ierr;
2944b271bb04SBarry Smith 
2945b271bb04SBarry Smith   PetscFunctionBegin;
2946b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2947b271bb04SBarry Smith   PetscFunctionReturn(0);
2948b271bb04SBarry Smith }
2949b271bb04SBarry Smith 
29507a03ce2fSLisandro Dalcin #undef __FUNCT__
29517a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
2952228d79bcSJed Brown /*@
2953228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
2954228d79bcSJed Brown 
2955228d79bcSJed Brown    Collective on SNES
2956228d79bcSJed Brown 
2957228d79bcSJed Brown    Input Parameters:
2958228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
2959228d79bcSJed Brown .  iter - iteration number
2960228d79bcSJed Brown -  rnorm - relative norm of the residual
2961228d79bcSJed Brown 
2962228d79bcSJed Brown    Notes:
2963228d79bcSJed Brown    This routine is called by the SNES implementations.
2964228d79bcSJed Brown    It does not typically need to be called by the user.
2965228d79bcSJed Brown 
2966228d79bcSJed Brown    Level: developer
2967228d79bcSJed Brown 
2968228d79bcSJed Brown .seealso: SNESMonitorSet()
2969228d79bcSJed Brown @*/
29707a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
29717a03ce2fSLisandro Dalcin {
29727a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
29737a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
29747a03ce2fSLisandro Dalcin 
29757a03ce2fSLisandro Dalcin   PetscFunctionBegin;
29767a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
29777a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
29787a03ce2fSLisandro Dalcin   }
29797a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
29807a03ce2fSLisandro Dalcin }
29817a03ce2fSLisandro Dalcin 
29829b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
29839b94acceSBarry Smith 
29844a2ae208SSatish Balay #undef __FUNCT__
2985a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
29869b94acceSBarry Smith /*@C
2987a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
29889b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
29899b94acceSBarry Smith    progress.
29909b94acceSBarry Smith 
29913f9fe445SBarry Smith    Logically Collective on SNES
2992fee21e36SBarry Smith 
2993c7afd0dbSLois Curfman McInnes    Input Parameters:
2994c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2995c7afd0dbSLois Curfman McInnes .  func - monitoring routine
2996b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
2997e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
2998b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
2999b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
30009b94acceSBarry Smith 
3001c7afd0dbSLois Curfman McInnes    Calling sequence of func:
3002a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
3003c7afd0dbSLois Curfman McInnes 
3004c7afd0dbSLois Curfman McInnes +    snes - the SNES context
3005c7afd0dbSLois Curfman McInnes .    its - iteration number
3006c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
300740a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
30089b94acceSBarry Smith 
30099665c990SLois Curfman McInnes    Options Database Keys:
3010a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
3011a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
3012a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
3013cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
3014c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
3015a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
3016c7afd0dbSLois Curfman McInnes                             does not cancel those set via
3017c7afd0dbSLois Curfman McInnes                             the options database.
30189665c990SLois Curfman McInnes 
3019639f9d9dSBarry Smith    Notes:
30206bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
3021a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
30226bc08f3fSLois Curfman McInnes    order in which they were set.
3023639f9d9dSBarry Smith 
3024025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
3025025f1a04SBarry Smith 
302636851e7fSLois Curfman McInnes    Level: intermediate
302736851e7fSLois Curfman McInnes 
30289b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
30299b94acceSBarry Smith 
3030a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
30319b94acceSBarry Smith @*/
3032c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
30339b94acceSBarry Smith {
3034b90d0a6eSBarry Smith   PetscInt       i;
3035649052a6SBarry Smith   PetscErrorCode ierr;
3036b90d0a6eSBarry Smith 
30373a40ed3dSBarry Smith   PetscFunctionBegin;
30380700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
303917186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
3040b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
3041649052a6SBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
3042649052a6SBarry Smith       if (monitordestroy) {
3043c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
3044649052a6SBarry Smith       }
3045b90d0a6eSBarry Smith       PetscFunctionReturn(0);
3046b90d0a6eSBarry Smith     }
3047b90d0a6eSBarry Smith   }
3048b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
3049b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
3050639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
30513a40ed3dSBarry Smith   PetscFunctionReturn(0);
30529b94acceSBarry Smith }
30539b94acceSBarry Smith 
30544a2ae208SSatish Balay #undef __FUNCT__
3055a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
30565cd90555SBarry Smith /*@C
3057a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
30585cd90555SBarry Smith 
30593f9fe445SBarry Smith    Logically Collective on SNES
3060c7afd0dbSLois Curfman McInnes 
30615cd90555SBarry Smith    Input Parameters:
30625cd90555SBarry Smith .  snes - the SNES context
30635cd90555SBarry Smith 
30641a480d89SAdministrator    Options Database Key:
3065a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
3066a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
3067c7afd0dbSLois Curfman McInnes     set via the options database
30685cd90555SBarry Smith 
30695cd90555SBarry Smith    Notes:
30705cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
30715cd90555SBarry Smith 
307236851e7fSLois Curfman McInnes    Level: intermediate
307336851e7fSLois Curfman McInnes 
30745cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
30755cd90555SBarry Smith 
3076a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
30775cd90555SBarry Smith @*/
30787087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
30795cd90555SBarry Smith {
3080d952e501SBarry Smith   PetscErrorCode ierr;
3081d952e501SBarry Smith   PetscInt       i;
3082d952e501SBarry Smith 
30835cd90555SBarry Smith   PetscFunctionBegin;
30840700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3085d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
3086d952e501SBarry Smith     if (snes->monitordestroy[i]) {
30873c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
3088d952e501SBarry Smith     }
3089d952e501SBarry Smith   }
30905cd90555SBarry Smith   snes->numbermonitors = 0;
30915cd90555SBarry Smith   PetscFunctionReturn(0);
30925cd90555SBarry Smith }
30935cd90555SBarry Smith 
30944a2ae208SSatish Balay #undef __FUNCT__
30954a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
30969b94acceSBarry Smith /*@C
30979b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
30989b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
30999b94acceSBarry Smith 
31003f9fe445SBarry Smith    Logically Collective on SNES
3101fee21e36SBarry Smith 
3102c7afd0dbSLois Curfman McInnes    Input Parameters:
3103c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3104c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
31057f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
31067f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
31079b94acceSBarry Smith 
3108c7afd0dbSLois Curfman McInnes    Calling sequence of func:
310906ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
3110c7afd0dbSLois Curfman McInnes 
3111c7afd0dbSLois Curfman McInnes +    snes - the SNES context
311206ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
3113c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
3114184914b5SBarry Smith .    reason - reason for convergence/divergence
3115c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
31164b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
31174b27c08aSLois Curfman McInnes -    f - 2-norm of function
31189b94acceSBarry Smith 
311936851e7fSLois Curfman McInnes    Level: advanced
312036851e7fSLois Curfman McInnes 
31219b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
31229b94acceSBarry Smith 
312385385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
31249b94acceSBarry Smith @*/
31257087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
31269b94acceSBarry Smith {
31277f7931b9SBarry Smith   PetscErrorCode ierr;
31287f7931b9SBarry Smith 
31293a40ed3dSBarry Smith   PetscFunctionBegin;
31300700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
313185385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
31327f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
31337f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
31347f7931b9SBarry Smith   }
313585385478SLisandro Dalcin   snes->ops->converged        = func;
31367f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
313785385478SLisandro Dalcin   snes->cnvP                  = cctx;
31383a40ed3dSBarry Smith   PetscFunctionReturn(0);
31399b94acceSBarry Smith }
31409b94acceSBarry Smith 
31414a2ae208SSatish Balay #undef __FUNCT__
31424a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
314352baeb72SSatish Balay /*@
3144184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
3145184914b5SBarry Smith 
3146184914b5SBarry Smith    Not Collective
3147184914b5SBarry Smith 
3148184914b5SBarry Smith    Input Parameter:
3149184914b5SBarry Smith .  snes - the SNES context
3150184914b5SBarry Smith 
3151184914b5SBarry Smith    Output Parameter:
31524d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
3153184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
3154184914b5SBarry Smith 
3155184914b5SBarry Smith    Level: intermediate
3156184914b5SBarry Smith 
3157184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
3158184914b5SBarry Smith 
3159184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
3160184914b5SBarry Smith 
316185385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
3162184914b5SBarry Smith @*/
31637087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
3164184914b5SBarry Smith {
3165184914b5SBarry Smith   PetscFunctionBegin;
31660700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
31674482741eSBarry Smith   PetscValidPointer(reason,2);
3168184914b5SBarry Smith   *reason = snes->reason;
3169184914b5SBarry Smith   PetscFunctionReturn(0);
3170184914b5SBarry Smith }
3171184914b5SBarry Smith 
31724a2ae208SSatish Balay #undef __FUNCT__
31734a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
3174c9005455SLois Curfman McInnes /*@
3175c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
3176c9005455SLois Curfman McInnes 
31773f9fe445SBarry Smith    Logically Collective on SNES
3178fee21e36SBarry Smith 
3179c7afd0dbSLois Curfman McInnes    Input Parameters:
3180c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
31818c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
3182cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
3183758f92a0SBarry Smith .  na  - size of a and its
318464731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
3185758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
3186c7afd0dbSLois Curfman McInnes 
3187308dcc3eSBarry Smith    Notes:
3188308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
3189308dcc3eSBarry Smith    default array of length 10000 is allocated.
3190308dcc3eSBarry Smith 
3191c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
3192c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
3193c9005455SLois Curfman McInnes    during the section of code that is being timed.
3194c9005455SLois Curfman McInnes 
319536851e7fSLois Curfman McInnes    Level: intermediate
319636851e7fSLois Curfman McInnes 
3197c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
3198758f92a0SBarry Smith 
319908405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
3200758f92a0SBarry Smith 
3201c9005455SLois Curfman McInnes @*/
32027087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
3203c9005455SLois Curfman McInnes {
3204308dcc3eSBarry Smith   PetscErrorCode ierr;
3205308dcc3eSBarry Smith 
32063a40ed3dSBarry Smith   PetscFunctionBegin;
32070700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
32084482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
3209a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
3210308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
3211308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
3212308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
3213308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
3214308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
3215308dcc3eSBarry Smith   }
3216c9005455SLois Curfman McInnes   snes->conv_hist       = a;
3217758f92a0SBarry Smith   snes->conv_hist_its   = its;
3218758f92a0SBarry Smith   snes->conv_hist_max   = na;
3219a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
3220758f92a0SBarry Smith   snes->conv_hist_reset = reset;
3221758f92a0SBarry Smith   PetscFunctionReturn(0);
3222758f92a0SBarry Smith }
3223758f92a0SBarry Smith 
3224308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3225c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
3226c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
3227308dcc3eSBarry Smith EXTERN_C_BEGIN
3228308dcc3eSBarry Smith #undef __FUNCT__
3229308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
3230308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
3231308dcc3eSBarry Smith {
3232308dcc3eSBarry Smith   mxArray        *mat;
3233308dcc3eSBarry Smith   PetscInt       i;
3234308dcc3eSBarry Smith   PetscReal      *ar;
3235308dcc3eSBarry Smith 
3236308dcc3eSBarry Smith   PetscFunctionBegin;
3237308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
3238308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
3239308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
3240308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
3241308dcc3eSBarry Smith   }
3242308dcc3eSBarry Smith   PetscFunctionReturn(mat);
3243308dcc3eSBarry Smith }
3244308dcc3eSBarry Smith EXTERN_C_END
3245308dcc3eSBarry Smith #endif
3246308dcc3eSBarry Smith 
3247308dcc3eSBarry Smith 
32484a2ae208SSatish Balay #undef __FUNCT__
32494a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
32500c4c9dddSBarry Smith /*@C
3251758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
3252758f92a0SBarry Smith 
32533f9fe445SBarry Smith    Not Collective
3254758f92a0SBarry Smith 
3255758f92a0SBarry Smith    Input Parameter:
3256758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
3257758f92a0SBarry Smith 
3258758f92a0SBarry Smith    Output Parameters:
3259758f92a0SBarry Smith .  a   - array to hold history
3260758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
3261758f92a0SBarry Smith          negative if not converged) for each solve.
3262758f92a0SBarry Smith -  na  - size of a and its
3263758f92a0SBarry Smith 
3264758f92a0SBarry Smith    Notes:
3265758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
3266758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
3267758f92a0SBarry Smith 
3268758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
3269758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
3270758f92a0SBarry Smith    during the section of code that is being timed.
3271758f92a0SBarry Smith 
3272758f92a0SBarry Smith    Level: intermediate
3273758f92a0SBarry Smith 
3274758f92a0SBarry Smith .keywords: SNES, get, convergence, history
3275758f92a0SBarry Smith 
3276758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
3277758f92a0SBarry Smith 
3278758f92a0SBarry Smith @*/
32797087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3280758f92a0SBarry Smith {
3281758f92a0SBarry Smith   PetscFunctionBegin;
32820700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3283758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
3284758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
3285758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
32863a40ed3dSBarry Smith   PetscFunctionReturn(0);
3287c9005455SLois Curfman McInnes }
3288c9005455SLois Curfman McInnes 
3289e74ef692SMatthew Knepley #undef __FUNCT__
3290e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
3291ac226902SBarry Smith /*@C
329276b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
3293eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
32947e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
329576b2cf59SMatthew Knepley 
32963f9fe445SBarry Smith   Logically Collective on SNES
329776b2cf59SMatthew Knepley 
329876b2cf59SMatthew Knepley   Input Parameters:
329976b2cf59SMatthew Knepley . snes - The nonlinear solver context
330076b2cf59SMatthew Knepley . func - The function
330176b2cf59SMatthew Knepley 
330276b2cf59SMatthew Knepley   Calling sequence of func:
3303b5d30489SBarry Smith . func (SNES snes, PetscInt step);
330476b2cf59SMatthew Knepley 
330576b2cf59SMatthew Knepley . step - The current step of the iteration
330676b2cf59SMatthew Knepley 
3307fe97e370SBarry Smith   Level: advanced
3308fe97e370SBarry Smith 
3309fe97e370SBarry 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()
3310fe97e370SBarry Smith         This is not used by most users.
331176b2cf59SMatthew Knepley 
331276b2cf59SMatthew Knepley .keywords: SNES, update
3313b5d30489SBarry Smith 
331485385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
331576b2cf59SMatthew Knepley @*/
33167087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
331776b2cf59SMatthew Knepley {
331876b2cf59SMatthew Knepley   PetscFunctionBegin;
33190700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
3320e7788613SBarry Smith   snes->ops->update = func;
332176b2cf59SMatthew Knepley   PetscFunctionReturn(0);
332276b2cf59SMatthew Knepley }
332376b2cf59SMatthew Knepley 
3324e74ef692SMatthew Knepley #undef __FUNCT__
3325e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
332676b2cf59SMatthew Knepley /*@
332776b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
332876b2cf59SMatthew Knepley 
332976b2cf59SMatthew Knepley   Not collective
333076b2cf59SMatthew Knepley 
333176b2cf59SMatthew Knepley   Input Parameters:
333276b2cf59SMatthew Knepley . snes - The nonlinear solver context
333376b2cf59SMatthew Knepley . step - The current step of the iteration
333476b2cf59SMatthew Knepley 
3335205452f4SMatthew Knepley   Level: intermediate
3336205452f4SMatthew Knepley 
333776b2cf59SMatthew Knepley .keywords: SNES, update
3338a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
333976b2cf59SMatthew Knepley @*/
33407087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
334176b2cf59SMatthew Knepley {
334276b2cf59SMatthew Knepley   PetscFunctionBegin;
334376b2cf59SMatthew Knepley   PetscFunctionReturn(0);
334476b2cf59SMatthew Knepley }
334576b2cf59SMatthew Knepley 
33464a2ae208SSatish Balay #undef __FUNCT__
33474a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
33489b94acceSBarry Smith /*
33499b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
33509b94acceSBarry Smith    positive parameter delta.
33519b94acceSBarry Smith 
33529b94acceSBarry Smith     Input Parameters:
3353c7afd0dbSLois Curfman McInnes +   snes - the SNES context
33549b94acceSBarry Smith .   y - approximate solution of linear system
33559b94acceSBarry Smith .   fnorm - 2-norm of current function
3356c7afd0dbSLois Curfman McInnes -   delta - trust region size
33579b94acceSBarry Smith 
33589b94acceSBarry Smith     Output Parameters:
3359c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
33609b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
33619b94acceSBarry Smith     region, and exceeds zero otherwise.
3362c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
33639b94acceSBarry Smith 
33649b94acceSBarry Smith     Note:
33654b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
33669b94acceSBarry Smith     is set to be the maximum allowable step size.
33679b94acceSBarry Smith 
33689b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
33699b94acceSBarry Smith */
3370dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
33719b94acceSBarry Smith {
3372064f8208SBarry Smith   PetscReal      nrm;
3373ea709b57SSatish Balay   PetscScalar    cnorm;
3374dfbe8321SBarry Smith   PetscErrorCode ierr;
33753a40ed3dSBarry Smith 
33763a40ed3dSBarry Smith   PetscFunctionBegin;
33770700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
33780700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3379c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
3380184914b5SBarry Smith 
3381064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
3382064f8208SBarry Smith   if (nrm > *delta) {
3383064f8208SBarry Smith      nrm = *delta/nrm;
3384064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
3385064f8208SBarry Smith      cnorm = nrm;
33862dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
33879b94acceSBarry Smith      *ynorm = *delta;
33889b94acceSBarry Smith   } else {
33899b94acceSBarry Smith      *gpnorm = 0.0;
3390064f8208SBarry Smith      *ynorm = nrm;
33919b94acceSBarry Smith   }
33923a40ed3dSBarry Smith   PetscFunctionReturn(0);
33939b94acceSBarry Smith }
33949b94acceSBarry Smith 
33954a2ae208SSatish Balay #undef __FUNCT__
33964a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
33976ce558aeSBarry Smith /*@C
3398f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
3399f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
34009b94acceSBarry Smith 
3401c7afd0dbSLois Curfman McInnes    Collective on SNES
3402c7afd0dbSLois Curfman McInnes 
3403b2002411SLois Curfman McInnes    Input Parameters:
3404c7afd0dbSLois Curfman McInnes +  snes - the SNES context
34053cebf274SJed Brown .  b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero.
340685385478SLisandro Dalcin -  x - the solution vector.
34079b94acceSBarry Smith 
3408b2002411SLois Curfman McInnes    Notes:
34098ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
34108ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
34118ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
34128ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
34138ddd3da0SLois Curfman McInnes 
341436851e7fSLois Curfman McInnes    Level: beginner
341536851e7fSLois Curfman McInnes 
34169b94acceSBarry Smith .keywords: SNES, nonlinear, solve
34179b94acceSBarry Smith 
3418c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
34199b94acceSBarry Smith @*/
34207087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
34219b94acceSBarry Smith {
3422dfbe8321SBarry Smith   PetscErrorCode ierr;
3423ace3abfcSBarry Smith   PetscBool      flg;
3424eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
3425eabae89aSBarry Smith   PetscViewer    viewer;
3426efd51863SBarry Smith   PetscInt       grid;
3427a69afd8bSBarry Smith   Vec            xcreated = PETSC_NULL;
3428caa4e7f2SJed Brown   DM             dm;
3429052efed2SBarry Smith 
34303a40ed3dSBarry Smith   PetscFunctionBegin;
34310700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3432a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3433a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
34340700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
343585385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
343685385478SLisandro Dalcin 
3437caa4e7f2SJed Brown   if (!x) {
3438caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3439caa4e7f2SJed Brown     ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr);
3440a69afd8bSBarry Smith     x    = xcreated;
3441a69afd8bSBarry Smith   }
3442a69afd8bSBarry Smith 
3443a8248277SBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);}
3444efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
3445efd51863SBarry Smith 
344685385478SLisandro Dalcin     /* set solution vector */
3447efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
34486bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
344985385478SLisandro Dalcin     snes->vec_sol = x;
3450caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3451caa4e7f2SJed Brown 
3452caa4e7f2SJed Brown     /* set affine vector if provided */
345385385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
34546bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
345585385478SLisandro Dalcin     snes->vec_rhs = b;
345685385478SLisandro Dalcin 
345770e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
34583f149594SLisandro Dalcin 
34597eee914bSBarry Smith     if (!grid) {
34607eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
3461d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
3462dd568438SSatish Balay       } else if (snes->dm) {
3463dd568438SSatish Balay         PetscBool ig;
3464dd568438SSatish Balay         ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr);
3465dd568438SSatish Balay         if (ig) {
34667eee914bSBarry Smith           ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr);
34677eee914bSBarry Smith         }
3468d25893d9SBarry Smith       }
3469dd568438SSatish Balay     }
3470d25893d9SBarry Smith 
3471abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
347250ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
3473d5e45103SBarry Smith 
34743f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
34754936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
347685385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
34774936397dSBarry Smith     if (snes->domainerror){
34784936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
34794936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
34804936397dSBarry Smith     }
348117186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
34823f149594SLisandro Dalcin 
34837adad957SLisandro Dalcin     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
3484eabae89aSBarry Smith     if (flg && !PetscPreLoadingOn) {
34857adad957SLisandro Dalcin       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
3486eabae89aSBarry Smith       ierr = SNESView(snes,viewer);CHKERRQ(ierr);
34876bf464f9SBarry Smith       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3488eabae89aSBarry Smith     }
3489eabae89aSBarry Smith 
349090d69ab7SBarry Smith     flg  = PETSC_FALSE;
3491acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
3492da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
34935968eb51SBarry Smith     if (snes->printreason) {
3494a8248277SBarry Smith       ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
34955968eb51SBarry Smith       if (snes->reason > 0) {
3496c7e7b494SJed 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);
34975968eb51SBarry Smith       } else {
3498c7e7b494SJed 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);
34995968eb51SBarry Smith       }
3500a8248277SBarry Smith       ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
35015968eb51SBarry Smith     }
35025968eb51SBarry Smith 
35038501fc72SJed Brown     flg = PETSC_FALSE;
35048501fc72SJed Brown     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
35058501fc72SJed Brown     if (flg) {
35068501fc72SJed Brown       PetscViewer viewer;
35078501fc72SJed Brown       ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
35088501fc72SJed Brown       ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr);
35098501fc72SJed Brown       ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr);
35108501fc72SJed Brown       ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr);
35118501fc72SJed Brown       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
35128501fc72SJed Brown     }
35138501fc72SJed Brown 
3514e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
3515efd51863SBarry Smith     if (grid <  snes->gridsequence) {
3516efd51863SBarry Smith       DM  fine;
3517efd51863SBarry Smith       Vec xnew;
3518efd51863SBarry Smith       Mat interp;
3519efd51863SBarry Smith 
3520efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
3521c5c77316SJed Brown       if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
3522e727c939SJed Brown       ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
3523efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
3524efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
3525c833c3b5SJed Brown       ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr);
3526efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
3527efd51863SBarry Smith       x    = xnew;
3528efd51863SBarry Smith 
3529efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
3530efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
3531efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
3532a8248277SBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);
3533efd51863SBarry Smith     }
3534efd51863SBarry Smith   }
3535a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
35363a40ed3dSBarry Smith   PetscFunctionReturn(0);
35379b94acceSBarry Smith }
35389b94acceSBarry Smith 
35399b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
35409b94acceSBarry Smith 
35414a2ae208SSatish Balay #undef __FUNCT__
35424a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
354382bf6240SBarry Smith /*@C
35444b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
35459b94acceSBarry Smith 
3546fee21e36SBarry Smith    Collective on SNES
3547fee21e36SBarry Smith 
3548c7afd0dbSLois Curfman McInnes    Input Parameters:
3549c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3550454a90a3SBarry Smith -  type - a known method
3551c7afd0dbSLois Curfman McInnes 
3552c7afd0dbSLois Curfman McInnes    Options Database Key:
3553454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
3554c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
3555ae12b187SLois Curfman McInnes 
35569b94acceSBarry Smith    Notes:
3557e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
35584b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
3559c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
35604b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
3561c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
35629b94acceSBarry Smith 
3563ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
3564ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
3565ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
3566ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
3567ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
3568ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
3569ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
3570ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
3571ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
3572b0a32e0cSBarry Smith   appropriate method.
357336851e7fSLois Curfman McInnes 
357436851e7fSLois Curfman McInnes   Level: intermediate
3575a703fe33SLois Curfman McInnes 
3576454a90a3SBarry Smith .keywords: SNES, set, type
3577435da068SBarry Smith 
3578435da068SBarry Smith .seealso: SNESType, SNESCreate()
3579435da068SBarry Smith 
35809b94acceSBarry Smith @*/
35817087cfbeSBarry Smith PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
35829b94acceSBarry Smith {
3583dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
3584ace3abfcSBarry Smith   PetscBool      match;
35853a40ed3dSBarry Smith 
35863a40ed3dSBarry Smith   PetscFunctionBegin;
35870700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35884482741eSBarry Smith   PetscValidCharPointer(type,2);
358982bf6240SBarry Smith 
3590251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
35910f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
359292ff6ae8SBarry Smith 
35934b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
3594e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
359575396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
3596b5c23020SJed Brown   if (snes->ops->destroy) {
3597b5c23020SJed Brown     ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
3598b5c23020SJed Brown     snes->ops->destroy = PETSC_NULL;
3599b5c23020SJed Brown   }
360075396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
360175396ef9SLisandro Dalcin   snes->ops->setup          = 0;
360275396ef9SLisandro Dalcin   snes->ops->solve          = 0;
360375396ef9SLisandro Dalcin   snes->ops->view           = 0;
360475396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
360575396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
360675396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
360775396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
3608454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
360903bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
36109fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
36119fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
36129fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
36139fb22e1aSBarry Smith   }
36149fb22e1aSBarry Smith #endif
36153a40ed3dSBarry Smith   PetscFunctionReturn(0);
36169b94acceSBarry Smith }
36179b94acceSBarry Smith 
3618a847f771SSatish Balay 
36199b94acceSBarry Smith /* --------------------------------------------------------------------- */
36204a2ae208SSatish Balay #undef __FUNCT__
36214a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
362252baeb72SSatish Balay /*@
36239b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
3624f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
36259b94acceSBarry Smith 
3626fee21e36SBarry Smith    Not Collective
3627fee21e36SBarry Smith 
362836851e7fSLois Curfman McInnes    Level: advanced
362936851e7fSLois Curfman McInnes 
36309b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
36319b94acceSBarry Smith 
36329b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
36339b94acceSBarry Smith @*/
36347087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
36359b94acceSBarry Smith {
3636dfbe8321SBarry Smith   PetscErrorCode ierr;
363782bf6240SBarry Smith 
36383a40ed3dSBarry Smith   PetscFunctionBegin;
36391441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
36404c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
36413a40ed3dSBarry Smith   PetscFunctionReturn(0);
36429b94acceSBarry Smith }
36439b94acceSBarry Smith 
36444a2ae208SSatish Balay #undef __FUNCT__
36454a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
36469b94acceSBarry Smith /*@C
36479a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
36489b94acceSBarry Smith 
3649c7afd0dbSLois Curfman McInnes    Not Collective
3650c7afd0dbSLois Curfman McInnes 
36519b94acceSBarry Smith    Input Parameter:
36524b0e389bSBarry Smith .  snes - nonlinear solver context
36539b94acceSBarry Smith 
36549b94acceSBarry Smith    Output Parameter:
36553a7fca6bSBarry Smith .  type - SNES method (a character string)
36569b94acceSBarry Smith 
365736851e7fSLois Curfman McInnes    Level: intermediate
365836851e7fSLois Curfman McInnes 
3659454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
36609b94acceSBarry Smith @*/
36617087cfbeSBarry Smith PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
36629b94acceSBarry Smith {
36633a40ed3dSBarry Smith   PetscFunctionBegin;
36640700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36654482741eSBarry Smith   PetscValidPointer(type,2);
36667adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
36673a40ed3dSBarry Smith   PetscFunctionReturn(0);
36689b94acceSBarry Smith }
36699b94acceSBarry Smith 
36704a2ae208SSatish Balay #undef __FUNCT__
36714a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
367252baeb72SSatish Balay /*@
36739b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
3674c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
36759b94acceSBarry Smith 
3676c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3677c7afd0dbSLois Curfman McInnes 
36789b94acceSBarry Smith    Input Parameter:
36799b94acceSBarry Smith .  snes - the SNES context
36809b94acceSBarry Smith 
36819b94acceSBarry Smith    Output Parameter:
36829b94acceSBarry Smith .  x - the solution
36839b94acceSBarry Smith 
368470e92668SMatthew Knepley    Level: intermediate
368536851e7fSLois Curfman McInnes 
36869b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
36879b94acceSBarry Smith 
368885385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
36899b94acceSBarry Smith @*/
36907087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
36919b94acceSBarry Smith {
36923a40ed3dSBarry Smith   PetscFunctionBegin;
36930700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36944482741eSBarry Smith   PetscValidPointer(x,2);
369585385478SLisandro Dalcin   *x = snes->vec_sol;
369670e92668SMatthew Knepley   PetscFunctionReturn(0);
369770e92668SMatthew Knepley }
369870e92668SMatthew Knepley 
369970e92668SMatthew Knepley #undef __FUNCT__
37004a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
370152baeb72SSatish Balay /*@
37029b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
37039b94acceSBarry Smith    stored.
37049b94acceSBarry Smith 
3705c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3706c7afd0dbSLois Curfman McInnes 
37079b94acceSBarry Smith    Input Parameter:
37089b94acceSBarry Smith .  snes - the SNES context
37099b94acceSBarry Smith 
37109b94acceSBarry Smith    Output Parameter:
37119b94acceSBarry Smith .  x - the solution update
37129b94acceSBarry Smith 
371336851e7fSLois Curfman McInnes    Level: advanced
371436851e7fSLois Curfman McInnes 
37159b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
37169b94acceSBarry Smith 
371785385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
37189b94acceSBarry Smith @*/
37197087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
37209b94acceSBarry Smith {
37213a40ed3dSBarry Smith   PetscFunctionBegin;
37220700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37234482741eSBarry Smith   PetscValidPointer(x,2);
372485385478SLisandro Dalcin   *x = snes->vec_sol_update;
37253a40ed3dSBarry Smith   PetscFunctionReturn(0);
37269b94acceSBarry Smith }
37279b94acceSBarry Smith 
37284a2ae208SSatish Balay #undef __FUNCT__
37294a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
37309b94acceSBarry Smith /*@C
37313638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
37329b94acceSBarry Smith 
3733a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
3734c7afd0dbSLois Curfman McInnes 
37359b94acceSBarry Smith    Input Parameter:
37369b94acceSBarry Smith .  snes - the SNES context
37379b94acceSBarry Smith 
37389b94acceSBarry Smith    Output Parameter:
37397bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
374070e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
374170e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
37429b94acceSBarry Smith 
374336851e7fSLois Curfman McInnes    Level: advanced
374436851e7fSLois Curfman McInnes 
3745a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
37469b94acceSBarry Smith 
37474b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
37489b94acceSBarry Smith @*/
37497087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
37509b94acceSBarry Smith {
3751a63bb30eSJed Brown   PetscErrorCode ierr;
37526cab3a1bSJed Brown   DM             dm;
3753a63bb30eSJed Brown 
37543a40ed3dSBarry Smith   PetscFunctionBegin;
37550700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3756a63bb30eSJed Brown   if (r) {
3757a63bb30eSJed Brown     if (!snes->vec_func) {
3758a63bb30eSJed Brown       if (snes->vec_rhs) {
3759a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
3760a63bb30eSJed Brown       } else if (snes->vec_sol) {
3761a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
3762a63bb30eSJed Brown       } else if (snes->dm) {
3763a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
3764a63bb30eSJed Brown       }
3765a63bb30eSJed Brown     }
3766a63bb30eSJed Brown     *r = snes->vec_func;
3767a63bb30eSJed Brown   }
37686cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
37696cab3a1bSJed Brown   ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr);
37703a40ed3dSBarry Smith   PetscFunctionReturn(0);
37719b94acceSBarry Smith }
37729b94acceSBarry Smith 
3773c79ef259SPeter Brune /*@C
3774c79ef259SPeter Brune    SNESGetGS - Returns the GS function and context.
3775c79ef259SPeter Brune 
3776c79ef259SPeter Brune    Input Parameter:
3777c79ef259SPeter Brune .  snes - the SNES context
3778c79ef259SPeter Brune 
3779c79ef259SPeter Brune    Output Parameter:
3780c79ef259SPeter Brune +  gsfunc - the function (or PETSC_NULL)
3781c79ef259SPeter Brune -  ctx    - the function context (or PETSC_NULL)
3782c79ef259SPeter Brune 
3783c79ef259SPeter Brune    Level: advanced
3784c79ef259SPeter Brune 
3785c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
3786c79ef259SPeter Brune 
3787c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction()
3788c79ef259SPeter Brune @*/
3789c79ef259SPeter Brune 
37904a2ae208SSatish Balay #undef __FUNCT__
3791646217ecSPeter Brune #define __FUNCT__ "SNESGetGS"
3792646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx)
3793646217ecSPeter Brune {
37946cab3a1bSJed Brown   PetscErrorCode ierr;
37956cab3a1bSJed Brown   DM             dm;
37966cab3a1bSJed Brown 
3797646217ecSPeter Brune   PetscFunctionBegin;
3798646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37996cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
38006cab3a1bSJed Brown   ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr);
3801646217ecSPeter Brune   PetscFunctionReturn(0);
3802646217ecSPeter Brune }
3803646217ecSPeter Brune 
38044a2ae208SSatish Balay #undef __FUNCT__
38054a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
38063c7409f5SSatish Balay /*@C
38073c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
3808d850072dSLois Curfman McInnes    SNES options in the database.
38093c7409f5SSatish Balay 
38103f9fe445SBarry Smith    Logically Collective on SNES
3811fee21e36SBarry Smith 
3812c7afd0dbSLois Curfman McInnes    Input Parameter:
3813c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3814c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3815c7afd0dbSLois Curfman McInnes 
3816d850072dSLois Curfman McInnes    Notes:
3817a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3818c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3819d850072dSLois Curfman McInnes 
382036851e7fSLois Curfman McInnes    Level: advanced
382136851e7fSLois Curfman McInnes 
38223c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
3823a86d99e1SLois Curfman McInnes 
3824a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
38253c7409f5SSatish Balay @*/
38267087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
38273c7409f5SSatish Balay {
3828dfbe8321SBarry Smith   PetscErrorCode ierr;
38293c7409f5SSatish Balay 
38303a40ed3dSBarry Smith   PetscFunctionBegin;
38310700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3832639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
38331cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
383494b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
38353a40ed3dSBarry Smith   PetscFunctionReturn(0);
38363c7409f5SSatish Balay }
38373c7409f5SSatish Balay 
38384a2ae208SSatish Balay #undef __FUNCT__
38394a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
38403c7409f5SSatish Balay /*@C
3841f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
3842d850072dSLois Curfman McInnes    SNES options in the database.
38433c7409f5SSatish Balay 
38443f9fe445SBarry Smith    Logically Collective on SNES
3845fee21e36SBarry Smith 
3846c7afd0dbSLois Curfman McInnes    Input Parameters:
3847c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3848c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3849c7afd0dbSLois Curfman McInnes 
3850d850072dSLois Curfman McInnes    Notes:
3851a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3852c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3853d850072dSLois Curfman McInnes 
385436851e7fSLois Curfman McInnes    Level: advanced
385536851e7fSLois Curfman McInnes 
38563c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
3857a86d99e1SLois Curfman McInnes 
3858a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
38593c7409f5SSatish Balay @*/
38607087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
38613c7409f5SSatish Balay {
3862dfbe8321SBarry Smith   PetscErrorCode ierr;
38633c7409f5SSatish Balay 
38643a40ed3dSBarry Smith   PetscFunctionBegin;
38650700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3866639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
38671cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
386894b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
38693a40ed3dSBarry Smith   PetscFunctionReturn(0);
38703c7409f5SSatish Balay }
38713c7409f5SSatish Balay 
38724a2ae208SSatish Balay #undef __FUNCT__
38734a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
38749ab63eb5SSatish Balay /*@C
38753c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
38763c7409f5SSatish Balay    SNES options in the database.
38773c7409f5SSatish Balay 
3878c7afd0dbSLois Curfman McInnes    Not Collective
3879c7afd0dbSLois Curfman McInnes 
38803c7409f5SSatish Balay    Input Parameter:
38813c7409f5SSatish Balay .  snes - the SNES context
38823c7409f5SSatish Balay 
38833c7409f5SSatish Balay    Output Parameter:
38843c7409f5SSatish Balay .  prefix - pointer to the prefix string used
38853c7409f5SSatish Balay 
38864ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
38879ab63eb5SSatish Balay    sufficient length to hold the prefix.
38889ab63eb5SSatish Balay 
388936851e7fSLois Curfman McInnes    Level: advanced
389036851e7fSLois Curfman McInnes 
38913c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
3892a86d99e1SLois Curfman McInnes 
3893a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
38943c7409f5SSatish Balay @*/
38957087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
38963c7409f5SSatish Balay {
3897dfbe8321SBarry Smith   PetscErrorCode ierr;
38983c7409f5SSatish Balay 
38993a40ed3dSBarry Smith   PetscFunctionBegin;
39000700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3901639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
39023a40ed3dSBarry Smith   PetscFunctionReturn(0);
39033c7409f5SSatish Balay }
39043c7409f5SSatish Balay 
3905b2002411SLois Curfman McInnes 
39064a2ae208SSatish Balay #undef __FUNCT__
39074a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
39083cea93caSBarry Smith /*@C
39093cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
39103cea93caSBarry Smith 
39117f6c08e0SMatthew Knepley   Level: advanced
39123cea93caSBarry Smith @*/
39137087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
3914b2002411SLois Curfman McInnes {
3915e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
3916dfbe8321SBarry Smith   PetscErrorCode ierr;
3917b2002411SLois Curfman McInnes 
3918b2002411SLois Curfman McInnes   PetscFunctionBegin;
3919b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3920c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3921b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
3922b2002411SLois Curfman McInnes }
3923da9b6338SBarry Smith 
3924da9b6338SBarry Smith #undef __FUNCT__
3925da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
39267087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
3927da9b6338SBarry Smith {
3928dfbe8321SBarry Smith   PetscErrorCode ierr;
392977431f27SBarry Smith   PetscInt       N,i,j;
3930da9b6338SBarry Smith   Vec            u,uh,fh;
3931da9b6338SBarry Smith   PetscScalar    value;
3932da9b6338SBarry Smith   PetscReal      norm;
3933da9b6338SBarry Smith 
3934da9b6338SBarry Smith   PetscFunctionBegin;
3935da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
3936da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
3937da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
3938da9b6338SBarry Smith 
3939da9b6338SBarry Smith   /* currently only works for sequential */
3940da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
3941da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
3942da9b6338SBarry Smith   for (i=0; i<N; i++) {
3943da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
394477431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
3945da9b6338SBarry Smith     for (j=-10; j<11; j++) {
3946ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
3947da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
39483ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
3949da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
395077431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
3951da9b6338SBarry Smith       value = -value;
3952da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
3953da9b6338SBarry Smith     }
3954da9b6338SBarry Smith   }
39556bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
39566bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
3957da9b6338SBarry Smith   PetscFunctionReturn(0);
3958da9b6338SBarry Smith }
395971f87433Sdalcinl 
396071f87433Sdalcinl #undef __FUNCT__
3961fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
396271f87433Sdalcinl /*@
3963fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
396471f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
396571f87433Sdalcinl    Newton method.
396671f87433Sdalcinl 
39673f9fe445SBarry Smith    Logically Collective on SNES
396871f87433Sdalcinl 
396971f87433Sdalcinl    Input Parameters:
397071f87433Sdalcinl +  snes - SNES context
397171f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
397271f87433Sdalcinl 
397364ba62caSBarry Smith     Options Database:
397464ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
397564ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
397664ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
397764ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
397864ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
397964ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
398064ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
398164ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
398264ba62caSBarry Smith 
398371f87433Sdalcinl    Notes:
398471f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
398571f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
398671f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
398771f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
398871f87433Sdalcinl    solver.
398971f87433Sdalcinl 
399071f87433Sdalcinl    Level: advanced
399171f87433Sdalcinl 
399271f87433Sdalcinl    Reference:
399371f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
399471f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
399571f87433Sdalcinl 
399671f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
399771f87433Sdalcinl 
3998fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
399971f87433Sdalcinl @*/
40007087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
400171f87433Sdalcinl {
400271f87433Sdalcinl   PetscFunctionBegin;
40030700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4004acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
400571f87433Sdalcinl   snes->ksp_ewconv = flag;
400671f87433Sdalcinl   PetscFunctionReturn(0);
400771f87433Sdalcinl }
400871f87433Sdalcinl 
400971f87433Sdalcinl #undef __FUNCT__
4010fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
401171f87433Sdalcinl /*@
4012fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
401371f87433Sdalcinl    for computing relative tolerance for linear solvers within an
401471f87433Sdalcinl    inexact Newton method.
401571f87433Sdalcinl 
401671f87433Sdalcinl    Not Collective
401771f87433Sdalcinl 
401871f87433Sdalcinl    Input Parameter:
401971f87433Sdalcinl .  snes - SNES context
402071f87433Sdalcinl 
402171f87433Sdalcinl    Output Parameter:
402271f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
402371f87433Sdalcinl 
402471f87433Sdalcinl    Notes:
402571f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
402671f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
402771f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
402871f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
402971f87433Sdalcinl    solver.
403071f87433Sdalcinl 
403171f87433Sdalcinl    Level: advanced
403271f87433Sdalcinl 
403371f87433Sdalcinl    Reference:
403471f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
403571f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
403671f87433Sdalcinl 
403771f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
403871f87433Sdalcinl 
4039fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
404071f87433Sdalcinl @*/
40417087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
404271f87433Sdalcinl {
404371f87433Sdalcinl   PetscFunctionBegin;
40440700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
404571f87433Sdalcinl   PetscValidPointer(flag,2);
404671f87433Sdalcinl   *flag = snes->ksp_ewconv;
404771f87433Sdalcinl   PetscFunctionReturn(0);
404871f87433Sdalcinl }
404971f87433Sdalcinl 
405071f87433Sdalcinl #undef __FUNCT__
4051fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
405271f87433Sdalcinl /*@
4053fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
405471f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
405571f87433Sdalcinl    Newton method.
405671f87433Sdalcinl 
40573f9fe445SBarry Smith    Logically Collective on SNES
405871f87433Sdalcinl 
405971f87433Sdalcinl    Input Parameters:
406071f87433Sdalcinl +    snes - SNES context
406171f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
406271f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
406371f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
406471f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
406571f87433Sdalcinl              (0 <= gamma2 <= 1)
406671f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
406771f87433Sdalcinl .    alpha2 - power for safeguard
406871f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
406971f87433Sdalcinl 
407071f87433Sdalcinl    Note:
407171f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
407271f87433Sdalcinl 
407371f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
407471f87433Sdalcinl 
407571f87433Sdalcinl    Level: advanced
407671f87433Sdalcinl 
407771f87433Sdalcinl    Reference:
407871f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
407971f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
408071f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
408171f87433Sdalcinl 
408271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
408371f87433Sdalcinl 
4084fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
408571f87433Sdalcinl @*/
40867087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
408771f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
408871f87433Sdalcinl {
4089fa9f3622SBarry Smith   SNESKSPEW *kctx;
409071f87433Sdalcinl   PetscFunctionBegin;
40910700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4092fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4093e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
4094c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
4095c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
4096c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
4097c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
4098c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
4099c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
4100c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
410171f87433Sdalcinl 
410271f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
410371f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
410471f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
410571f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
410671f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
410771f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
410871f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
410971f87433Sdalcinl 
411071f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
4111e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
411271f87433Sdalcinl   }
411371f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
4114e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
411571f87433Sdalcinl   }
411671f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
4117e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
411871f87433Sdalcinl   }
411971f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
4120e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
412171f87433Sdalcinl   }
412271f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
4123e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
412471f87433Sdalcinl   }
412571f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
4126e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
412771f87433Sdalcinl   }
412871f87433Sdalcinl   PetscFunctionReturn(0);
412971f87433Sdalcinl }
413071f87433Sdalcinl 
413171f87433Sdalcinl #undef __FUNCT__
4132fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
413371f87433Sdalcinl /*@
4134fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
413571f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
413671f87433Sdalcinl    Newton method.
413771f87433Sdalcinl 
413871f87433Sdalcinl    Not Collective
413971f87433Sdalcinl 
414071f87433Sdalcinl    Input Parameters:
414171f87433Sdalcinl      snes - SNES context
414271f87433Sdalcinl 
414371f87433Sdalcinl    Output Parameters:
414471f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
414571f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
414671f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
414771f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
414871f87433Sdalcinl              (0 <= gamma2 <= 1)
414971f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
415071f87433Sdalcinl .    alpha2 - power for safeguard
415171f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
415271f87433Sdalcinl 
415371f87433Sdalcinl    Level: advanced
415471f87433Sdalcinl 
415571f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
415671f87433Sdalcinl 
4157fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
415871f87433Sdalcinl @*/
41597087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
416071f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
416171f87433Sdalcinl {
4162fa9f3622SBarry Smith   SNESKSPEW *kctx;
416371f87433Sdalcinl   PetscFunctionBegin;
41640700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4165fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4166e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
416771f87433Sdalcinl   if(version)   *version   = kctx->version;
416871f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
416971f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
417071f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
417171f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
417271f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
417371f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
417471f87433Sdalcinl   PetscFunctionReturn(0);
417571f87433Sdalcinl }
417671f87433Sdalcinl 
417771f87433Sdalcinl #undef __FUNCT__
4178fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
4179fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
418071f87433Sdalcinl {
418171f87433Sdalcinl   PetscErrorCode ierr;
4182fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
418371f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
418471f87433Sdalcinl 
418571f87433Sdalcinl   PetscFunctionBegin;
4186e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
418771f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
418871f87433Sdalcinl     rtol = kctx->rtol_0;
418971f87433Sdalcinl   } else {
419071f87433Sdalcinl     if (kctx->version == 1) {
419171f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
419271f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
419371f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
419471f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
419571f87433Sdalcinl     } else if (kctx->version == 2) {
419671f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
419771f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
419871f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
419971f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
420071f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
420171f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
420271f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
420371f87433Sdalcinl       stol = PetscMax(rtol,stol);
420471f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
420571f87433Sdalcinl       /* safeguard: avoid oversolving */
420671f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
420771f87433Sdalcinl       stol = PetscMax(rtol,stol);
420871f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
4209e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
421071f87433Sdalcinl   }
421171f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
421271f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
421371f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
421471f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
421571f87433Sdalcinl   PetscFunctionReturn(0);
421671f87433Sdalcinl }
421771f87433Sdalcinl 
421871f87433Sdalcinl #undef __FUNCT__
4219fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
4220fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
422171f87433Sdalcinl {
422271f87433Sdalcinl   PetscErrorCode ierr;
4223fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
422471f87433Sdalcinl   PCSide         pcside;
422571f87433Sdalcinl   Vec            lres;
422671f87433Sdalcinl 
422771f87433Sdalcinl   PetscFunctionBegin;
4228e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
422971f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
423071f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
423171f87433Sdalcinl   if (kctx->version == 1) {
4232b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
423371f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
423471f87433Sdalcinl       /* KSP residual is true linear residual */
423571f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
423671f87433Sdalcinl     } else {
423771f87433Sdalcinl       /* KSP residual is preconditioned residual */
423871f87433Sdalcinl       /* compute true linear residual norm */
423971f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
424071f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
424171f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
424271f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
42436bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
424471f87433Sdalcinl     }
424571f87433Sdalcinl   }
424671f87433Sdalcinl   PetscFunctionReturn(0);
424771f87433Sdalcinl }
424871f87433Sdalcinl 
424971f87433Sdalcinl #undef __FUNCT__
425071f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
425171f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
425271f87433Sdalcinl {
425371f87433Sdalcinl   PetscErrorCode ierr;
425471f87433Sdalcinl 
425571f87433Sdalcinl   PetscFunctionBegin;
4256fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
425771f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
4258fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
425971f87433Sdalcinl   PetscFunctionReturn(0);
426071f87433Sdalcinl }
42616c699258SBarry Smith 
42626c699258SBarry Smith #undef __FUNCT__
42636c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
42646c699258SBarry Smith /*@
42656c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
42666c699258SBarry Smith 
42673f9fe445SBarry Smith    Logically Collective on SNES
42686c699258SBarry Smith 
42696c699258SBarry Smith    Input Parameters:
42706c699258SBarry Smith +  snes - the preconditioner context
42716c699258SBarry Smith -  dm - the dm
42726c699258SBarry Smith 
42736c699258SBarry Smith    Level: intermediate
42746c699258SBarry Smith 
42756c699258SBarry Smith 
42766c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
42776c699258SBarry Smith @*/
42787087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
42796c699258SBarry Smith {
42806c699258SBarry Smith   PetscErrorCode ierr;
4281345fed2cSBarry Smith   KSP            ksp;
42826cab3a1bSJed Brown   SNESDM         sdm;
42836c699258SBarry Smith 
42846c699258SBarry Smith   PetscFunctionBegin;
42850700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4286d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
42876cab3a1bSJed Brown   if (snes->dm) {               /* Move the SNESDM context over to the new DM unless the new DM already has one */
42886cab3a1bSJed Brown     PetscContainer oldcontainer,container;
42896cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr);
42906cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr);
42916cab3a1bSJed Brown     if (oldcontainer && !container) {
42926cab3a1bSJed Brown       ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr);
42936cab3a1bSJed Brown       ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr);
42946cab3a1bSJed Brown       if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */
42956cab3a1bSJed Brown         sdm->originaldm = dm;
42966cab3a1bSJed Brown       }
42976cab3a1bSJed Brown     }
42986bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
42996cab3a1bSJed Brown   }
43006c699258SBarry Smith   snes->dm = dm;
4301345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4302345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4303f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
43042c155ee1SBarry Smith   if (snes->pc) {
43052c155ee1SBarry Smith     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
43062c155ee1SBarry Smith   }
43076c699258SBarry Smith   PetscFunctionReturn(0);
43086c699258SBarry Smith }
43096c699258SBarry Smith 
43106c699258SBarry Smith #undef __FUNCT__
43116c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
43126c699258SBarry Smith /*@
43136c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
43146c699258SBarry Smith 
43153f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
43166c699258SBarry Smith 
43176c699258SBarry Smith    Input Parameter:
43186c699258SBarry Smith . snes - the preconditioner context
43196c699258SBarry Smith 
43206c699258SBarry Smith    Output Parameter:
43216c699258SBarry Smith .  dm - the dm
43226c699258SBarry Smith 
43236c699258SBarry Smith    Level: intermediate
43246c699258SBarry Smith 
43256c699258SBarry Smith 
43266c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
43276c699258SBarry Smith @*/
43287087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
43296c699258SBarry Smith {
43306cab3a1bSJed Brown   PetscErrorCode ierr;
43316cab3a1bSJed Brown 
43326c699258SBarry Smith   PetscFunctionBegin;
43330700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
43346cab3a1bSJed Brown   if (!snes->dm) {
43356cab3a1bSJed Brown     ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr);
43366cab3a1bSJed Brown   }
43376c699258SBarry Smith   *dm = snes->dm;
43386c699258SBarry Smith   PetscFunctionReturn(0);
43396c699258SBarry Smith }
43400807856dSBarry Smith 
434131823bd8SMatthew G Knepley #undef __FUNCT__
434231823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
434331823bd8SMatthew G Knepley /*@
4344fd4b34e9SJed Brown   SNESSetPC - Sets the nonlinear preconditioner to be used.
434531823bd8SMatthew G Knepley 
434631823bd8SMatthew G Knepley   Collective on SNES
434731823bd8SMatthew G Knepley 
434831823bd8SMatthew G Knepley   Input Parameters:
434931823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
435031823bd8SMatthew G Knepley - pc   - the preconditioner object
435131823bd8SMatthew G Knepley 
435231823bd8SMatthew G Knepley   Notes:
435331823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
435431823bd8SMatthew G Knepley   to configure it using the API).
435531823bd8SMatthew G Knepley 
435631823bd8SMatthew G Knepley   Level: developer
435731823bd8SMatthew G Knepley 
435831823bd8SMatthew G Knepley .keywords: SNES, set, precondition
435931823bd8SMatthew G Knepley .seealso: SNESGetPC()
436031823bd8SMatthew G Knepley @*/
436131823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
436231823bd8SMatthew G Knepley {
436331823bd8SMatthew G Knepley   PetscErrorCode ierr;
436431823bd8SMatthew G Knepley 
436531823bd8SMatthew G Knepley   PetscFunctionBegin;
436631823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
436731823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
436831823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
436931823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4370bf11d3b6SBarry Smith   ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr);
437131823bd8SMatthew G Knepley   snes->pc = pc;
437231823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
437331823bd8SMatthew G Knepley   PetscFunctionReturn(0);
437431823bd8SMatthew G Knepley }
437531823bd8SMatthew G Knepley 
437631823bd8SMatthew G Knepley #undef __FUNCT__
437731823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
437831823bd8SMatthew G Knepley /*@
4379fd4b34e9SJed Brown   SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().
438031823bd8SMatthew G Knepley 
438131823bd8SMatthew G Knepley   Not Collective
438231823bd8SMatthew G Knepley 
438331823bd8SMatthew G Knepley   Input Parameter:
438431823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
438531823bd8SMatthew G Knepley 
438631823bd8SMatthew G Knepley   Output Parameter:
438731823bd8SMatthew G Knepley . pc - preconditioner context
438831823bd8SMatthew G Knepley 
438931823bd8SMatthew G Knepley   Level: developer
439031823bd8SMatthew G Knepley 
439131823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
439231823bd8SMatthew G Knepley .seealso: SNESSetPC()
439331823bd8SMatthew G Knepley @*/
439431823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
439531823bd8SMatthew G Knepley {
439631823bd8SMatthew G Knepley   PetscErrorCode              ierr;
4397a64e098fSPeter Brune   const char                  *optionsprefix;
439831823bd8SMatthew G Knepley 
439931823bd8SMatthew G Knepley   PetscFunctionBegin;
440031823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
440131823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
440231823bd8SMatthew G Knepley   if (!snes->pc) {
440331823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm,&snes->pc);CHKERRQ(ierr);
44044a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);CHKERRQ(ierr);
440531823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes,snes->pc);CHKERRQ(ierr);
4406a64e098fSPeter Brune     ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr);
4407a64e098fSPeter Brune     ierr = SNESSetOptionsPrefix(snes->pc,optionsprefix);CHKERRQ(ierr);
4408a64e098fSPeter Brune     ierr = SNESAppendOptionsPrefix(snes->pc,"npc_");CHKERRQ(ierr);
440931823bd8SMatthew G Knepley   }
441031823bd8SMatthew G Knepley   *pc = snes->pc;
441131823bd8SMatthew G Knepley   PetscFunctionReturn(0);
441231823bd8SMatthew G Knepley }
441331823bd8SMatthew G Knepley 
44149e764e56SPeter Brune #undef __FUNCT__
4415f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch"
44169e764e56SPeter Brune /*@
44178141a3b9SPeter Brune   SNESSetSNESLineSearch - Sets the linesearch on the SNES instance.
44189e764e56SPeter Brune 
44199e764e56SPeter Brune   Collective on SNES
44209e764e56SPeter Brune 
44219e764e56SPeter Brune   Input Parameters:
44229e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
44239e764e56SPeter Brune - linesearch   - the linesearch object
44249e764e56SPeter Brune 
44259e764e56SPeter Brune   Notes:
4426f1c6b773SPeter Brune   Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example,
44279e764e56SPeter Brune   to configure it using the API).
44289e764e56SPeter Brune 
44299e764e56SPeter Brune   Level: developer
44309e764e56SPeter Brune 
44319e764e56SPeter Brune .keywords: SNES, set, linesearch
4432f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch()
44339e764e56SPeter Brune @*/
4434f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch)
44359e764e56SPeter Brune {
44369e764e56SPeter Brune   PetscErrorCode ierr;
44379e764e56SPeter Brune 
44389e764e56SPeter Brune   PetscFunctionBegin;
44399e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4440f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
44419e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
44429e764e56SPeter Brune   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
4443f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
44449e764e56SPeter Brune   snes->linesearch = linesearch;
44459e764e56SPeter Brune   ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
44469e764e56SPeter Brune   PetscFunctionReturn(0);
44479e764e56SPeter Brune }
44489e764e56SPeter Brune 
44499e764e56SPeter Brune #undef __FUNCT__
4450f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch"
4451ea5d4fccSPeter Brune /*@C
44528141a3b9SPeter Brune   SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch()
44538141a3b9SPeter Brune   or creates a default line search instance associated with the SNES and returns it.
44549e764e56SPeter Brune 
44559e764e56SPeter Brune   Not Collective
44569e764e56SPeter Brune 
44579e764e56SPeter Brune   Input Parameter:
44589e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
44599e764e56SPeter Brune 
44609e764e56SPeter Brune   Output Parameter:
44619e764e56SPeter Brune . linesearch - linesearch context
44629e764e56SPeter Brune 
44639e764e56SPeter Brune   Level: developer
44649e764e56SPeter Brune 
44659e764e56SPeter Brune .keywords: SNES, get, linesearch
4466f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch()
44679e764e56SPeter Brune @*/
4468f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch)
44699e764e56SPeter Brune {
44709e764e56SPeter Brune   PetscErrorCode ierr;
44719e764e56SPeter Brune   const char     *optionsprefix;
44729e764e56SPeter Brune 
44739e764e56SPeter Brune   PetscFunctionBegin;
44749e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
44759e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
44769e764e56SPeter Brune   if (!snes->linesearch) {
44779e764e56SPeter Brune     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
4478f1c6b773SPeter Brune     ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr);
4479f1c6b773SPeter Brune     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
4480b1dca40bSPeter Brune     ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr);
44819e764e56SPeter Brune     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
44829e764e56SPeter Brune     ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
44839e764e56SPeter Brune   }
44849e764e56SPeter Brune   *linesearch = snes->linesearch;
44859e764e56SPeter Brune   PetscFunctionReturn(0);
44869e764e56SPeter Brune }
44879e764e56SPeter Brune 
448869b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4489c6db04a5SJed Brown #include <mex.h>
449069b4f73cSBarry Smith 
44918f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
44928f6e6473SBarry Smith 
44930807856dSBarry Smith #undef __FUNCT__
44940807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
44950807856dSBarry Smith /*
44960807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
44970807856dSBarry Smith                          SNESSetFunctionMatlab().
44980807856dSBarry Smith 
44990807856dSBarry Smith    Collective on SNES
45000807856dSBarry Smith 
45010807856dSBarry Smith    Input Parameters:
45020807856dSBarry Smith +  snes - the SNES context
45030807856dSBarry Smith -  x - input vector
45040807856dSBarry Smith 
45050807856dSBarry Smith    Output Parameter:
45060807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
45070807856dSBarry Smith 
45080807856dSBarry Smith    Notes:
45090807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
45100807856dSBarry Smith    implementations, so most users would not generally call this routine
45110807856dSBarry Smith    themselves.
45120807856dSBarry Smith 
45130807856dSBarry Smith    Level: developer
45140807856dSBarry Smith 
45150807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
45160807856dSBarry Smith 
45170807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
451861b2408cSBarry Smith */
45197087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
45200807856dSBarry Smith {
4521e650e774SBarry Smith   PetscErrorCode    ierr;
45228f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
45238f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
45248f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
452591621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
4526e650e774SBarry Smith 
45270807856dSBarry Smith   PetscFunctionBegin;
45280807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
45290807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
45300807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
45310807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
45320807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
45330807856dSBarry Smith 
45340807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
4535e650e774SBarry Smith 
453691621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4537e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4538e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
453991621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
454091621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
454191621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
45428f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
45438f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
4544b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
4545e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4546e650e774SBarry Smith   mxDestroyArray(prhs[0]);
4547e650e774SBarry Smith   mxDestroyArray(prhs[1]);
4548e650e774SBarry Smith   mxDestroyArray(prhs[2]);
45498f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
4550e650e774SBarry Smith   mxDestroyArray(plhs[0]);
45510807856dSBarry Smith   PetscFunctionReturn(0);
45520807856dSBarry Smith }
45530807856dSBarry Smith 
45540807856dSBarry Smith 
45550807856dSBarry Smith #undef __FUNCT__
45560807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
455761b2408cSBarry Smith /*
45580807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
45590807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4560e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
45610807856dSBarry Smith 
45620807856dSBarry Smith    Logically Collective on SNES
45630807856dSBarry Smith 
45640807856dSBarry Smith    Input Parameters:
45650807856dSBarry Smith +  snes - the SNES context
45660807856dSBarry Smith .  r - vector to store function value
45670807856dSBarry Smith -  func - function evaluation routine
45680807856dSBarry Smith 
45690807856dSBarry Smith    Calling sequence of func:
457061b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
45710807856dSBarry Smith 
45720807856dSBarry Smith 
45730807856dSBarry Smith    Notes:
45740807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
45750807856dSBarry Smith $      f'(x) x = -f(x),
45760807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
45770807856dSBarry Smith 
45780807856dSBarry Smith    Level: beginner
45790807856dSBarry Smith 
45800807856dSBarry Smith .keywords: SNES, nonlinear, set, function
45810807856dSBarry Smith 
45820807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
458361b2408cSBarry Smith */
45847087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
45850807856dSBarry Smith {
45860807856dSBarry Smith   PetscErrorCode    ierr;
45878f6e6473SBarry Smith   SNESMatlabContext *sctx;
45880807856dSBarry Smith 
45890807856dSBarry Smith   PetscFunctionBegin;
45908f6e6473SBarry Smith   /* currently sctx is memory bleed */
45918f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
45928f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
45938f6e6473SBarry Smith   /*
45948f6e6473SBarry Smith      This should work, but it doesn't
45958f6e6473SBarry Smith   sctx->ctx = ctx;
45968f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
45978f6e6473SBarry Smith   */
45988f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
45998f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
46000807856dSBarry Smith   PetscFunctionReturn(0);
46010807856dSBarry Smith }
460269b4f73cSBarry Smith 
460361b2408cSBarry Smith #undef __FUNCT__
460461b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
460561b2408cSBarry Smith /*
460661b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
460761b2408cSBarry Smith                          SNESSetJacobianMatlab().
460861b2408cSBarry Smith 
460961b2408cSBarry Smith    Collective on SNES
461061b2408cSBarry Smith 
461161b2408cSBarry Smith    Input Parameters:
461261b2408cSBarry Smith +  snes - the SNES context
461361b2408cSBarry Smith .  x - input vector
461461b2408cSBarry Smith .  A, B - the matrices
461561b2408cSBarry Smith -  ctx - user context
461661b2408cSBarry Smith 
461761b2408cSBarry Smith    Output Parameter:
461861b2408cSBarry Smith .  flag - structure of the matrix
461961b2408cSBarry Smith 
462061b2408cSBarry Smith    Level: developer
462161b2408cSBarry Smith 
462261b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
462361b2408cSBarry Smith 
462461b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
462561b2408cSBarry Smith @*/
46267087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
462761b2408cSBarry Smith {
462861b2408cSBarry Smith   PetscErrorCode    ierr;
462961b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
463061b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
463161b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
463261b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
463361b2408cSBarry Smith 
463461b2408cSBarry Smith   PetscFunctionBegin;
463561b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
463661b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
463761b2408cSBarry Smith 
463861b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
463961b2408cSBarry Smith 
464061b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
464161b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
464261b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
464361b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
464461b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
464561b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
464661b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
464761b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
464861b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
464961b2408cSBarry Smith   prhs[5] =  sctx->ctx;
4650b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
465161b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
465261b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
465361b2408cSBarry Smith   mxDestroyArray(prhs[0]);
465461b2408cSBarry Smith   mxDestroyArray(prhs[1]);
465561b2408cSBarry Smith   mxDestroyArray(prhs[2]);
465661b2408cSBarry Smith   mxDestroyArray(prhs[3]);
465761b2408cSBarry Smith   mxDestroyArray(prhs[4]);
465861b2408cSBarry Smith   mxDestroyArray(plhs[0]);
465961b2408cSBarry Smith   mxDestroyArray(plhs[1]);
466061b2408cSBarry Smith   PetscFunctionReturn(0);
466161b2408cSBarry Smith }
466261b2408cSBarry Smith 
466361b2408cSBarry Smith 
466461b2408cSBarry Smith #undef __FUNCT__
466561b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
466661b2408cSBarry Smith /*
466761b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
466861b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4669e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
467061b2408cSBarry Smith 
467161b2408cSBarry Smith    Logically Collective on SNES
467261b2408cSBarry Smith 
467361b2408cSBarry Smith    Input Parameters:
467461b2408cSBarry Smith +  snes - the SNES context
467561b2408cSBarry Smith .  A,B - Jacobian matrices
467661b2408cSBarry Smith .  func - function evaluation routine
467761b2408cSBarry Smith -  ctx - user context
467861b2408cSBarry Smith 
467961b2408cSBarry Smith    Calling sequence of func:
468061b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
468161b2408cSBarry Smith 
468261b2408cSBarry Smith 
468361b2408cSBarry Smith    Level: developer
468461b2408cSBarry Smith 
468561b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
468661b2408cSBarry Smith 
468761b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
468861b2408cSBarry Smith */
46897087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
469061b2408cSBarry Smith {
469161b2408cSBarry Smith   PetscErrorCode    ierr;
469261b2408cSBarry Smith   SNESMatlabContext *sctx;
469361b2408cSBarry Smith 
469461b2408cSBarry Smith   PetscFunctionBegin;
469561b2408cSBarry Smith   /* currently sctx is memory bleed */
469661b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
469761b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
469861b2408cSBarry Smith   /*
469961b2408cSBarry Smith      This should work, but it doesn't
470061b2408cSBarry Smith   sctx->ctx = ctx;
470161b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
470261b2408cSBarry Smith   */
470361b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
470461b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
470561b2408cSBarry Smith   PetscFunctionReturn(0);
470661b2408cSBarry Smith }
470769b4f73cSBarry Smith 
4708f9eb7ae2SShri Abhyankar #undef __FUNCT__
4709f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
4710f9eb7ae2SShri Abhyankar /*
4711f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
4712f9eb7ae2SShri Abhyankar 
4713f9eb7ae2SShri Abhyankar    Collective on SNES
4714f9eb7ae2SShri Abhyankar 
4715f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
4716f9eb7ae2SShri Abhyankar @*/
47177087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
4718f9eb7ae2SShri Abhyankar {
4719f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
472048f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
4721f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
4722f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
4723f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
4724f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
4725f9eb7ae2SShri Abhyankar 
4726f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4727f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4728f9eb7ae2SShri Abhyankar 
4729f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4730f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4731f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
4732f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
4733f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
4734f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
4735f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
4736f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
4737f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
4738f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4739f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
4740f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
4741f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
4742f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
4743f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
4744f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
4745f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4746f9eb7ae2SShri Abhyankar }
4747f9eb7ae2SShri Abhyankar 
4748f9eb7ae2SShri Abhyankar 
4749f9eb7ae2SShri Abhyankar #undef __FUNCT__
4750f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
4751f9eb7ae2SShri Abhyankar /*
4752e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
4753f9eb7ae2SShri Abhyankar 
4754f9eb7ae2SShri Abhyankar    Level: developer
4755f9eb7ae2SShri Abhyankar 
4756f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
4757f9eb7ae2SShri Abhyankar 
4758f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
4759f9eb7ae2SShri Abhyankar */
47607087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
4761f9eb7ae2SShri Abhyankar {
4762f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
4763f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
4764f9eb7ae2SShri Abhyankar 
4765f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4766f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
4767f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
4768f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4769f9eb7ae2SShri Abhyankar   /*
4770f9eb7ae2SShri Abhyankar      This should work, but it doesn't
4771f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
4772f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
4773f9eb7ae2SShri Abhyankar   */
4774f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
4775f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4776f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4777f9eb7ae2SShri Abhyankar }
4778f9eb7ae2SShri Abhyankar 
477969b4f73cSBarry Smith #endif
4780