xref: /petsc/src/snes/interface/snes.c (revision 3f7e2da0cd1ad29222fca2148815285575d4c903)
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) {
39817842b4fSJed Brown     SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_PLIB,"SNESDM not improperly configured");
3996cab3a1bSJed Brown   } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) {
4006cab3a1bSJed Brown     Mat J;
4016cab3a1bSJed Brown     void *functx;
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     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
4066cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
4076cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
408caa4e7f2SJed Brown   } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
4096cab3a1bSJed Brown     Mat J,B;
4106cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4116cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4126cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4136cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
41406f20277SJed Brown     /* sdm->computejacobian was already set to reach here */
41506f20277SJed Brown     ierr = SNESSetJacobian(snes,J,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
4166cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
4176cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
418caa4e7f2SJed Brown   } else if (!snes->jacobian_pre) {
4196cab3a1bSJed Brown     Mat J,B;
4206cab3a1bSJed Brown     J = snes->jacobian;
4216cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4226cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
4236cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
4246cab3a1bSJed Brown   }
425caa4e7f2SJed Brown   {
42660a3618bSJed Brown     PetscBool flg = PETSC_FALSE;
427caa4e7f2SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_kspcompute",&flg,PETSC_NULL);CHKERRQ(ierr);
428caa4e7f2SJed Brown     if (flg) {                  /* Plan to transition to this model */
429caa4e7f2SJed Brown       KSP ksp;
430caa4e7f2SJed Brown       ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
431caa4e7f2SJed Brown       ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr);
432dfe15315SJed Brown       ierr = DMCoarsenHookAdd(snes->dm,PETSC_NULL,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr);
433caa4e7f2SJed Brown     }
434caa4e7f2SJed Brown   }
4356cab3a1bSJed Brown   PetscFunctionReturn(0);
4366cab3a1bSJed Brown }
4376cab3a1bSJed Brown 
4386cab3a1bSJed Brown #undef __FUNCT__
4394a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions"
4409b94acceSBarry Smith /*@
44194b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
4429b94acceSBarry Smith 
443c7afd0dbSLois Curfman McInnes    Collective on SNES
444c7afd0dbSLois Curfman McInnes 
4459b94acceSBarry Smith    Input Parameter:
4469b94acceSBarry Smith .  snes - the SNES context
4479b94acceSBarry Smith 
44836851e7fSLois Curfman McInnes    Options Database Keys:
449ea630c6eSPeter Brune +  -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas
45082738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
45182738288SBarry Smith                 of the change in the solution between steps
45270441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
453b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
454b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
455b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
4564839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
457ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
458a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
459e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
460b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
4612492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
46282738288SBarry Smith                                solver; hence iterations will continue until max_it
4631fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
46482738288SBarry Smith                                of convergence test
465e8105e01SRichard Katz .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
466e8105e01SRichard Katz                                        filename given prints to stdout
467a6570f20SBarry Smith .  -snes_monitor_solution - plots solution at each iteration
468a6570f20SBarry Smith .  -snes_monitor_residual - plots residual (not its norm) at each iteration
469a6570f20SBarry Smith .  -snes_monitor_solution_update - plots update to solution at each iteration
470a6570f20SBarry Smith .  -snes_monitor_draw - plots residual norm at each iteration
471e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
4725968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
473fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
47482738288SBarry Smith 
47582738288SBarry Smith     Options Database for Eisenstat-Walker method:
476fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
4774b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
47836851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
47936851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
48036851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
48136851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
48236851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
48336851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
48482738288SBarry Smith 
48511ca99fdSLois Curfman McInnes    Notes:
48611ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
4870598bfebSBarry Smith    the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>.
48883e2fdc7SBarry Smith 
48936851e7fSLois Curfman McInnes    Level: beginner
49036851e7fSLois Curfman McInnes 
4919b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
4929b94acceSBarry Smith 
49369ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
4949b94acceSBarry Smith @*/
4957087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
4969b94acceSBarry Smith {
497872b6db9SPeter Brune   PetscBool               flg,mf,mf_operator,pcset;
498efd51863SBarry Smith   PetscInt                i,indx,lag,mf_version,grids;
499aa3661deSLisandro Dalcin   MatStructure            matflag;
50085385478SLisandro Dalcin   const char              *deft = SNESLS;
50185385478SLisandro Dalcin   const char              *convtests[] = {"default","skip"};
50285385478SLisandro Dalcin   SNESKSPEW               *kctx = NULL;
503e8105e01SRichard Katz   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
504649052a6SBarry Smith   PetscViewer             monviewer;
50585385478SLisandro Dalcin   PetscErrorCode          ierr;
506a64e098fSPeter Brune   const char              *optionsprefix;
5079b94acceSBarry Smith 
5083a40ed3dSBarry Smith   PetscFunctionBegin;
5090700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
510ca161407SBarry Smith 
511186905e3SBarry Smith   if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
5123194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
5137adad957SLisandro Dalcin     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
514b0a32e0cSBarry Smith     ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
515d64ed03dSBarry Smith     if (flg) {
516186905e3SBarry Smith       ierr = SNESSetType(snes,type);CHKERRQ(ierr);
5177adad957SLisandro Dalcin     } else if (!((PetscObject)snes)->type_name) {
518186905e3SBarry Smith       ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
519d64ed03dSBarry Smith     }
52090d69ab7SBarry Smith     /* not used here, but called so will go into help messaage */
521909c8a9fSBarry Smith     ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr);
52293c39befSBarry Smith 
523c60f73f4SPeter Brune     ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);CHKERRQ(ierr);
52457034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr);
525186905e3SBarry Smith 
52657034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr);
527b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr);
528b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr);
52924254dc1SJed Brown     ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr);
530ddf469c8SBarry Smith     ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr);
531acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr);
53285385478SLisandro Dalcin 
533a8054027SBarry Smith     ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
534a8054027SBarry Smith     if (flg) {
535a8054027SBarry Smith       ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
536a8054027SBarry Smith     }
537e35cf81dSBarry Smith     ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
538e35cf81dSBarry Smith     if (flg) {
539e35cf81dSBarry Smith       ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
540e35cf81dSBarry Smith     }
541efd51863SBarry Smith     ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
542efd51863SBarry Smith     if (flg) {
543efd51863SBarry Smith       ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
544efd51863SBarry Smith     }
545a8054027SBarry Smith 
54685385478SLisandro Dalcin     ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
54785385478SLisandro Dalcin     if (flg) {
54885385478SLisandro Dalcin       switch (indx) {
5497f7931b9SBarry Smith       case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break;
5507f7931b9SBarry Smith       case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);    break;
55185385478SLisandro Dalcin       }
55285385478SLisandro Dalcin     }
55385385478SLisandro Dalcin 
554acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr);
555186905e3SBarry Smith 
556fdacfa88SPeter Brune     ierr = PetscOptionsEList("-snes_norm_type","SNES Norm type","SNESSetNormType",SNESNormTypes,5,"function",&indx,&flg);CHKERRQ(ierr);
557fdacfa88SPeter Brune     if (flg) { ierr = SNESSetNormType(snes,(SNESNormType)indx);CHKERRQ(ierr); }
558fdacfa88SPeter Brune 
55985385478SLisandro Dalcin     kctx = (SNESKSPEW *)snes->kspconvctx;
56085385478SLisandro Dalcin 
561acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr);
562186905e3SBarry Smith 
563fa9f3622SBarry Smith     ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr);
564fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr);
565fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr);
566fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr);
567fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr);
568fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr);
569fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr);
570186905e3SBarry Smith 
57190d69ab7SBarry Smith     flg  = PETSC_FALSE;
572acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
573a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
574eabae89aSBarry Smith 
575a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
576e8105e01SRichard Katz     if (flg) {
577649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
578649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
579e8105e01SRichard Katz     }
580eabae89aSBarry Smith 
581b271bb04SBarry Smith     ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
582b271bb04SBarry Smith     if (flg) {
583b271bb04SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr);
584b271bb04SBarry Smith     }
585b271bb04SBarry Smith 
586a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
587eabae89aSBarry Smith     if (flg) {
588649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
589f1bef1bcSMatthew Knepley       ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr);
590e8105e01SRichard Katz     }
591eabae89aSBarry Smith 
592a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
593eabae89aSBarry Smith     if (flg) {
594649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
595649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
596eabae89aSBarry Smith     }
597eabae89aSBarry Smith 
5985180491cSLisandro Dalcin     ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
5995180491cSLisandro Dalcin     if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);}
6005180491cSLisandro Dalcin 
60190d69ab7SBarry Smith     flg  = PETSC_FALSE;
602acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
603a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
60490d69ab7SBarry Smith     flg  = PETSC_FALSE;
605acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
606a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
60790d69ab7SBarry Smith     flg  = PETSC_FALSE;
608acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
609a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
61090d69ab7SBarry Smith     flg  = PETSC_FALSE;
611acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
612a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
61390d69ab7SBarry Smith     flg  = PETSC_FALSE;
614acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
615b271bb04SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
616e24b481bSBarry Smith 
61790d69ab7SBarry Smith     flg  = PETSC_FALSE;
618acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
6194b27c08aSLois Curfman McInnes     if (flg) {
6206cab3a1bSJed Brown       void *functx;
6216cab3a1bSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
6226cab3a1bSJed Brown       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr);
623ae15b995SBarry Smith       ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
6249b94acceSBarry Smith     }
625639f9d9dSBarry Smith 
626aa3661deSLisandro Dalcin     mf = mf_operator = PETSC_FALSE;
627aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
628acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr);
629a8248277SBarry Smith     if (flg && mf_operator) {
630a8248277SBarry Smith       snes->mf_operator = PETSC_TRUE;
631a8248277SBarry Smith       mf = PETSC_TRUE;
632a8248277SBarry Smith     }
633aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
634acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr);
635aa3661deSLisandro Dalcin     if (!flg && mf_operator) mf = PETSC_TRUE;
636aa3661deSLisandro Dalcin     mf_version = 1;
637aa3661deSLisandro Dalcin     ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr);
638aa3661deSLisandro Dalcin 
639d28543b3SPeter Brune 
64089b92e6fSPeter Brune     /* GS Options */
64189b92e6fSPeter Brune     ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr);
64289b92e6fSPeter Brune 
64376b2cf59SMatthew Knepley     for(i = 0; i < numberofsetfromoptions; i++) {
64476b2cf59SMatthew Knepley       ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
64576b2cf59SMatthew Knepley     }
64676b2cf59SMatthew Knepley 
647e7788613SBarry Smith     if (snes->ops->setfromoptions) {
648e7788613SBarry Smith       ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr);
649639f9d9dSBarry Smith     }
6505d973c19SBarry Smith 
6515d973c19SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
6525d973c19SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr);
653b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
6544bbc92c1SBarry Smith 
655aa3661deSLisandro Dalcin   if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); }
6561cee3971SBarry Smith 
6571cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
658aa3661deSLisandro Dalcin   ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
659aa3661deSLisandro Dalcin   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr);
66085385478SLisandro Dalcin   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
66193993e2dSLois Curfman McInnes 
6629e764e56SPeter Brune   if (!snes->linesearch) {
663f1c6b773SPeter Brune     ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
6649e764e56SPeter Brune   }
665f1c6b773SPeter Brune   ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr);
6669e764e56SPeter Brune 
66751e86f29SPeter Brune   /* if someone has set the SNES PC type, create it. */
66851e86f29SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
66951e86f29SPeter Brune   ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr);
67051e86f29SPeter Brune   if (pcset && (!snes->pc)) {
67151e86f29SPeter Brune     ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr);
67251e86f29SPeter Brune   }
6733a40ed3dSBarry Smith   PetscFunctionReturn(0);
6749b94acceSBarry Smith }
6759b94acceSBarry Smith 
676d25893d9SBarry Smith #undef __FUNCT__
677d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext"
678d25893d9SBarry Smith /*@
679d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
680d25893d9SBarry Smith    the nonlinear solvers.
681d25893d9SBarry Smith 
682d25893d9SBarry Smith    Logically Collective on SNES
683d25893d9SBarry Smith 
684d25893d9SBarry Smith    Input Parameters:
685d25893d9SBarry Smith +  snes - the SNES context
686d25893d9SBarry Smith .  compute - function to compute the context
687d25893d9SBarry Smith -  destroy - function to destroy the context
688d25893d9SBarry Smith 
689d25893d9SBarry Smith    Level: intermediate
690d25893d9SBarry Smith 
691d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
692d25893d9SBarry Smith 
693d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
694d25893d9SBarry Smith @*/
695d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
696d25893d9SBarry Smith {
697d25893d9SBarry Smith   PetscFunctionBegin;
698d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
699d25893d9SBarry Smith   snes->ops->usercompute = compute;
700d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
701d25893d9SBarry Smith   PetscFunctionReturn(0);
702d25893d9SBarry Smith }
703a847f771SSatish Balay 
7044a2ae208SSatish Balay #undef __FUNCT__
7054a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
706b07ff414SBarry Smith /*@
7079b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
7089b94acceSBarry Smith    the nonlinear solvers.
7099b94acceSBarry Smith 
7103f9fe445SBarry Smith    Logically Collective on SNES
711fee21e36SBarry Smith 
712c7afd0dbSLois Curfman McInnes    Input Parameters:
713c7afd0dbSLois Curfman McInnes +  snes - the SNES context
714c7afd0dbSLois Curfman McInnes -  usrP - optional user context
715c7afd0dbSLois Curfman McInnes 
71636851e7fSLois Curfman McInnes    Level: intermediate
71736851e7fSLois Curfman McInnes 
7189b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
7199b94acceSBarry Smith 
720ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext()
7219b94acceSBarry Smith @*/
7227087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
7239b94acceSBarry Smith {
7241b2093e4SBarry Smith   PetscErrorCode ierr;
725b07ff414SBarry Smith   KSP            ksp;
7261b2093e4SBarry Smith 
7273a40ed3dSBarry Smith   PetscFunctionBegin;
7280700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
729b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
730b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
7319b94acceSBarry Smith   snes->user = usrP;
7323a40ed3dSBarry Smith   PetscFunctionReturn(0);
7339b94acceSBarry Smith }
73474679c65SBarry Smith 
7354a2ae208SSatish Balay #undef __FUNCT__
7364a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
737b07ff414SBarry Smith /*@
7389b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
7399b94acceSBarry Smith    nonlinear solvers.
7409b94acceSBarry Smith 
741c7afd0dbSLois Curfman McInnes    Not Collective
742c7afd0dbSLois Curfman McInnes 
7439b94acceSBarry Smith    Input Parameter:
7449b94acceSBarry Smith .  snes - SNES context
7459b94acceSBarry Smith 
7469b94acceSBarry Smith    Output Parameter:
7479b94acceSBarry Smith .  usrP - user context
7489b94acceSBarry Smith 
74936851e7fSLois Curfman McInnes    Level: intermediate
75036851e7fSLois Curfman McInnes 
7519b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
7529b94acceSBarry Smith 
7539b94acceSBarry Smith .seealso: SNESSetApplicationContext()
7549b94acceSBarry Smith @*/
755e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
7569b94acceSBarry Smith {
7573a40ed3dSBarry Smith   PetscFunctionBegin;
7580700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
759e71120c6SJed Brown   *(void**)usrP = snes->user;
7603a40ed3dSBarry Smith   PetscFunctionReturn(0);
7619b94acceSBarry Smith }
76274679c65SBarry Smith 
7634a2ae208SSatish Balay #undef __FUNCT__
7644a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
7659b94acceSBarry Smith /*@
766c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
767c8228a4eSBarry Smith    at this time.
7689b94acceSBarry Smith 
769c7afd0dbSLois Curfman McInnes    Not Collective
770c7afd0dbSLois Curfman McInnes 
7719b94acceSBarry Smith    Input Parameter:
7729b94acceSBarry Smith .  snes - SNES context
7739b94acceSBarry Smith 
7749b94acceSBarry Smith    Output Parameter:
7759b94acceSBarry Smith .  iter - iteration number
7769b94acceSBarry Smith 
777c8228a4eSBarry Smith    Notes:
778c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
779c8228a4eSBarry Smith 
780c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
78108405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
78208405cd6SLois Curfman McInnes .vb
78308405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
78408405cd6SLois Curfman McInnes       if (!(it % 2)) {
78508405cd6SLois Curfman McInnes         [compute Jacobian here]
78608405cd6SLois Curfman McInnes       }
78708405cd6SLois Curfman McInnes .ve
788c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
78908405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
790c8228a4eSBarry Smith 
79136851e7fSLois Curfman McInnes    Level: intermediate
79236851e7fSLois Curfman McInnes 
7932b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
7942b668275SBarry Smith 
795b850b91aSLisandro Dalcin .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
7969b94acceSBarry Smith @*/
7977087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
7989b94acceSBarry Smith {
7993a40ed3dSBarry Smith   PetscFunctionBegin;
8000700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8014482741eSBarry Smith   PetscValidIntPointer(iter,2);
8029b94acceSBarry Smith   *iter = snes->iter;
8033a40ed3dSBarry Smith   PetscFunctionReturn(0);
8049b94acceSBarry Smith }
80574679c65SBarry Smith 
8064a2ae208SSatish Balay #undef __FUNCT__
807360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber"
808360c497dSPeter Brune /*@
809360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
810360c497dSPeter Brune 
811360c497dSPeter Brune    Not Collective
812360c497dSPeter Brune 
813360c497dSPeter Brune    Input Parameter:
814360c497dSPeter Brune .  snes - SNES context
815360c497dSPeter Brune .  iter - iteration number
816360c497dSPeter Brune 
817360c497dSPeter Brune    Level: developer
818360c497dSPeter Brune 
819360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number,
820360c497dSPeter Brune 
821360c497dSPeter Brune .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
822360c497dSPeter Brune @*/
823360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
824360c497dSPeter Brune {
825360c497dSPeter Brune   PetscErrorCode ierr;
826360c497dSPeter Brune 
827360c497dSPeter Brune   PetscFunctionBegin;
828360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
829360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
830360c497dSPeter Brune   snes->iter = iter;
831360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
832360c497dSPeter Brune   PetscFunctionReturn(0);
833360c497dSPeter Brune }
834360c497dSPeter Brune 
835360c497dSPeter Brune #undef __FUNCT__
8364a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm"
8379b94acceSBarry Smith /*@
8389b94acceSBarry Smith    SNESGetFunctionNorm - Gets the norm of the current function that was set
8399b94acceSBarry Smith    with SNESSSetFunction().
8409b94acceSBarry Smith 
841c7afd0dbSLois Curfman McInnes    Collective on SNES
842c7afd0dbSLois Curfman McInnes 
8439b94acceSBarry Smith    Input Parameter:
8449b94acceSBarry Smith .  snes - SNES context
8459b94acceSBarry Smith 
8469b94acceSBarry Smith    Output Parameter:
8479b94acceSBarry Smith .  fnorm - 2-norm of function
8489b94acceSBarry Smith 
84936851e7fSLois Curfman McInnes    Level: intermediate
85036851e7fSLois Curfman McInnes 
8519b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm
852a86d99e1SLois Curfman McInnes 
853b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
8549b94acceSBarry Smith @*/
8557087cfbeSBarry Smith PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
8569b94acceSBarry Smith {
8573a40ed3dSBarry Smith   PetscFunctionBegin;
8580700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8594482741eSBarry Smith   PetscValidScalarPointer(fnorm,2);
8609b94acceSBarry Smith   *fnorm = snes->norm;
8613a40ed3dSBarry Smith   PetscFunctionReturn(0);
8629b94acceSBarry Smith }
86374679c65SBarry Smith 
864360c497dSPeter Brune 
865360c497dSPeter Brune #undef __FUNCT__
866360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm"
867360c497dSPeter Brune /*@
868360c497dSPeter Brune    SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm().
869360c497dSPeter Brune 
870360c497dSPeter Brune    Collective on SNES
871360c497dSPeter Brune 
872360c497dSPeter Brune    Input Parameter:
873360c497dSPeter Brune .  snes - SNES context
874360c497dSPeter Brune .  fnorm - 2-norm of function
875360c497dSPeter Brune 
876360c497dSPeter Brune    Level: developer
877360c497dSPeter Brune 
878360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm
879360c497dSPeter Brune 
880360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm().
881360c497dSPeter Brune @*/
882360c497dSPeter Brune PetscErrorCode  SNESSetFunctionNorm(SNES snes,PetscReal fnorm)
883360c497dSPeter Brune {
884360c497dSPeter Brune 
885360c497dSPeter Brune   PetscErrorCode ierr;
886360c497dSPeter Brune 
887360c497dSPeter Brune   PetscFunctionBegin;
888360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
889360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
890360c497dSPeter Brune   snes->norm = fnorm;
891360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
892360c497dSPeter Brune   PetscFunctionReturn(0);
893360c497dSPeter Brune }
894360c497dSPeter Brune 
8954a2ae208SSatish Balay #undef __FUNCT__
896b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
8979b94acceSBarry Smith /*@
898b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
8999b94acceSBarry Smith    attempted by the nonlinear solver.
9009b94acceSBarry Smith 
901c7afd0dbSLois Curfman McInnes    Not Collective
902c7afd0dbSLois Curfman McInnes 
9039b94acceSBarry Smith    Input Parameter:
9049b94acceSBarry Smith .  snes - SNES context
9059b94acceSBarry Smith 
9069b94acceSBarry Smith    Output Parameter:
9079b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
9089b94acceSBarry Smith 
909c96a6f78SLois Curfman McInnes    Notes:
910c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
911c96a6f78SLois Curfman McInnes 
91236851e7fSLois Curfman McInnes    Level: intermediate
91336851e7fSLois Curfman McInnes 
9149b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
91558ebbce7SBarry Smith 
916e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
91758ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
9189b94acceSBarry Smith @*/
9197087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
9209b94acceSBarry Smith {
9213a40ed3dSBarry Smith   PetscFunctionBegin;
9220700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9234482741eSBarry Smith   PetscValidIntPointer(nfails,2);
92450ffb88aSMatthew Knepley   *nfails = snes->numFailures;
92550ffb88aSMatthew Knepley   PetscFunctionReturn(0);
92650ffb88aSMatthew Knepley }
92750ffb88aSMatthew Knepley 
92850ffb88aSMatthew Knepley #undef __FUNCT__
929b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
93050ffb88aSMatthew Knepley /*@
931b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
93250ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
93350ffb88aSMatthew Knepley 
93450ffb88aSMatthew Knepley    Not Collective
93550ffb88aSMatthew Knepley 
93650ffb88aSMatthew Knepley    Input Parameters:
93750ffb88aSMatthew Knepley +  snes     - SNES context
93850ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
93950ffb88aSMatthew Knepley 
94050ffb88aSMatthew Knepley    Level: intermediate
94150ffb88aSMatthew Knepley 
94250ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
94358ebbce7SBarry Smith 
944e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
94558ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
94650ffb88aSMatthew Knepley @*/
9477087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
94850ffb88aSMatthew Knepley {
94950ffb88aSMatthew Knepley   PetscFunctionBegin;
9500700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
95150ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
95250ffb88aSMatthew Knepley   PetscFunctionReturn(0);
95350ffb88aSMatthew Knepley }
95450ffb88aSMatthew Knepley 
95550ffb88aSMatthew Knepley #undef __FUNCT__
956b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
95750ffb88aSMatthew Knepley /*@
958b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
95950ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
96050ffb88aSMatthew Knepley 
96150ffb88aSMatthew Knepley    Not Collective
96250ffb88aSMatthew Knepley 
96350ffb88aSMatthew Knepley    Input Parameter:
96450ffb88aSMatthew Knepley .  snes     - SNES context
96550ffb88aSMatthew Knepley 
96650ffb88aSMatthew Knepley    Output Parameter:
96750ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
96850ffb88aSMatthew Knepley 
96950ffb88aSMatthew Knepley    Level: intermediate
97050ffb88aSMatthew Knepley 
97150ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
97258ebbce7SBarry Smith 
973e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
97458ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
97558ebbce7SBarry Smith 
97650ffb88aSMatthew Knepley @*/
9777087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
97850ffb88aSMatthew Knepley {
97950ffb88aSMatthew Knepley   PetscFunctionBegin;
9800700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9814482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
98250ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
9833a40ed3dSBarry Smith   PetscFunctionReturn(0);
9849b94acceSBarry Smith }
985a847f771SSatish Balay 
9864a2ae208SSatish Balay #undef __FUNCT__
9872541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
9882541af92SBarry Smith /*@
9892541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
9902541af92SBarry Smith      done by SNES.
9912541af92SBarry Smith 
9922541af92SBarry Smith    Not Collective
9932541af92SBarry Smith 
9942541af92SBarry Smith    Input Parameter:
9952541af92SBarry Smith .  snes     - SNES context
9962541af92SBarry Smith 
9972541af92SBarry Smith    Output Parameter:
9982541af92SBarry Smith .  nfuncs - number of evaluations
9992541af92SBarry Smith 
10002541af92SBarry Smith    Level: intermediate
10012541af92SBarry Smith 
10022541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
100358ebbce7SBarry Smith 
1004e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
10052541af92SBarry Smith @*/
10067087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
10072541af92SBarry Smith {
10082541af92SBarry Smith   PetscFunctionBegin;
10090700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10102541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
10112541af92SBarry Smith   *nfuncs = snes->nfuncs;
10122541af92SBarry Smith   PetscFunctionReturn(0);
10132541af92SBarry Smith }
10142541af92SBarry Smith 
10152541af92SBarry Smith #undef __FUNCT__
10163d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
10173d4c4710SBarry Smith /*@
10183d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
10193d4c4710SBarry Smith    linear solvers.
10203d4c4710SBarry Smith 
10213d4c4710SBarry Smith    Not Collective
10223d4c4710SBarry Smith 
10233d4c4710SBarry Smith    Input Parameter:
10243d4c4710SBarry Smith .  snes - SNES context
10253d4c4710SBarry Smith 
10263d4c4710SBarry Smith    Output Parameter:
10273d4c4710SBarry Smith .  nfails - number of failed solves
10283d4c4710SBarry Smith 
10293d4c4710SBarry Smith    Notes:
10303d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
10313d4c4710SBarry Smith 
10323d4c4710SBarry Smith    Level: intermediate
10333d4c4710SBarry Smith 
10343d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
103558ebbce7SBarry Smith 
1036e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
10373d4c4710SBarry Smith @*/
10387087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
10393d4c4710SBarry Smith {
10403d4c4710SBarry Smith   PetscFunctionBegin;
10410700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10423d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
10433d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
10443d4c4710SBarry Smith   PetscFunctionReturn(0);
10453d4c4710SBarry Smith }
10463d4c4710SBarry Smith 
10473d4c4710SBarry Smith #undef __FUNCT__
10483d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
10493d4c4710SBarry Smith /*@
10503d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
10513d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
10523d4c4710SBarry Smith 
10533f9fe445SBarry Smith    Logically Collective on SNES
10543d4c4710SBarry Smith 
10553d4c4710SBarry Smith    Input Parameters:
10563d4c4710SBarry Smith +  snes     - SNES context
10573d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
10583d4c4710SBarry Smith 
10593d4c4710SBarry Smith    Level: intermediate
10603d4c4710SBarry Smith 
1061a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
10623d4c4710SBarry Smith 
10633d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
10643d4c4710SBarry Smith 
106558ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
10663d4c4710SBarry Smith @*/
10677087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
10683d4c4710SBarry Smith {
10693d4c4710SBarry Smith   PetscFunctionBegin;
10700700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1071c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
10723d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
10733d4c4710SBarry Smith   PetscFunctionReturn(0);
10743d4c4710SBarry Smith }
10753d4c4710SBarry Smith 
10763d4c4710SBarry Smith #undef __FUNCT__
10773d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
10783d4c4710SBarry Smith /*@
10793d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
10803d4c4710SBarry Smith      are allowed before SNES terminates
10813d4c4710SBarry Smith 
10823d4c4710SBarry Smith    Not Collective
10833d4c4710SBarry Smith 
10843d4c4710SBarry Smith    Input Parameter:
10853d4c4710SBarry Smith .  snes     - SNES context
10863d4c4710SBarry Smith 
10873d4c4710SBarry Smith    Output Parameter:
10883d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
10893d4c4710SBarry Smith 
10903d4c4710SBarry Smith    Level: intermediate
10913d4c4710SBarry Smith 
10923d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
10933d4c4710SBarry Smith 
10943d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
10953d4c4710SBarry Smith 
1096e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
10973d4c4710SBarry Smith @*/
10987087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
10993d4c4710SBarry Smith {
11003d4c4710SBarry Smith   PetscFunctionBegin;
11010700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11023d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
11033d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
11043d4c4710SBarry Smith   PetscFunctionReturn(0);
11053d4c4710SBarry Smith }
11063d4c4710SBarry Smith 
11073d4c4710SBarry Smith #undef __FUNCT__
1108b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
1109c96a6f78SLois Curfman McInnes /*@
1110b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1111c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1112c96a6f78SLois Curfman McInnes 
1113c7afd0dbSLois Curfman McInnes    Not Collective
1114c7afd0dbSLois Curfman McInnes 
1115c96a6f78SLois Curfman McInnes    Input Parameter:
1116c96a6f78SLois Curfman McInnes .  snes - SNES context
1117c96a6f78SLois Curfman McInnes 
1118c96a6f78SLois Curfman McInnes    Output Parameter:
1119c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1120c96a6f78SLois Curfman McInnes 
1121c96a6f78SLois Curfman McInnes    Notes:
1122c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1123c96a6f78SLois Curfman McInnes 
112436851e7fSLois Curfman McInnes    Level: intermediate
112536851e7fSLois Curfman McInnes 
1126c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
11272b668275SBarry Smith 
11288c7482ecSBarry Smith .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
1129c96a6f78SLois Curfman McInnes @*/
11307087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
1131c96a6f78SLois Curfman McInnes {
11323a40ed3dSBarry Smith   PetscFunctionBegin;
11330700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11344482741eSBarry Smith   PetscValidIntPointer(lits,2);
1135c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
11363a40ed3dSBarry Smith   PetscFunctionReturn(0);
1137c96a6f78SLois Curfman McInnes }
1138c96a6f78SLois Curfman McInnes 
11394a2ae208SSatish Balay #undef __FUNCT__
114094b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP"
114152baeb72SSatish Balay /*@
114294b7f48cSBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
11439b94acceSBarry Smith 
114494b7f48cSBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
1145c7afd0dbSLois Curfman McInnes 
11469b94acceSBarry Smith    Input Parameter:
11479b94acceSBarry Smith .  snes - the SNES context
11489b94acceSBarry Smith 
11499b94acceSBarry Smith    Output Parameter:
115094b7f48cSBarry Smith .  ksp - the KSP context
11519b94acceSBarry Smith 
11529b94acceSBarry Smith    Notes:
115394b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
11549b94acceSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
11552999313aSBarry Smith    PC contexts as well.
11569b94acceSBarry Smith 
115736851e7fSLois Curfman McInnes    Level: beginner
115836851e7fSLois Curfman McInnes 
115994b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
11609b94acceSBarry Smith 
11612999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
11629b94acceSBarry Smith @*/
11637087cfbeSBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
11649b94acceSBarry Smith {
11651cee3971SBarry Smith   PetscErrorCode ierr;
11661cee3971SBarry Smith 
11673a40ed3dSBarry Smith   PetscFunctionBegin;
11680700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11694482741eSBarry Smith   PetscValidPointer(ksp,2);
11701cee3971SBarry Smith 
11711cee3971SBarry Smith   if (!snes->ksp) {
11721cee3971SBarry Smith     ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr);
11731cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
11741cee3971SBarry Smith     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
11751cee3971SBarry Smith   }
117694b7f48cSBarry Smith   *ksp = snes->ksp;
11773a40ed3dSBarry Smith   PetscFunctionReturn(0);
11789b94acceSBarry Smith }
117982bf6240SBarry Smith 
11804a2ae208SSatish Balay #undef __FUNCT__
11812999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
11822999313aSBarry Smith /*@
11832999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
11842999313aSBarry Smith 
11852999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
11862999313aSBarry Smith 
11872999313aSBarry Smith    Input Parameters:
11882999313aSBarry Smith +  snes - the SNES context
11892999313aSBarry Smith -  ksp - the KSP context
11902999313aSBarry Smith 
11912999313aSBarry Smith    Notes:
11922999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
11932999313aSBarry Smith    so this routine is rarely needed.
11942999313aSBarry Smith 
11952999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
11962999313aSBarry Smith    decreased by one.
11972999313aSBarry Smith 
11982999313aSBarry Smith    Level: developer
11992999313aSBarry Smith 
12002999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
12012999313aSBarry Smith 
12022999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
12032999313aSBarry Smith @*/
12047087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
12052999313aSBarry Smith {
12062999313aSBarry Smith   PetscErrorCode ierr;
12072999313aSBarry Smith 
12082999313aSBarry Smith   PetscFunctionBegin;
12090700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12100700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
12112999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
12127dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1213906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
12142999313aSBarry Smith   snes->ksp = ksp;
12152999313aSBarry Smith   PetscFunctionReturn(0);
12162999313aSBarry Smith }
12172999313aSBarry Smith 
12187adad957SLisandro Dalcin #if 0
12192999313aSBarry Smith #undef __FUNCT__
12204a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc"
12216849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
1222e24b481bSBarry Smith {
1223e24b481bSBarry Smith   PetscFunctionBegin;
1224e24b481bSBarry Smith   PetscFunctionReturn(0);
1225e24b481bSBarry Smith }
12267adad957SLisandro Dalcin #endif
1227e24b481bSBarry Smith 
12289b94acceSBarry Smith /* -----------------------------------------------------------*/
12294a2ae208SSatish Balay #undef __FUNCT__
12304a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
123152baeb72SSatish Balay /*@
12329b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
12339b94acceSBarry Smith 
1234c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1235c7afd0dbSLois Curfman McInnes 
1236c7afd0dbSLois Curfman McInnes    Input Parameters:
1237906ed7ccSBarry Smith .  comm - MPI communicator
12389b94acceSBarry Smith 
12399b94acceSBarry Smith    Output Parameter:
12409b94acceSBarry Smith .  outsnes - the new SNES context
12419b94acceSBarry Smith 
1242c7afd0dbSLois Curfman McInnes    Options Database Keys:
1243c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1244c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1245c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1246c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1247c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1248c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1249c1f60f51SBarry Smith 
125036851e7fSLois Curfman McInnes    Level: beginner
125136851e7fSLois Curfman McInnes 
12529b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
12539b94acceSBarry Smith 
1254a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1255a8054027SBarry Smith 
12569b94acceSBarry Smith @*/
12577087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
12589b94acceSBarry Smith {
1259dfbe8321SBarry Smith   PetscErrorCode      ierr;
12609b94acceSBarry Smith   SNES                snes;
1261fa9f3622SBarry Smith   SNESKSPEW           *kctx;
126237fcc0dbSBarry Smith 
12633a40ed3dSBarry Smith   PetscFunctionBegin;
1264ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
12658ba1e511SMatthew Knepley   *outsnes = PETSC_NULL;
12668ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
12678ba1e511SMatthew Knepley   ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr);
12688ba1e511SMatthew Knepley #endif
12698ba1e511SMatthew Knepley 
12703194b578SJed Brown   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
12717adad957SLisandro Dalcin 
127285385478SLisandro Dalcin   snes->ops->converged    = SNESDefaultConverged;
12732c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
127488976e71SPeter Brune   snes->tolerancesset     = PETSC_FALSE;
12759b94acceSBarry Smith   snes->max_its           = 50;
12769750a799SBarry Smith   snes->max_funcs         = 10000;
12779b94acceSBarry Smith   snes->norm              = 0.0;
1278fdacfa88SPeter Brune   snes->normtype          = SNES_NORM_FUNCTION;
1279b4874afaSBarry Smith   snes->rtol              = 1.e-8;
1280b4874afaSBarry Smith   snes->ttol              = 0.0;
128170441072SBarry Smith   snes->abstol            = 1.e-50;
1282c60f73f4SPeter Brune   snes->stol              = 1.e-8;
12834b27c08aSLois Curfman McInnes   snes->deltatol          = 1.e-12;
12849b94acceSBarry Smith   snes->nfuncs            = 0;
128550ffb88aSMatthew Knepley   snes->numFailures       = 0;
128650ffb88aSMatthew Knepley   snes->maxFailures       = 1;
12877a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1288e35cf81dSBarry Smith   snes->lagjacobian       = 1;
1289a8054027SBarry Smith   snes->lagpreconditioner = 1;
1290639f9d9dSBarry Smith   snes->numbermonitors    = 0;
12919b94acceSBarry Smith   snes->data              = 0;
12924dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1293186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
12946f24a144SLois Curfman McInnes   snes->nwork             = 0;
129558c9b817SLisandro Dalcin   snes->work              = 0;
129658c9b817SLisandro Dalcin   snes->nvwork            = 0;
129758c9b817SLisandro Dalcin   snes->vwork             = 0;
1298758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1299758f92a0SBarry Smith   snes->conv_hist_max     = 0;
1300758f92a0SBarry Smith   snes->conv_hist         = PETSC_NULL;
1301758f92a0SBarry Smith   snes->conv_hist_its     = PETSC_NULL;
1302758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1303e4ed7901SPeter Brune   snes->vec_func_init_set = PETSC_FALSE;
1304e4ed7901SPeter Brune   snes->norm_init         = 0.;
1305e4ed7901SPeter Brune   snes->norm_init_set     = PETSC_FALSE;
1306184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
130789b92e6fSPeter Brune   snes->gssweeps          = 1;
13089b94acceSBarry Smith 
13093d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
13103d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
13113d4c4710SBarry Smith 
13129b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
131338f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr);
13149b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
13159b94acceSBarry Smith   kctx->version     = 2;
13169b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
13179b94acceSBarry Smith                              this was too large for some test cases */
131875567043SBarry Smith   kctx->rtol_last   = 0.0;
13199b94acceSBarry Smith   kctx->rtol_max    = .9;
13209b94acceSBarry Smith   kctx->gamma       = 1.0;
132162d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
132271f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
13239b94acceSBarry Smith   kctx->threshold   = .1;
132475567043SBarry Smith   kctx->lresid_last = 0.0;
132575567043SBarry Smith   kctx->norm_last   = 0.0;
13269b94acceSBarry Smith 
13279b94acceSBarry Smith   *outsnes = snes;
13283a40ed3dSBarry Smith   PetscFunctionReturn(0);
13299b94acceSBarry Smith }
13309b94acceSBarry Smith 
13314a2ae208SSatish Balay #undef __FUNCT__
13324a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
13339b94acceSBarry Smith /*@C
13349b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
13359b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
13369b94acceSBarry Smith    equations.
13379b94acceSBarry Smith 
13383f9fe445SBarry Smith    Logically Collective on SNES
1339fee21e36SBarry Smith 
1340c7afd0dbSLois Curfman McInnes    Input Parameters:
1341c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1342c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1343de044059SHong Zhang .  func - function evaluation routine
1344c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1345c7afd0dbSLois Curfman McInnes          function evaluation routine (may be PETSC_NULL)
13469b94acceSBarry Smith 
1347c7afd0dbSLois Curfman McInnes    Calling sequence of func:
13488d76a1e5SLois Curfman McInnes $    func (SNES snes,Vec x,Vec f,void *ctx);
1349c7afd0dbSLois Curfman McInnes 
1350c586c404SJed Brown +  snes - the SNES context
1351c586c404SJed Brown .  x - state at which to evaluate residual
1352c586c404SJed Brown .  f - vector to put residual
1353c7afd0dbSLois Curfman McInnes -  ctx - optional user-defined function context
13549b94acceSBarry Smith 
13559b94acceSBarry Smith    Notes:
13569b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
13579b94acceSBarry Smith $      f'(x) x = -f(x),
1358c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
13599b94acceSBarry Smith 
136036851e7fSLois Curfman McInnes    Level: beginner
136136851e7fSLois Curfman McInnes 
13629b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
13639b94acceSBarry Smith 
13648b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard()
13659b94acceSBarry Smith @*/
13667087cfbeSBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
13679b94acceSBarry Smith {
136885385478SLisandro Dalcin   PetscErrorCode ierr;
13696cab3a1bSJed Brown   DM             dm;
13706cab3a1bSJed Brown 
13713a40ed3dSBarry Smith   PetscFunctionBegin;
13720700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1373d2a683ecSLisandro Dalcin   if (r) {
1374d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1375d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
137685385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
13776bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
137885385478SLisandro Dalcin     snes->vec_func = r;
1379d2a683ecSLisandro Dalcin   }
13806cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
13816cab3a1bSJed Brown   ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr);
13823a40ed3dSBarry Smith   PetscFunctionReturn(0);
13839b94acceSBarry Smith }
13849b94acceSBarry Smith 
1385646217ecSPeter Brune 
1386646217ecSPeter Brune #undef __FUNCT__
1387e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction"
1388e4ed7901SPeter Brune /*@C
1389e4ed7901SPeter Brune    SNESSetInitialFunction - Sets the function vector to be used as the
1390e4ed7901SPeter Brune    function norm at the initialization of the method.  In some
1391e4ed7901SPeter Brune    instances, the user has precomputed the function before calling
1392e4ed7901SPeter Brune    SNESSolve.  This function allows one to avoid a redundant call
1393e4ed7901SPeter Brune    to SNESComputeFunction in that case.
1394e4ed7901SPeter Brune 
1395e4ed7901SPeter Brune    Logically Collective on SNES
1396e4ed7901SPeter Brune 
1397e4ed7901SPeter Brune    Input Parameters:
1398e4ed7901SPeter Brune +  snes - the SNES context
1399e4ed7901SPeter Brune -  f - vector to store function value
1400e4ed7901SPeter Brune 
1401e4ed7901SPeter Brune    Notes:
1402e4ed7901SPeter Brune    This should not be modified during the solution procedure.
1403e4ed7901SPeter Brune 
1404e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1405e4ed7901SPeter Brune 
1406e4ed7901SPeter Brune    Level: developer
1407e4ed7901SPeter Brune 
1408e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function
1409e4ed7901SPeter Brune 
1410e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm()
1411e4ed7901SPeter Brune @*/
1412e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunction(SNES snes, Vec f)
1413e4ed7901SPeter Brune {
1414e4ed7901SPeter Brune   PetscErrorCode ierr;
1415e4ed7901SPeter Brune   Vec            vec_func;
1416e4ed7901SPeter Brune 
1417e4ed7901SPeter Brune   PetscFunctionBegin;
1418e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1419e4ed7901SPeter Brune   PetscValidHeaderSpecific(f,VEC_CLASSID,2);
1420e4ed7901SPeter Brune   PetscCheckSameComm(snes,1,f,2);
1421e4ed7901SPeter Brune   ierr = SNESGetFunction(snes,&vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
1422e4ed7901SPeter Brune   ierr = VecCopy(f, vec_func);CHKERRQ(ierr);
1423217b9c2eSPeter Brune   snes->vec_func_init_set = PETSC_TRUE;
1424e4ed7901SPeter Brune   PetscFunctionReturn(0);
1425e4ed7901SPeter Brune }
1426e4ed7901SPeter Brune 
1427e4ed7901SPeter Brune 
1428e4ed7901SPeter Brune #undef __FUNCT__
1429e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunctionNorm"
1430e4ed7901SPeter Brune /*@C
1431e4ed7901SPeter Brune    SNESSetInitialFunctionNorm - Sets the function norm to be used as the function norm
1432e4ed7901SPeter Brune    at the initialization of the  method.  In some instances, the user has precomputed
1433e4ed7901SPeter Brune    the function and its norm before calling SNESSolve.  This function allows one to
1434e4ed7901SPeter Brune    avoid a redundant call to SNESComputeFunction() and VecNorm() in that case.
1435e4ed7901SPeter Brune 
1436e4ed7901SPeter Brune    Logically Collective on SNES
1437e4ed7901SPeter Brune 
1438e4ed7901SPeter Brune    Input Parameters:
1439e4ed7901SPeter Brune +  snes - the SNES context
1440e4ed7901SPeter Brune -  fnorm - the norm of F as set by SNESSetInitialFunction()
1441e4ed7901SPeter Brune 
1442e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1443e4ed7901SPeter Brune 
1444e4ed7901SPeter Brune    Level: developer
1445e4ed7901SPeter Brune 
1446e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function, norm
1447e4ed7901SPeter Brune 
1448e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction()
1449e4ed7901SPeter Brune @*/
1450e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm)
1451e4ed7901SPeter Brune {
1452e4ed7901SPeter Brune   PetscFunctionBegin;
1453e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1454e4ed7901SPeter Brune   snes->norm_init = fnorm;
1455e4ed7901SPeter Brune   snes->norm_init_set = PETSC_TRUE;
1456e4ed7901SPeter Brune   PetscFunctionReturn(0);
1457e4ed7901SPeter Brune }
1458e4ed7901SPeter Brune 
1459e4ed7901SPeter Brune #undef __FUNCT__
1460534ebe21SPeter Brune #define __FUNCT__ "SNESSetNormType"
1461534ebe21SPeter Brune /*@
1462534ebe21SPeter Brune    SNESSetNormType - Sets the SNESNormType used in covergence and monitoring
1463534ebe21SPeter Brune    of the SNES method.
1464534ebe21SPeter Brune 
1465534ebe21SPeter Brune    Logically Collective on SNES
1466534ebe21SPeter Brune 
1467534ebe21SPeter Brune    Input Parameters:
1468534ebe21SPeter Brune +  snes - the SNES context
1469534ebe21SPeter Brune -  normtype - the type of the norm used
1470534ebe21SPeter Brune 
1471534ebe21SPeter Brune    Notes:
1472534ebe21SPeter Brune    Only certain SNES methods support certain SNESNormTypes.  Most require evaluation
1473534ebe21SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
1474534ebe21SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1475534ebe21SPeter Brune    (SNESGS) and the like do not require the norm of the function to be computed, and therfore
1476534ebe21SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
1477534ebe21SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
1478534ebe21SPeter Brune    their solution.
1479534ebe21SPeter Brune 
1480534ebe21SPeter Brune    Level: developer
1481534ebe21SPeter Brune 
1482534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1483534ebe21SPeter Brune 
1484534ebe21SPeter Brune .seealso: SNESGetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType
1485534ebe21SPeter Brune @*/
1486534ebe21SPeter Brune PetscErrorCode  SNESSetNormType(SNES snes, SNESNormType normtype)
1487534ebe21SPeter Brune {
1488534ebe21SPeter Brune   PetscFunctionBegin;
1489534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1490534ebe21SPeter Brune   snes->normtype = normtype;
1491534ebe21SPeter Brune   PetscFunctionReturn(0);
1492534ebe21SPeter Brune }
1493534ebe21SPeter Brune 
1494534ebe21SPeter Brune 
1495534ebe21SPeter Brune #undef __FUNCT__
1496534ebe21SPeter Brune #define __FUNCT__ "SNESGetNormType"
1497534ebe21SPeter Brune /*@
1498534ebe21SPeter Brune    SNESGetNormType - Gets the SNESNormType used in covergence and monitoring
1499534ebe21SPeter Brune    of the SNES method.
1500534ebe21SPeter Brune 
1501534ebe21SPeter Brune    Logically Collective on SNES
1502534ebe21SPeter Brune 
1503534ebe21SPeter Brune    Input Parameters:
1504534ebe21SPeter Brune +  snes - the SNES context
1505534ebe21SPeter Brune -  normtype - the type of the norm used
1506534ebe21SPeter Brune 
1507534ebe21SPeter Brune    Level: advanced
1508534ebe21SPeter Brune 
1509534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1510534ebe21SPeter Brune 
1511534ebe21SPeter Brune .seealso: SNESSetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType
1512534ebe21SPeter Brune @*/
1513534ebe21SPeter Brune PetscErrorCode  SNESGetNormType(SNES snes, SNESNormType *normtype)
1514534ebe21SPeter Brune {
1515534ebe21SPeter Brune   PetscFunctionBegin;
1516534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1517534ebe21SPeter Brune   *normtype = snes->normtype;
1518534ebe21SPeter Brune   PetscFunctionReturn(0);
1519534ebe21SPeter Brune }
1520534ebe21SPeter Brune 
1521534ebe21SPeter Brune #undef __FUNCT__
1522646217ecSPeter Brune #define __FUNCT__ "SNESSetGS"
1523c79ef259SPeter Brune /*@C
1524c79ef259SPeter Brune    SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for
1525c79ef259SPeter Brune    use with composed nonlinear solvers.
1526c79ef259SPeter Brune 
1527c79ef259SPeter Brune    Input Parameters:
1528c79ef259SPeter Brune +  snes   - the SNES context
1529c79ef259SPeter Brune .  gsfunc - function evaluation routine
1530c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
1531c79ef259SPeter Brune             smoother evaluation routine (may be PETSC_NULL)
1532c79ef259SPeter Brune 
1533c79ef259SPeter Brune    Calling sequence of func:
1534c79ef259SPeter Brune $    func (SNES snes,Vec x,Vec b,void *ctx);
1535c79ef259SPeter Brune 
1536c79ef259SPeter Brune +  X   - solution vector
1537c79ef259SPeter Brune .  B   - RHS vector
1538d28543b3SPeter Brune -  ctx - optional user-defined Gauss-Seidel context
1539c79ef259SPeter Brune 
1540c79ef259SPeter Brune    Notes:
1541c79ef259SPeter Brune    The GS routines are used by the composed nonlinear solver to generate
1542c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
1543c79ef259SPeter Brune 
1544d28543b3SPeter Brune    Level: intermediate
1545c79ef259SPeter Brune 
1546d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel
1547c79ef259SPeter Brune 
1548c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS()
1549c79ef259SPeter Brune @*/
15506cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx)
15516cab3a1bSJed Brown {
15526cab3a1bSJed Brown   PetscErrorCode ierr;
15536cab3a1bSJed Brown   DM dm;
15546cab3a1bSJed Brown 
1555646217ecSPeter Brune   PetscFunctionBegin;
15566cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15576cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
15586cab3a1bSJed Brown   ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr);
1559646217ecSPeter Brune   PetscFunctionReturn(0);
1560646217ecSPeter Brune }
1561646217ecSPeter Brune 
1562d25893d9SBarry Smith #undef __FUNCT__
156389b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps"
156489b92e6fSPeter Brune /*@
156589b92e6fSPeter Brune    SNESSetGSSweeps - Sets the number of sweeps of GS to use.
156689b92e6fSPeter Brune 
156789b92e6fSPeter Brune    Input Parameters:
156889b92e6fSPeter Brune +  snes   - the SNES context
156989b92e6fSPeter Brune -  sweeps  - the number of sweeps of GS to perform.
157089b92e6fSPeter Brune 
157189b92e6fSPeter Brune    Level: intermediate
157289b92e6fSPeter Brune 
157389b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
157489b92e6fSPeter Brune 
157589b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps()
157689b92e6fSPeter Brune @*/
157789b92e6fSPeter Brune 
157889b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) {
157989b92e6fSPeter Brune   PetscFunctionBegin;
158089b92e6fSPeter Brune   snes->gssweeps = sweeps;
158189b92e6fSPeter Brune   PetscFunctionReturn(0);
158289b92e6fSPeter Brune }
158389b92e6fSPeter Brune 
158489b92e6fSPeter Brune 
158589b92e6fSPeter Brune #undef __FUNCT__
158689b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps"
158789b92e6fSPeter Brune /*@
158889b92e6fSPeter Brune    SNESGetGSSweeps - Gets the number of sweeps GS will use.
158989b92e6fSPeter Brune 
159089b92e6fSPeter Brune    Input Parameters:
159189b92e6fSPeter Brune .  snes   - the SNES context
159289b92e6fSPeter Brune 
159389b92e6fSPeter Brune    Output Parameters:
159489b92e6fSPeter Brune .  sweeps  - the number of sweeps of GS to perform.
159589b92e6fSPeter Brune 
159689b92e6fSPeter Brune    Level: intermediate
159789b92e6fSPeter Brune 
159889b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
159989b92e6fSPeter Brune 
160089b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps()
160189b92e6fSPeter Brune @*/
160289b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) {
160389b92e6fSPeter Brune   PetscFunctionBegin;
160489b92e6fSPeter Brune   *sweeps = snes->gssweeps;
160589b92e6fSPeter Brune   PetscFunctionReturn(0);
160689b92e6fSPeter Brune }
160789b92e6fSPeter Brune 
160889b92e6fSPeter Brune #undef __FUNCT__
16098b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction"
16108b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
16118b0a5094SBarry Smith {
16128b0a5094SBarry Smith   PetscErrorCode ierr;
16136cab3a1bSJed Brown   void *functx,*jacctx;
16146cab3a1bSJed Brown 
16158b0a5094SBarry Smith   PetscFunctionBegin;
16166cab3a1bSJed Brown   ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
16176cab3a1bSJed Brown   ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr);
16188b0a5094SBarry Smith   /*  A(x)*x - b(x) */
16196cab3a1bSJed Brown   ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr);
16206cab3a1bSJed Brown   ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr);
16218b0a5094SBarry Smith   ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
16228b0a5094SBarry Smith   ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
16238b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
16248b0a5094SBarry Smith   ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr);
16258b0a5094SBarry Smith   PetscFunctionReturn(0);
16268b0a5094SBarry Smith }
16278b0a5094SBarry Smith 
16288b0a5094SBarry Smith #undef __FUNCT__
16298b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian"
16308b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
16318b0a5094SBarry Smith {
16328b0a5094SBarry Smith   PetscFunctionBegin;
16338b0a5094SBarry Smith   *flag = snes->matstruct;
16348b0a5094SBarry Smith   PetscFunctionReturn(0);
16358b0a5094SBarry Smith }
16368b0a5094SBarry Smith 
16378b0a5094SBarry Smith #undef __FUNCT__
16388b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard"
16398b0a5094SBarry Smith /*@C
16400d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
16418b0a5094SBarry Smith 
16428b0a5094SBarry Smith    Logically Collective on SNES
16438b0a5094SBarry Smith 
16448b0a5094SBarry Smith    Input Parameters:
16458b0a5094SBarry Smith +  snes - the SNES context
16468b0a5094SBarry Smith .  r - vector to store function value
16478b0a5094SBarry Smith .  func - function evaluation routine
16488b0a5094SBarry 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)
16498b0a5094SBarry Smith .  mat - matrix to store A
16508b0a5094SBarry Smith .  mfunc  - function to compute matrix value
16518b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
16528b0a5094SBarry Smith          function evaluation routine (may be PETSC_NULL)
16538b0a5094SBarry Smith 
16548b0a5094SBarry Smith    Calling sequence of func:
16558b0a5094SBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
16568b0a5094SBarry Smith 
16578b0a5094SBarry Smith +  f - function vector
16588b0a5094SBarry Smith -  ctx - optional user-defined function context
16598b0a5094SBarry Smith 
16608b0a5094SBarry Smith    Calling sequence of mfunc:
16618b0a5094SBarry Smith $     mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx);
16628b0a5094SBarry Smith 
16638b0a5094SBarry Smith +  x - input vector
16648b0a5094SBarry 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(),
16658b0a5094SBarry Smith           normally just pass mat in this location
16668b0a5094SBarry Smith .  mat - form A(x) matrix
16678b0a5094SBarry Smith .  flag - flag indicating information about the preconditioner matrix
16688b0a5094SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
16698b0a5094SBarry Smith -  ctx - [optional] user-defined Jacobian context
16708b0a5094SBarry Smith 
16718b0a5094SBarry Smith    Notes:
16728b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
16738b0a5094SBarry Smith 
16748b0a5094SBarry 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}
16758b0a5094SBarry 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.
16768b0a5094SBarry Smith 
16778b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
16788b0a5094SBarry Smith 
16790d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
16800d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
16818b0a5094SBarry Smith 
16828b0a5094SBarry 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
16838b0a5094SBarry 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
16848b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
16858b0a5094SBarry Smith 
16868b0a5094SBarry Smith    Level: beginner
16878b0a5094SBarry Smith 
16888b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function
16898b0a5094SBarry Smith 
16900d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard()
16918b0a5094SBarry Smith @*/
16928b0a5094SBarry 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)
16938b0a5094SBarry Smith {
16948b0a5094SBarry Smith   PetscErrorCode ierr;
16958b0a5094SBarry Smith   PetscFunctionBegin;
16968b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
16978b0a5094SBarry Smith   snes->ops->computepfunction = func;
16988b0a5094SBarry Smith   snes->ops->computepjacobian = mfunc;
16998b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
17008b0a5094SBarry Smith   ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
17018b0a5094SBarry Smith   PetscFunctionReturn(0);
17028b0a5094SBarry Smith }
17038b0a5094SBarry Smith 
17048b0a5094SBarry Smith #undef __FUNCT__
1705d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess"
1706d25893d9SBarry Smith /*@C
1707d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1708d25893d9SBarry Smith 
1709d25893d9SBarry Smith    Logically Collective on SNES
1710d25893d9SBarry Smith 
1711d25893d9SBarry Smith    Input Parameters:
1712d25893d9SBarry Smith +  snes - the SNES context
1713d25893d9SBarry Smith .  func - function evaluation routine
1714d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
1715d25893d9SBarry Smith          function evaluation routine (may be PETSC_NULL)
1716d25893d9SBarry Smith 
1717d25893d9SBarry Smith    Calling sequence of func:
1718d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
1719d25893d9SBarry Smith 
1720d25893d9SBarry Smith .  f - function vector
1721d25893d9SBarry Smith -  ctx - optional user-defined function context
1722d25893d9SBarry Smith 
1723d25893d9SBarry Smith    Level: intermediate
1724d25893d9SBarry Smith 
1725d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
1726d25893d9SBarry Smith 
1727d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1728d25893d9SBarry Smith @*/
1729d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1730d25893d9SBarry Smith {
1731d25893d9SBarry Smith   PetscFunctionBegin;
1732d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1733d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
1734d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
1735d25893d9SBarry Smith   PetscFunctionReturn(0);
1736d25893d9SBarry Smith }
1737d25893d9SBarry Smith 
17383ab0aad5SBarry Smith /* --------------------------------------------------------------- */
17393ab0aad5SBarry Smith #undef __FUNCT__
17401096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
17411096aae1SMatthew Knepley /*@C
17421096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
17431096aae1SMatthew Knepley    it assumes a zero right hand side.
17441096aae1SMatthew Knepley 
17453f9fe445SBarry Smith    Logically Collective on SNES
17461096aae1SMatthew Knepley 
17471096aae1SMatthew Knepley    Input Parameter:
17481096aae1SMatthew Knepley .  snes - the SNES context
17491096aae1SMatthew Knepley 
17501096aae1SMatthew Knepley    Output Parameter:
1751bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
17521096aae1SMatthew Knepley 
17531096aae1SMatthew Knepley    Level: intermediate
17541096aae1SMatthew Knepley 
17551096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
17561096aae1SMatthew Knepley 
175785385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
17581096aae1SMatthew Knepley @*/
17597087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
17601096aae1SMatthew Knepley {
17611096aae1SMatthew Knepley   PetscFunctionBegin;
17620700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
17631096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
176485385478SLisandro Dalcin   *rhs = snes->vec_rhs;
17651096aae1SMatthew Knepley   PetscFunctionReturn(0);
17661096aae1SMatthew Knepley }
17671096aae1SMatthew Knepley 
17681096aae1SMatthew Knepley #undef __FUNCT__
17694a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
17709b94acceSBarry Smith /*@
177136851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
17729b94acceSBarry Smith                          SNESSetFunction().
17739b94acceSBarry Smith 
1774c7afd0dbSLois Curfman McInnes    Collective on SNES
1775c7afd0dbSLois Curfman McInnes 
17769b94acceSBarry Smith    Input Parameters:
1777c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1778c7afd0dbSLois Curfman McInnes -  x - input vector
17799b94acceSBarry Smith 
17809b94acceSBarry Smith    Output Parameter:
17813638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
17829b94acceSBarry Smith 
17831bffabb2SLois Curfman McInnes    Notes:
178436851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
178536851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
178636851e7fSLois Curfman McInnes    themselves.
178736851e7fSLois Curfman McInnes 
178836851e7fSLois Curfman McInnes    Level: developer
178936851e7fSLois Curfman McInnes 
17909b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
17919b94acceSBarry Smith 
1792a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
17939b94acceSBarry Smith @*/
17947087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
17959b94acceSBarry Smith {
1796dfbe8321SBarry Smith   PetscErrorCode ierr;
17976cab3a1bSJed Brown   DM             dm;
17986cab3a1bSJed Brown   SNESDM         sdm;
17999b94acceSBarry Smith 
18003a40ed3dSBarry Smith   PetscFunctionBegin;
18010700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
18020700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
18030700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
1804c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
1805c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
18064ec14c9cSBarry Smith   VecValidValues(x,2,PETSC_TRUE);
1807184914b5SBarry Smith 
18086cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
18096cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
1810d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
18116cab3a1bSJed Brown   if (sdm->computefunction) {
1812d64ed03dSBarry Smith     PetscStackPush("SNES user function");
18136cab3a1bSJed Brown     ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
1814d64ed03dSBarry Smith     PetscStackPop;
181573250ac0SBarry Smith   } else if (snes->dm) {
1816644e2e5bSBarry Smith     ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr);
1817c90fad12SPeter Brune   } else if (snes->vec_rhs) {
1818c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
1819644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
182085385478SLisandro Dalcin   if (snes->vec_rhs) {
182185385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
18223ab0aad5SBarry Smith   }
1823ae3c334cSLois Curfman McInnes   snes->nfuncs++;
1824d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
18254ec14c9cSBarry Smith   VecValidValues(y,3,PETSC_FALSE);
18263a40ed3dSBarry Smith   PetscFunctionReturn(0);
18279b94acceSBarry Smith }
18289b94acceSBarry Smith 
18294a2ae208SSatish Balay #undef __FUNCT__
1830646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS"
1831c79ef259SPeter Brune /*@
1832c79ef259SPeter Brune    SNESComputeGS - Calls the Gauss-Seidel function that has been set with
1833c79ef259SPeter Brune                    SNESSetGS().
1834c79ef259SPeter Brune 
1835c79ef259SPeter Brune    Collective on SNES
1836c79ef259SPeter Brune 
1837c79ef259SPeter Brune    Input Parameters:
1838c79ef259SPeter Brune +  snes - the SNES context
1839c79ef259SPeter Brune .  x - input vector
1840c79ef259SPeter Brune -  b - rhs vector
1841c79ef259SPeter Brune 
1842c79ef259SPeter Brune    Output Parameter:
1843c79ef259SPeter Brune .  x - new solution vector
1844c79ef259SPeter Brune 
1845c79ef259SPeter Brune    Notes:
1846c79ef259SPeter Brune    SNESComputeGS() is typically used within composed nonlinear solver
1847c79ef259SPeter Brune    implementations, so most users would not generally call this routine
1848c79ef259SPeter Brune    themselves.
1849c79ef259SPeter Brune 
1850c79ef259SPeter Brune    Level: developer
1851c79ef259SPeter Brune 
1852c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function
1853c79ef259SPeter Brune 
1854c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction()
1855c79ef259SPeter Brune @*/
1856646217ecSPeter Brune PetscErrorCode  SNESComputeGS(SNES snes,Vec b,Vec x)
1857646217ecSPeter Brune {
1858646217ecSPeter Brune   PetscErrorCode ierr;
185989b92e6fSPeter Brune   PetscInt i;
18606cab3a1bSJed Brown   DM dm;
18616cab3a1bSJed Brown   SNESDM sdm;
1862646217ecSPeter Brune 
1863646217ecSPeter Brune   PetscFunctionBegin;
1864646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1865646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
1866646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
1867646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
1868646217ecSPeter Brune   if(b) PetscCheckSameComm(snes,1,b,3);
18694ec14c9cSBarry Smith   if (b) VecValidValues(b,2,PETSC_TRUE);
1870701cf23dSPeter Brune   ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
18716cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
18726cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
18736cab3a1bSJed Brown   if (sdm->computegs) {
187489b92e6fSPeter Brune     for (i = 0; i < snes->gssweeps; i++) {
1875646217ecSPeter Brune       PetscStackPush("SNES user GS");
18766cab3a1bSJed Brown       ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
1877646217ecSPeter Brune       PetscStackPop;
187889b92e6fSPeter Brune     }
1879646217ecSPeter Brune   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve().");
1880701cf23dSPeter Brune   ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
18814ec14c9cSBarry Smith   VecValidValues(x,3,PETSC_FALSE);
1882646217ecSPeter Brune   PetscFunctionReturn(0);
1883646217ecSPeter Brune }
1884646217ecSPeter Brune 
1885646217ecSPeter Brune 
1886646217ecSPeter Brune #undef __FUNCT__
18874a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
188862fef451SLois Curfman McInnes /*@
188962fef451SLois Curfman McInnes    SNESComputeJacobian - Computes the Jacobian matrix that has been
189062fef451SLois Curfman McInnes    set with SNESSetJacobian().
189162fef451SLois Curfman McInnes 
1892c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
1893c7afd0dbSLois Curfman McInnes 
189462fef451SLois Curfman McInnes    Input Parameters:
1895c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1896c7afd0dbSLois Curfman McInnes -  x - input vector
189762fef451SLois Curfman McInnes 
189862fef451SLois Curfman McInnes    Output Parameters:
1899c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
190062fef451SLois Curfman McInnes .  B - optional preconditioning matrix
19012b668275SBarry Smith -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1902fee21e36SBarry Smith 
1903e35cf81dSBarry Smith   Options Database Keys:
1904e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
1905693365a8SJed Brown .    -snes_lag_jacobian <lag>
1906693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
1907693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
1908693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
19094c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
1910c01495d3SJed Brown .    -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference
1911c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
1912c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
1913c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
1914c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
19154c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
1916c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
1917c01495d3SJed Brown 
1918e35cf81dSBarry Smith 
191962fef451SLois Curfman McInnes    Notes:
192062fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
192162fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
192262fef451SLois Curfman McInnes 
192394b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the
1924dc5a77f8SLois Curfman McInnes    flag parameter.
192562fef451SLois Curfman McInnes 
192636851e7fSLois Curfman McInnes    Level: developer
192736851e7fSLois Curfman McInnes 
192862fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
192962fef451SLois Curfman McInnes 
1930e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
193162fef451SLois Curfman McInnes @*/
19327087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
19339b94acceSBarry Smith {
1934dfbe8321SBarry Smith   PetscErrorCode ierr;
1935ace3abfcSBarry Smith   PetscBool      flag;
19366cab3a1bSJed Brown   DM             dm;
19376cab3a1bSJed Brown   SNESDM         sdm;
19383a40ed3dSBarry Smith 
19393a40ed3dSBarry Smith   PetscFunctionBegin;
19400700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
19410700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
19424482741eSBarry Smith   PetscValidPointer(flg,5);
1943c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
19444ec14c9cSBarry Smith   VecValidValues(X,2,PETSC_TRUE);
19456cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
19466cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
19476cab3a1bSJed Brown   if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
1948ebd3b9afSBarry Smith 
1949ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
1950ebd3b9afSBarry Smith 
1951fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
1952fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
1953fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
1954fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
1955e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1956e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
1957251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1958ebd3b9afSBarry Smith     if (flag) {
1959ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1960ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1961ebd3b9afSBarry Smith     }
1962e35cf81dSBarry Smith     PetscFunctionReturn(0);
1963e35cf81dSBarry Smith   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
1964e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1965e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
1966251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1967ebd3b9afSBarry Smith     if (flag) {
1968ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1969ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1970ebd3b9afSBarry Smith     }
1971e35cf81dSBarry Smith     PetscFunctionReturn(0);
1972e35cf81dSBarry Smith   }
1973e35cf81dSBarry Smith 
1974c4fc05e7SBarry Smith   *flg = DIFFERENT_NONZERO_PATTERN;
1975e35cf81dSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1976d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
19776cab3a1bSJed Brown   ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr);
1978d64ed03dSBarry Smith   PetscStackPop;
1979d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1980a8054027SBarry Smith 
19813b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
19823b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
19833b4f5425SBarry Smith     snes->lagpreconditioner = -1;
19843b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
1985a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1986a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
1987a8054027SBarry Smith   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
1988a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1989a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
1990a8054027SBarry Smith   }
1991a8054027SBarry Smith 
19926d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
19930700a824SBarry Smith   /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
19940700a824SBarry Smith     PetscValidHeaderSpecific(*B,MAT_CLASSID,4);   */
1995693365a8SJed Brown   {
1996693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
1997693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr);
1998693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
1999693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
2000693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr);
2001693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
2002693365a8SJed Brown       Mat Bexp_mine = PETSC_NULL,Bexp,FDexp;
2003693365a8SJed Brown       MatStructure mstruct;
2004693365a8SJed Brown       PetscViewer vdraw,vstdout;
20056b3a5b13SJed Brown       PetscBool flg;
2006693365a8SJed Brown       if (flag_operator) {
2007693365a8SJed Brown         ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr);
2008693365a8SJed Brown         Bexp = Bexp_mine;
2009693365a8SJed Brown       } else {
2010693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
2011251f4c67SDmitry Karpeev         ierr = PetscObjectTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
2012693365a8SJed Brown         if (flg) Bexp = *B;
2013693365a8SJed Brown         else {
2014693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
2015693365a8SJed Brown           ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr);
2016693365a8SJed Brown           Bexp = Bexp_mine;
2017693365a8SJed Brown         }
2018693365a8SJed Brown       }
2019693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
2020693365a8SJed Brown       ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr);
2021693365a8SJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
2022693365a8SJed Brown       if (flag_draw || flag_contour) {
2023693365a8SJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
2024693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
2025693365a8SJed Brown       } else vdraw = PETSC_NULL;
2026693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr);
2027693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
2028693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
2029693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
2030693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2031693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
2032693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2033693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
2034693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2035693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
2036693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
2037693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
2038693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
2039693365a8SJed Brown       }
2040693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
2041693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
2042693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
2043693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
2044693365a8SJed Brown     }
2045693365a8SJed Brown   }
20464c30e9fbSJed Brown   {
20476719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
20486719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
20494c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr);
20506719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr);
20514c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
20524c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
20536719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr);
20546719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr);
20556719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr);
20566719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
20574c30e9fbSJed Brown       Mat Bfd;
20584c30e9fbSJed Brown       MatStructure mstruct;
20594c30e9fbSJed Brown       PetscViewer vdraw,vstdout;
20604c30e9fbSJed Brown       ISColoring iscoloring;
20614c30e9fbSJed Brown       MatFDColoring matfdcoloring;
20624c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
20634c30e9fbSJed Brown       void *funcctx;
20646719d8e4SJed Brown       PetscReal norm1,norm2,normmax;
20654c30e9fbSJed Brown 
20664c30e9fbSJed Brown       ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
20674c30e9fbSJed Brown       ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
20684c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
20694c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
20704c30e9fbSJed Brown 
20714c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
20724c30e9fbSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr);
20734c30e9fbSJed Brown       ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr);
20744c30e9fbSJed Brown       ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
20754c30e9fbSJed Brown       ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
20764c30e9fbSJed Brown       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
20774c30e9fbSJed Brown       ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr);
20784c30e9fbSJed Brown       ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
20794c30e9fbSJed Brown 
20804c30e9fbSJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
20814c30e9fbSJed Brown       if (flag_draw || flag_contour) {
20824c30e9fbSJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
20834c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
20844c30e9fbSJed Brown       } else vdraw = PETSC_NULL;
20854c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
20866719d8e4SJed Brown       if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);}
20874c30e9fbSJed Brown       if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);}
20884c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
20896719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
20904c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
20914c30e9fbSJed Brown       ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
20924c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
20936719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
20944c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
20956719d8e4SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr);
20966719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
20974c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
20984c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
20994c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
21004c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
21014c30e9fbSJed Brown       }
21024c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
21036719d8e4SJed Brown 
21046719d8e4SJed Brown       if (flag_threshold) {
21056719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
21066719d8e4SJed Brown         ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr);
21076719d8e4SJed Brown         ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr);
21086719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
21096719d8e4SJed Brown           const PetscScalar *ba,*ca;
21106719d8e4SJed Brown           const PetscInt *bj,*cj;
21116719d8e4SJed Brown           PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
21126719d8e4SJed Brown           PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0;
21136719d8e4SJed Brown           ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
21146719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
21156719d8e4SJed Brown           if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
21166719d8e4SJed Brown           for (j=0; j<bn; j++) {
21176719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
21186719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
21196719d8e4SJed Brown               maxentrycol = bj[j];
21206719d8e4SJed Brown               maxentry = PetscRealPart(ba[j]);
21216719d8e4SJed Brown             }
21226719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
21236719d8e4SJed Brown               maxdiffcol = bj[j];
21246719d8e4SJed Brown               maxdiff = PetscRealPart(ca[j]);
21256719d8e4SJed Brown             }
21266719d8e4SJed Brown             if (rdiff > maxrdiff) {
21276719d8e4SJed Brown               maxrdiffcol = bj[j];
21286719d8e4SJed Brown               maxrdiff = rdiff;
21296719d8e4SJed Brown             }
21306719d8e4SJed Brown           }
21316719d8e4SJed Brown           if (maxrdiff > 1) {
21326719d8e4SJed 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);
21336719d8e4SJed Brown             for (j=0; j<bn; j++) {
21346719d8e4SJed Brown               PetscReal rdiff;
21356719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
21366719d8e4SJed Brown               if (rdiff > 1) {
21376719d8e4SJed Brown                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr);
21386719d8e4SJed Brown               }
21396719d8e4SJed Brown             }
21406719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
21416719d8e4SJed Brown           }
21426719d8e4SJed Brown           ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
21436719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
21446719d8e4SJed Brown         }
21456719d8e4SJed Brown       }
21464c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
21474c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
21484c30e9fbSJed Brown     }
21494c30e9fbSJed Brown   }
21503a40ed3dSBarry Smith   PetscFunctionReturn(0);
21519b94acceSBarry Smith }
21529b94acceSBarry Smith 
21534a2ae208SSatish Balay #undef __FUNCT__
21544a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
21559b94acceSBarry Smith /*@C
21569b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2157044dda88SLois Curfman McInnes    location to store the matrix.
21589b94acceSBarry Smith 
21593f9fe445SBarry Smith    Logically Collective on SNES and Mat
2160c7afd0dbSLois Curfman McInnes 
21619b94acceSBarry Smith    Input Parameters:
2162c7afd0dbSLois Curfman McInnes +  snes - the SNES context
21639b94acceSBarry Smith .  A - Jacobian matrix
21649b94acceSBarry Smith .  B - preconditioner matrix (usually same as the Jacobian)
2165efd51863SBarry Smith .  func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value)
2166c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
2167efd51863SBarry Smith          Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value)
21689b94acceSBarry Smith 
21699b94acceSBarry Smith    Calling sequence of func:
21708d76a1e5SLois Curfman McInnes $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
21719b94acceSBarry Smith 
2172c7afd0dbSLois Curfman McInnes +  x - input vector
21739b94acceSBarry Smith .  A - Jacobian matrix
21749b94acceSBarry Smith .  B - preconditioner matrix, usually the same as A
2175ac21db08SLois Curfman McInnes .  flag - flag indicating information about the preconditioner matrix
21762b668275SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
2177c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined Jacobian context
21789b94acceSBarry Smith 
21799b94acceSBarry Smith    Notes:
218094b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the flag
21812cd2dfdcSLois Curfman McInnes    output parameter in the routine func().  Be sure to read this information!
2182ac21db08SLois Curfman McInnes 
2183ac21db08SLois Curfman McInnes    The routine func() takes Mat * as the matrix arguments rather than Mat.
21849b94acceSBarry Smith    This allows the Jacobian evaluation routine to replace A and/or B with a
21859b94acceSBarry Smith    completely new new matrix structure (not just different matrix elements)
21869b94acceSBarry Smith    when appropriate, for instance, if the nonzero structure is changing
21879b94acceSBarry Smith    throughout the global iterations.
21889b94acceSBarry Smith 
218916913363SBarry Smith    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
219016913363SBarry Smith    each matrix.
219116913363SBarry Smith 
2192a8a26c1eSJed Brown    If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument
2193a8a26c1eSJed Brown    must be a MatFDColoring.
2194a8a26c1eSJed Brown 
2195c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2196c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2197c3cc8fd1SJed Brown 
219836851e7fSLois Curfman McInnes    Level: beginner
219936851e7fSLois Curfman McInnes 
22009b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
22019b94acceSBarry Smith 
22023ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
22039b94acceSBarry Smith @*/
22047087cfbeSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
22059b94acceSBarry Smith {
2206dfbe8321SBarry Smith   PetscErrorCode ierr;
22076cab3a1bSJed Brown   DM             dm;
22083a7fca6bSBarry Smith 
22093a40ed3dSBarry Smith   PetscFunctionBegin;
22100700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
22110700a824SBarry Smith   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
22120700a824SBarry Smith   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
2213c9780b6fSBarry Smith   if (A) PetscCheckSameComm(snes,1,A,2);
221406975374SJed Brown   if (B) PetscCheckSameComm(snes,1,B,3);
22156cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
22166cab3a1bSJed Brown   ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr);
22173a7fca6bSBarry Smith   if (A) {
22187dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
22196bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
22209b94acceSBarry Smith     snes->jacobian = A;
22213a7fca6bSBarry Smith   }
22223a7fca6bSBarry Smith   if (B) {
22237dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
22246bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
22259b94acceSBarry Smith     snes->jacobian_pre = B;
22263a7fca6bSBarry Smith   }
22273a40ed3dSBarry Smith   PetscFunctionReturn(0);
22289b94acceSBarry Smith }
222962fef451SLois Curfman McInnes 
22304a2ae208SSatish Balay #undef __FUNCT__
22314a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
2232c2aafc4cSSatish Balay /*@C
2233b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2234b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2235b4fd4287SBarry Smith 
2236c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2237c7afd0dbSLois Curfman McInnes 
2238b4fd4287SBarry Smith    Input Parameter:
2239b4fd4287SBarry Smith .  snes - the nonlinear solver context
2240b4fd4287SBarry Smith 
2241b4fd4287SBarry Smith    Output Parameters:
2242c7afd0dbSLois Curfman McInnes +  A - location to stash Jacobian matrix (or PETSC_NULL)
2243b4fd4287SBarry Smith .  B - location to stash preconditioner matrix (or PETSC_NULL)
224470e92668SMatthew Knepley .  func - location to put Jacobian function (or PETSC_NULL)
224570e92668SMatthew Knepley -  ctx - location to stash Jacobian ctx (or PETSC_NULL)
2246fee21e36SBarry Smith 
224736851e7fSLois Curfman McInnes    Level: advanced
224836851e7fSLois Curfman McInnes 
2249b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian()
2250b4fd4287SBarry Smith @*/
22517087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
2252b4fd4287SBarry Smith {
22536cab3a1bSJed Brown   PetscErrorCode ierr;
22546cab3a1bSJed Brown   DM             dm;
22556cab3a1bSJed Brown   SNESDM         sdm;
22566cab3a1bSJed Brown 
22573a40ed3dSBarry Smith   PetscFunctionBegin;
22580700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2259b4fd4287SBarry Smith   if (A)    *A    = snes->jacobian;
2260b4fd4287SBarry Smith   if (B)    *B    = snes->jacobian_pre;
22616cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
22626cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
22636cab3a1bSJed Brown   if (func) *func = sdm->computejacobian;
22646cab3a1bSJed Brown   if (ctx)  *ctx  = sdm->jacobianctx;
22653a40ed3dSBarry Smith   PetscFunctionReturn(0);
2266b4fd4287SBarry Smith }
2267b4fd4287SBarry Smith 
22689b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
22699b94acceSBarry Smith 
22704a2ae208SSatish Balay #undef __FUNCT__
22714a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
22729b94acceSBarry Smith /*@
22739b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
2274272ac6f2SLois Curfman McInnes    of a nonlinear solver.
22759b94acceSBarry Smith 
2276fee21e36SBarry Smith    Collective on SNES
2277fee21e36SBarry Smith 
2278c7afd0dbSLois Curfman McInnes    Input Parameters:
227970e92668SMatthew Knepley .  snes - the SNES context
2280c7afd0dbSLois Curfman McInnes 
2281272ac6f2SLois Curfman McInnes    Notes:
2282272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
2283272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
2284272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
2285272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
2286272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
2287272ac6f2SLois Curfman McInnes 
228836851e7fSLois Curfman McInnes    Level: advanced
228936851e7fSLois Curfman McInnes 
22909b94acceSBarry Smith .keywords: SNES, nonlinear, setup
22919b94acceSBarry Smith 
22929b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
22939b94acceSBarry Smith @*/
22947087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
22959b94acceSBarry Smith {
2296dfbe8321SBarry Smith   PetscErrorCode ierr;
22976cab3a1bSJed Brown   DM             dm;
22986cab3a1bSJed Brown   SNESDM         sdm;
22996e2a1849SPeter Brune   SNESLineSearch              linesearch;
23006e2a1849SPeter Brune   SNESLineSearch              pclinesearch;
23016e2a1849SPeter Brune   void                        *lsprectx,*lspostctx;
23026e2a1849SPeter Brune   SNESLineSearchPreCheckFunc  lsprefunc;
23036e2a1849SPeter Brune   SNESLineSearchPostCheckFunc lspostfunc;
23046e2a1849SPeter Brune   PetscErrorCode              (*func)(SNES,Vec,Vec,void*);
23056e2a1849SPeter Brune   Vec                         f,fpc;
23066e2a1849SPeter Brune   void                        *funcctx;
23076e2a1849SPeter Brune   PetscErrorCode              (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*);
23086e2a1849SPeter Brune   void                        *jacctx;
23096e2a1849SPeter Brune   Mat                         A,B;
23103a40ed3dSBarry Smith 
23113a40ed3dSBarry Smith   PetscFunctionBegin;
23120700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
23134dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
23149b94acceSBarry Smith 
23157adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
231685385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
231785385478SLisandro Dalcin   }
231885385478SLisandro Dalcin 
2319a63bb30eSJed Brown   ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
232017186662SBarry Smith   if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
232158c9b817SLisandro Dalcin   if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
232258c9b817SLisandro Dalcin 
232358c9b817SLisandro Dalcin   if (!snes->vec_sol_update /* && snes->vec_sol */) {
232458c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
232558c9b817SLisandro Dalcin     ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr);
232658c9b817SLisandro Dalcin   }
232758c9b817SLisandro Dalcin 
23286cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
23296cab3a1bSJed Brown   ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */
23306cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
23316cab3a1bSJed Brown   if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc");
23326cab3a1bSJed Brown   if (!snes->vec_func) {
23336cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2334214df951SJed Brown   }
2335efd51863SBarry Smith 
2336b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
2337b710008aSBarry Smith 
2338f1c6b773SPeter Brune   if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);}
23399e764e56SPeter Brune 
2340d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
2341d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
2342d25893d9SBarry Smith   }
2343d25893d9SBarry Smith 
23446e2a1849SPeter Brune   if (snes->pc) {
23456e2a1849SPeter Brune     /* copy the DM over */
23466e2a1849SPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
23476e2a1849SPeter Brune     ierr = SNESSetDM(snes->pc,dm);CHKERRQ(ierr);
23486e2a1849SPeter Brune 
23496e2a1849SPeter Brune     /* copy the legacy SNES context not related to the DM over*/
23506e2a1849SPeter Brune     ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr);
23516e2a1849SPeter Brune     ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr);
23526e2a1849SPeter Brune     ierr = SNESSetFunction(snes->pc,fpc,func,funcctx);CHKERRQ(ierr);
23536e2a1849SPeter Brune     ierr = SNESGetJacobian(snes,&A,&B,&jac,&jacctx);CHKERRQ(ierr);
23546e2a1849SPeter Brune     ierr = SNESSetJacobian(snes->pc,A,B,jac,jacctx);CHKERRQ(ierr);
23556e2a1849SPeter Brune     ierr = VecDestroy(&fpc);CHKERRQ(ierr);
23566e2a1849SPeter Brune 
23576e2a1849SPeter Brune     /* copy the function pointers over */
23586e2a1849SPeter Brune     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr);
23596e2a1849SPeter Brune 
23606e2a1849SPeter Brune      /* default to 1 iteration */
23616e2a1849SPeter Brune     ierr = SNESSetTolerances(snes->pc, snes->pc->abstol, snes->pc->rtol, snes->pc->stol, 1, snes->pc->max_funcs);CHKERRQ(ierr);
23626e2a1849SPeter Brune     ierr = SNESSetNormType(snes->pc, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr);
23636e2a1849SPeter Brune     ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr);
23646e2a1849SPeter Brune 
23656e2a1849SPeter Brune     /* copy the line search context over */
23666e2a1849SPeter Brune     ierr = SNESGetSNESLineSearch(snes,&linesearch);CHKERRQ(ierr);
23676e2a1849SPeter Brune     ierr = SNESGetSNESLineSearch(snes->pc,&pclinesearch);CHKERRQ(ierr);
23686e2a1849SPeter Brune     ierr = SNESLineSearchGetPreCheck(linesearch,&lsprefunc,&lsprectx);CHKERRQ(ierr);
23696e2a1849SPeter Brune     ierr = SNESLineSearchGetPostCheck(linesearch,&lspostfunc,&lspostctx);CHKERRQ(ierr);
23706e2a1849SPeter Brune     ierr = SNESLineSearchSetPreCheck(pclinesearch,lsprefunc,lsprectx);CHKERRQ(ierr);
23716e2a1849SPeter Brune     ierr = SNESLineSearchSetPostCheck(pclinesearch,lspostfunc,lspostctx);CHKERRQ(ierr);
23726e2a1849SPeter Brune     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr);
23736e2a1849SPeter Brune   }
23746e2a1849SPeter Brune 
2375410397dcSLisandro Dalcin   if (snes->ops->setup) {
2376410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2377410397dcSLisandro Dalcin   }
237858c9b817SLisandro Dalcin 
23797aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
23803a40ed3dSBarry Smith   PetscFunctionReturn(0);
23819b94acceSBarry Smith }
23829b94acceSBarry Smith 
23834a2ae208SSatish Balay #undef __FUNCT__
238437596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
238537596af1SLisandro Dalcin /*@
238637596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
238737596af1SLisandro Dalcin 
238837596af1SLisandro Dalcin    Collective on SNES
238937596af1SLisandro Dalcin 
239037596af1SLisandro Dalcin    Input Parameter:
239137596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
239237596af1SLisandro Dalcin 
2393d25893d9SBarry Smith    Level: intermediate
2394d25893d9SBarry Smith 
2395d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
239637596af1SLisandro Dalcin 
239737596af1SLisandro Dalcin .keywords: SNES, destroy
239837596af1SLisandro Dalcin 
239937596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
240037596af1SLisandro Dalcin @*/
240137596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
240237596af1SLisandro Dalcin {
240337596af1SLisandro Dalcin   PetscErrorCode ierr;
240437596af1SLisandro Dalcin 
240537596af1SLisandro Dalcin   PetscFunctionBegin;
240637596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2407d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
2408d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
2409d25893d9SBarry Smith     snes->user = PETSC_NULL;
2410d25893d9SBarry Smith   }
24118a23116dSBarry Smith   if (snes->pc) {
24128a23116dSBarry Smith     ierr = SNESReset(snes->pc);CHKERRQ(ierr);
24138a23116dSBarry Smith   }
24148a23116dSBarry Smith 
241537596af1SLisandro Dalcin   if (snes->ops->reset) {
241637596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
241737596af1SLisandro Dalcin   }
24189e764e56SPeter Brune   if (snes->ksp) {
24199e764e56SPeter Brune     ierr = KSPReset(snes->ksp);CHKERRQ(ierr);
24209e764e56SPeter Brune   }
24219e764e56SPeter Brune 
24229e764e56SPeter Brune   if (snes->linesearch) {
2423f1c6b773SPeter Brune     ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr);
24249e764e56SPeter Brune   }
24259e764e56SPeter Brune 
24266bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
24276bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
24286bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
24296bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
24306bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
24316bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2432c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
2433c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
243437596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
243537596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
243637596af1SLisandro Dalcin   PetscFunctionReturn(0);
243737596af1SLisandro Dalcin }
243837596af1SLisandro Dalcin 
243937596af1SLisandro Dalcin #undef __FUNCT__
24404a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
244152baeb72SSatish Balay /*@
24429b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
24439b94acceSBarry Smith    with SNESCreate().
24449b94acceSBarry Smith 
2445c7afd0dbSLois Curfman McInnes    Collective on SNES
2446c7afd0dbSLois Curfman McInnes 
24479b94acceSBarry Smith    Input Parameter:
24489b94acceSBarry Smith .  snes - the SNES context
24499b94acceSBarry Smith 
245036851e7fSLois Curfman McInnes    Level: beginner
245136851e7fSLois Curfman McInnes 
24529b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
24539b94acceSBarry Smith 
245463a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
24559b94acceSBarry Smith @*/
24566bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
24579b94acceSBarry Smith {
24586849ba73SBarry Smith   PetscErrorCode ierr;
24593a40ed3dSBarry Smith 
24603a40ed3dSBarry Smith   PetscFunctionBegin;
24616bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
24626bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
24636bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2464d4bb536fSBarry Smith 
24656bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
24668a23116dSBarry Smith   ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr);
24676b8b9a38SLisandro Dalcin 
2468be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
24696bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
24706bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
24716d4c513bSLisandro Dalcin 
24726bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
24736bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
2474f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr);
24756b8b9a38SLisandro Dalcin 
24766bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
24776bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
24786bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
24796b8b9a38SLisandro Dalcin   }
24806bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
24816bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
24826bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
248358c9b817SLisandro Dalcin   }
24846bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2485a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
24863a40ed3dSBarry Smith  PetscFunctionReturn(0);
24879b94acceSBarry Smith }
24889b94acceSBarry Smith 
24899b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
24909b94acceSBarry Smith 
24914a2ae208SSatish Balay #undef __FUNCT__
2492a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
2493a8054027SBarry Smith /*@
2494a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2495a8054027SBarry Smith 
24963f9fe445SBarry Smith    Logically Collective on SNES
2497a8054027SBarry Smith 
2498a8054027SBarry Smith    Input Parameters:
2499a8054027SBarry Smith +  snes - the SNES context
2500a8054027SBarry 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
25013b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2502a8054027SBarry Smith 
2503a8054027SBarry Smith    Options Database Keys:
2504a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2505a8054027SBarry Smith 
2506a8054027SBarry Smith    Notes:
2507a8054027SBarry Smith    The default is 1
2508a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2509a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2510a8054027SBarry Smith 
2511a8054027SBarry Smith    Level: intermediate
2512a8054027SBarry Smith 
2513a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2514a8054027SBarry Smith 
2515e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2516a8054027SBarry Smith 
2517a8054027SBarry Smith @*/
25187087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2519a8054027SBarry Smith {
2520a8054027SBarry Smith   PetscFunctionBegin;
25210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2522e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2523e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2524c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2525a8054027SBarry Smith   snes->lagpreconditioner = lag;
2526a8054027SBarry Smith   PetscFunctionReturn(0);
2527a8054027SBarry Smith }
2528a8054027SBarry Smith 
2529a8054027SBarry Smith #undef __FUNCT__
2530efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
2531efd51863SBarry Smith /*@
2532efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2533efd51863SBarry Smith 
2534efd51863SBarry Smith    Logically Collective on SNES
2535efd51863SBarry Smith 
2536efd51863SBarry Smith    Input Parameters:
2537efd51863SBarry Smith +  snes - the SNES context
2538efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
2539efd51863SBarry Smith 
2540efd51863SBarry Smith    Options Database Keys:
2541efd51863SBarry Smith .    -snes_grid_sequence <steps>
2542efd51863SBarry Smith 
2543efd51863SBarry Smith    Level: intermediate
2544efd51863SBarry Smith 
2545c0df2a02SJed Brown    Notes:
2546c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2547c0df2a02SJed Brown 
2548efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2549efd51863SBarry Smith 
2550efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2551efd51863SBarry Smith 
2552efd51863SBarry Smith @*/
2553efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2554efd51863SBarry Smith {
2555efd51863SBarry Smith   PetscFunctionBegin;
2556efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2557efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
2558efd51863SBarry Smith   snes->gridsequence = steps;
2559efd51863SBarry Smith   PetscFunctionReturn(0);
2560efd51863SBarry Smith }
2561efd51863SBarry Smith 
2562efd51863SBarry Smith #undef __FUNCT__
2563a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
2564a8054027SBarry Smith /*@
2565a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
2566a8054027SBarry Smith 
25673f9fe445SBarry Smith    Not Collective
2568a8054027SBarry Smith 
2569a8054027SBarry Smith    Input Parameter:
2570a8054027SBarry Smith .  snes - the SNES context
2571a8054027SBarry Smith 
2572a8054027SBarry Smith    Output Parameter:
2573a8054027SBarry 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
25743b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2575a8054027SBarry Smith 
2576a8054027SBarry Smith    Options Database Keys:
2577a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2578a8054027SBarry Smith 
2579a8054027SBarry Smith    Notes:
2580a8054027SBarry Smith    The default is 1
2581a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2582a8054027SBarry Smith 
2583a8054027SBarry Smith    Level: intermediate
2584a8054027SBarry Smith 
2585a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2586a8054027SBarry Smith 
2587a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
2588a8054027SBarry Smith 
2589a8054027SBarry Smith @*/
25907087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
2591a8054027SBarry Smith {
2592a8054027SBarry Smith   PetscFunctionBegin;
25930700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2594a8054027SBarry Smith   *lag = snes->lagpreconditioner;
2595a8054027SBarry Smith   PetscFunctionReturn(0);
2596a8054027SBarry Smith }
2597a8054027SBarry Smith 
2598a8054027SBarry Smith #undef __FUNCT__
2599e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
2600e35cf81dSBarry Smith /*@
2601e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
2602e35cf81dSBarry Smith      often the preconditioner is rebuilt.
2603e35cf81dSBarry Smith 
26043f9fe445SBarry Smith    Logically Collective on SNES
2605e35cf81dSBarry Smith 
2606e35cf81dSBarry Smith    Input Parameters:
2607e35cf81dSBarry Smith +  snes - the SNES context
2608e35cf81dSBarry 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
2609fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
2610e35cf81dSBarry Smith 
2611e35cf81dSBarry Smith    Options Database Keys:
2612e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2613e35cf81dSBarry Smith 
2614e35cf81dSBarry Smith    Notes:
2615e35cf81dSBarry Smith    The default is 1
2616e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2617fe3ffe1eSBarry 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
2618fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
2619e35cf81dSBarry Smith 
2620e35cf81dSBarry Smith    Level: intermediate
2621e35cf81dSBarry Smith 
2622e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2623e35cf81dSBarry Smith 
2624e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
2625e35cf81dSBarry Smith 
2626e35cf81dSBarry Smith @*/
26277087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
2628e35cf81dSBarry Smith {
2629e35cf81dSBarry Smith   PetscFunctionBegin;
26300700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2631e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2632e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2633c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2634e35cf81dSBarry Smith   snes->lagjacobian = lag;
2635e35cf81dSBarry Smith   PetscFunctionReturn(0);
2636e35cf81dSBarry Smith }
2637e35cf81dSBarry Smith 
2638e35cf81dSBarry Smith #undef __FUNCT__
2639e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
2640e35cf81dSBarry Smith /*@
2641e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
2642e35cf81dSBarry Smith 
26433f9fe445SBarry Smith    Not Collective
2644e35cf81dSBarry Smith 
2645e35cf81dSBarry Smith    Input Parameter:
2646e35cf81dSBarry Smith .  snes - the SNES context
2647e35cf81dSBarry Smith 
2648e35cf81dSBarry Smith    Output Parameter:
2649e35cf81dSBarry 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
2650e35cf81dSBarry Smith          the Jacobian is built etc.
2651e35cf81dSBarry Smith 
2652e35cf81dSBarry Smith    Options Database Keys:
2653e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2654e35cf81dSBarry Smith 
2655e35cf81dSBarry Smith    Notes:
2656e35cf81dSBarry Smith    The default is 1
2657e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2658e35cf81dSBarry Smith 
2659e35cf81dSBarry Smith    Level: intermediate
2660e35cf81dSBarry Smith 
2661e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2662e35cf81dSBarry Smith 
2663e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
2664e35cf81dSBarry Smith 
2665e35cf81dSBarry Smith @*/
26667087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
2667e35cf81dSBarry Smith {
2668e35cf81dSBarry Smith   PetscFunctionBegin;
26690700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2670e35cf81dSBarry Smith   *lag = snes->lagjacobian;
2671e35cf81dSBarry Smith   PetscFunctionReturn(0);
2672e35cf81dSBarry Smith }
2673e35cf81dSBarry Smith 
2674e35cf81dSBarry Smith #undef __FUNCT__
26754a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
26769b94acceSBarry Smith /*@
2677d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
26789b94acceSBarry Smith 
26793f9fe445SBarry Smith    Logically Collective on SNES
2680c7afd0dbSLois Curfman McInnes 
26819b94acceSBarry Smith    Input Parameters:
2682c7afd0dbSLois Curfman McInnes +  snes - the SNES context
268370441072SBarry Smith .  abstol - absolute convergence tolerance
268433174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
268533174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
268633174efeSLois Curfman McInnes            of the change in the solution between steps
268733174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2688c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2689fee21e36SBarry Smith 
269033174efeSLois Curfman McInnes    Options Database Keys:
269170441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
2692c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
2693c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
2694c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
2695c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
26969b94acceSBarry Smith 
2697d7a720efSLois Curfman McInnes    Notes:
26989b94acceSBarry Smith    The default maximum number of iterations is 50.
26999b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
27009b94acceSBarry Smith 
270136851e7fSLois Curfman McInnes    Level: intermediate
270236851e7fSLois Curfman McInnes 
270333174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
27049b94acceSBarry Smith 
27052492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
27069b94acceSBarry Smith @*/
27077087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
27089b94acceSBarry Smith {
27093a40ed3dSBarry Smith   PetscFunctionBegin;
27100700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2711c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
2712c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
2713c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
2714c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
2715c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
2716c5eb9154SBarry Smith 
2717ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
2718ab54825eSJed Brown     if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol);
2719ab54825eSJed Brown     snes->abstol = abstol;
2720ab54825eSJed Brown   }
2721ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
2722ab54825eSJed 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);
2723ab54825eSJed Brown     snes->rtol = rtol;
2724ab54825eSJed Brown   }
2725ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
2726ab54825eSJed Brown     if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol);
2727c60f73f4SPeter Brune     snes->stol = stol;
2728ab54825eSJed Brown   }
2729ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
2730ab54825eSJed Brown     if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
2731ab54825eSJed Brown     snes->max_its = maxit;
2732ab54825eSJed Brown   }
2733ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
2734ab54825eSJed Brown     if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
2735ab54825eSJed Brown     snes->max_funcs = maxf;
2736ab54825eSJed Brown   }
273788976e71SPeter Brune   snes->tolerancesset = PETSC_TRUE;
27383a40ed3dSBarry Smith   PetscFunctionReturn(0);
27399b94acceSBarry Smith }
27409b94acceSBarry Smith 
27414a2ae208SSatish Balay #undef __FUNCT__
27424a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
27439b94acceSBarry Smith /*@
274433174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
274533174efeSLois Curfman McInnes 
2746c7afd0dbSLois Curfman McInnes    Not Collective
2747c7afd0dbSLois Curfman McInnes 
274833174efeSLois Curfman McInnes    Input Parameters:
2749c7afd0dbSLois Curfman McInnes +  snes - the SNES context
275085385478SLisandro Dalcin .  atol - absolute convergence tolerance
275133174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
275233174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
275333174efeSLois Curfman McInnes            of the change in the solution between steps
275433174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2755c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2756fee21e36SBarry Smith 
275733174efeSLois Curfman McInnes    Notes:
275833174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
275933174efeSLois Curfman McInnes 
276036851e7fSLois Curfman McInnes    Level: intermediate
276136851e7fSLois Curfman McInnes 
276233174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
276333174efeSLois Curfman McInnes 
276433174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
276533174efeSLois Curfman McInnes @*/
27667087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
276733174efeSLois Curfman McInnes {
27683a40ed3dSBarry Smith   PetscFunctionBegin;
27690700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
277085385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
277133174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
2772c60f73f4SPeter Brune   if (stol)  *stol  = snes->stol;
277333174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
277433174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
27753a40ed3dSBarry Smith   PetscFunctionReturn(0);
277633174efeSLois Curfman McInnes }
277733174efeSLois Curfman McInnes 
27784a2ae208SSatish Balay #undef __FUNCT__
27794a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
278033174efeSLois Curfman McInnes /*@
27819b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
27829b94acceSBarry Smith 
27833f9fe445SBarry Smith    Logically Collective on SNES
2784fee21e36SBarry Smith 
2785c7afd0dbSLois Curfman McInnes    Input Parameters:
2786c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2787c7afd0dbSLois Curfman McInnes -  tol - tolerance
2788c7afd0dbSLois Curfman McInnes 
27899b94acceSBarry Smith    Options Database Key:
2790c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
27919b94acceSBarry Smith 
279236851e7fSLois Curfman McInnes    Level: intermediate
279336851e7fSLois Curfman McInnes 
27949b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
27959b94acceSBarry Smith 
27962492ecdbSBarry Smith .seealso: SNESSetTolerances()
27979b94acceSBarry Smith @*/
27987087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
27999b94acceSBarry Smith {
28003a40ed3dSBarry Smith   PetscFunctionBegin;
28010700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2802c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
28039b94acceSBarry Smith   snes->deltatol = tol;
28043a40ed3dSBarry Smith   PetscFunctionReturn(0);
28059b94acceSBarry Smith }
28069b94acceSBarry Smith 
2807df9fa365SBarry Smith /*
2808df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
2809df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
2810df9fa365SBarry Smith    macros instead of functions
2811df9fa365SBarry Smith */
28124a2ae208SSatish Balay #undef __FUNCT__
2813a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
28147087cfbeSBarry Smith PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2815ce1608b8SBarry Smith {
2816dfbe8321SBarry Smith   PetscErrorCode ierr;
2817ce1608b8SBarry Smith 
2818ce1608b8SBarry Smith   PetscFunctionBegin;
28190700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2820a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
2821ce1608b8SBarry Smith   PetscFunctionReturn(0);
2822ce1608b8SBarry Smith }
2823ce1608b8SBarry Smith 
28244a2ae208SSatish Balay #undef __FUNCT__
2825a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
28267087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2827df9fa365SBarry Smith {
2828dfbe8321SBarry Smith   PetscErrorCode ierr;
2829df9fa365SBarry Smith 
2830df9fa365SBarry Smith   PetscFunctionBegin;
2831a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2832df9fa365SBarry Smith   PetscFunctionReturn(0);
2833df9fa365SBarry Smith }
2834df9fa365SBarry Smith 
28354a2ae208SSatish Balay #undef __FUNCT__
2836a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
28376bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
2838df9fa365SBarry Smith {
2839dfbe8321SBarry Smith   PetscErrorCode ierr;
2840df9fa365SBarry Smith 
2841df9fa365SBarry Smith   PetscFunctionBegin;
2842a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2843df9fa365SBarry Smith   PetscFunctionReturn(0);
2844df9fa365SBarry Smith }
2845df9fa365SBarry Smith 
28467087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
2847b271bb04SBarry Smith #undef __FUNCT__
2848b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
28497087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2850b271bb04SBarry Smith {
2851b271bb04SBarry Smith   PetscDrawLG      lg;
2852b271bb04SBarry Smith   PetscErrorCode   ierr;
2853b271bb04SBarry Smith   PetscReal        x,y,per;
2854b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
2855b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
2856b271bb04SBarry Smith   PetscDraw        draw;
2857b271bb04SBarry Smith   PetscFunctionBegin;
2858b271bb04SBarry Smith   if (!monctx) {
2859b271bb04SBarry Smith     MPI_Comm    comm;
2860b271bb04SBarry Smith 
2861b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2862b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
2863b271bb04SBarry Smith   }
2864b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
2865b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2866b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2867b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
2868b271bb04SBarry Smith   x = (PetscReal) n;
2869b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
2870b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2871b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2872b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2873b271bb04SBarry Smith   }
2874b271bb04SBarry Smith 
2875b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
2876b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2877b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2878b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
2879b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
2880b271bb04SBarry Smith   x = (PetscReal) n;
2881b271bb04SBarry Smith   y = 100.0*per;
2882b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2883b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2884b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2885b271bb04SBarry Smith   }
2886b271bb04SBarry Smith 
2887b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
2888b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2889b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2890b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
2891b271bb04SBarry Smith   x = (PetscReal) n;
2892b271bb04SBarry Smith   y = (prev - rnorm)/prev;
2893b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2894b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2895b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2896b271bb04SBarry Smith   }
2897b271bb04SBarry Smith 
2898b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
2899b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2900b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2901b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
2902b271bb04SBarry Smith   x = (PetscReal) n;
2903b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
2904b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
2905b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2906b271bb04SBarry Smith   }
2907b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2908b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2909b271bb04SBarry Smith   }
2910b271bb04SBarry Smith   prev = rnorm;
2911b271bb04SBarry Smith   PetscFunctionReturn(0);
2912b271bb04SBarry Smith }
2913b271bb04SBarry Smith 
2914b271bb04SBarry Smith #undef __FUNCT__
2915b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
29167087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2917b271bb04SBarry Smith {
2918b271bb04SBarry Smith   PetscErrorCode ierr;
2919b271bb04SBarry Smith 
2920b271bb04SBarry Smith   PetscFunctionBegin;
2921b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2922b271bb04SBarry Smith   PetscFunctionReturn(0);
2923b271bb04SBarry Smith }
2924b271bb04SBarry Smith 
2925b271bb04SBarry Smith #undef __FUNCT__
2926b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
29276bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG *draw)
2928b271bb04SBarry Smith {
2929b271bb04SBarry Smith   PetscErrorCode ierr;
2930b271bb04SBarry Smith 
2931b271bb04SBarry Smith   PetscFunctionBegin;
2932b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2933b271bb04SBarry Smith   PetscFunctionReturn(0);
2934b271bb04SBarry Smith }
2935b271bb04SBarry Smith 
29367a03ce2fSLisandro Dalcin #undef __FUNCT__
29377a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
2938228d79bcSJed Brown /*@
2939228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
2940228d79bcSJed Brown 
2941228d79bcSJed Brown    Collective on SNES
2942228d79bcSJed Brown 
2943228d79bcSJed Brown    Input Parameters:
2944228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
2945228d79bcSJed Brown .  iter - iteration number
2946228d79bcSJed Brown -  rnorm - relative norm of the residual
2947228d79bcSJed Brown 
2948228d79bcSJed Brown    Notes:
2949228d79bcSJed Brown    This routine is called by the SNES implementations.
2950228d79bcSJed Brown    It does not typically need to be called by the user.
2951228d79bcSJed Brown 
2952228d79bcSJed Brown    Level: developer
2953228d79bcSJed Brown 
2954228d79bcSJed Brown .seealso: SNESMonitorSet()
2955228d79bcSJed Brown @*/
29567a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
29577a03ce2fSLisandro Dalcin {
29587a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
29597a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
29607a03ce2fSLisandro Dalcin 
29617a03ce2fSLisandro Dalcin   PetscFunctionBegin;
29627a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
29637a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
29647a03ce2fSLisandro Dalcin   }
29657a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
29667a03ce2fSLisandro Dalcin }
29677a03ce2fSLisandro Dalcin 
29689b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
29699b94acceSBarry Smith 
29704a2ae208SSatish Balay #undef __FUNCT__
2971a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
29729b94acceSBarry Smith /*@C
2973a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
29749b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
29759b94acceSBarry Smith    progress.
29769b94acceSBarry Smith 
29773f9fe445SBarry Smith    Logically Collective on SNES
2978fee21e36SBarry Smith 
2979c7afd0dbSLois Curfman McInnes    Input Parameters:
2980c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2981c7afd0dbSLois Curfman McInnes .  func - monitoring routine
2982b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
2983e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
2984b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
2985b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
29869b94acceSBarry Smith 
2987c7afd0dbSLois Curfman McInnes    Calling sequence of func:
2988a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
2989c7afd0dbSLois Curfman McInnes 
2990c7afd0dbSLois Curfman McInnes +    snes - the SNES context
2991c7afd0dbSLois Curfman McInnes .    its - iteration number
2992c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
299340a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
29949b94acceSBarry Smith 
29959665c990SLois Curfman McInnes    Options Database Keys:
2996a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
2997a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
2998a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
2999cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
3000c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
3001a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
3002c7afd0dbSLois Curfman McInnes                             does not cancel those set via
3003c7afd0dbSLois Curfman McInnes                             the options database.
30049665c990SLois Curfman McInnes 
3005639f9d9dSBarry Smith    Notes:
30066bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
3007a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
30086bc08f3fSLois Curfman McInnes    order in which they were set.
3009639f9d9dSBarry Smith 
3010025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
3011025f1a04SBarry Smith 
301236851e7fSLois Curfman McInnes    Level: intermediate
301336851e7fSLois Curfman McInnes 
30149b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
30159b94acceSBarry Smith 
3016a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
30179b94acceSBarry Smith @*/
3018c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
30199b94acceSBarry Smith {
3020b90d0a6eSBarry Smith   PetscInt       i;
3021649052a6SBarry Smith   PetscErrorCode ierr;
3022b90d0a6eSBarry Smith 
30233a40ed3dSBarry Smith   PetscFunctionBegin;
30240700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
302517186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
3026b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
3027649052a6SBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
3028649052a6SBarry Smith       if (monitordestroy) {
3029c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
3030649052a6SBarry Smith       }
3031b90d0a6eSBarry Smith       PetscFunctionReturn(0);
3032b90d0a6eSBarry Smith     }
3033b90d0a6eSBarry Smith   }
3034b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
3035b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
3036639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
30373a40ed3dSBarry Smith   PetscFunctionReturn(0);
30389b94acceSBarry Smith }
30399b94acceSBarry Smith 
30404a2ae208SSatish Balay #undef __FUNCT__
3041a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
30425cd90555SBarry Smith /*@C
3043a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
30445cd90555SBarry Smith 
30453f9fe445SBarry Smith    Logically Collective on SNES
3046c7afd0dbSLois Curfman McInnes 
30475cd90555SBarry Smith    Input Parameters:
30485cd90555SBarry Smith .  snes - the SNES context
30495cd90555SBarry Smith 
30501a480d89SAdministrator    Options Database Key:
3051a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
3052a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
3053c7afd0dbSLois Curfman McInnes     set via the options database
30545cd90555SBarry Smith 
30555cd90555SBarry Smith    Notes:
30565cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
30575cd90555SBarry Smith 
305836851e7fSLois Curfman McInnes    Level: intermediate
305936851e7fSLois Curfman McInnes 
30605cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
30615cd90555SBarry Smith 
3062a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
30635cd90555SBarry Smith @*/
30647087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
30655cd90555SBarry Smith {
3066d952e501SBarry Smith   PetscErrorCode ierr;
3067d952e501SBarry Smith   PetscInt       i;
3068d952e501SBarry Smith 
30695cd90555SBarry Smith   PetscFunctionBegin;
30700700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3071d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
3072d952e501SBarry Smith     if (snes->monitordestroy[i]) {
30733c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
3074d952e501SBarry Smith     }
3075d952e501SBarry Smith   }
30765cd90555SBarry Smith   snes->numbermonitors = 0;
30775cd90555SBarry Smith   PetscFunctionReturn(0);
30785cd90555SBarry Smith }
30795cd90555SBarry Smith 
30804a2ae208SSatish Balay #undef __FUNCT__
30814a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
30829b94acceSBarry Smith /*@C
30839b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
30849b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
30859b94acceSBarry Smith 
30863f9fe445SBarry Smith    Logically Collective on SNES
3087fee21e36SBarry Smith 
3088c7afd0dbSLois Curfman McInnes    Input Parameters:
3089c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3090c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
30917f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
30927f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
30939b94acceSBarry Smith 
3094c7afd0dbSLois Curfman McInnes    Calling sequence of func:
309506ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
3096c7afd0dbSLois Curfman McInnes 
3097c7afd0dbSLois Curfman McInnes +    snes - the SNES context
309806ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
3099c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
3100184914b5SBarry Smith .    reason - reason for convergence/divergence
3101c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
31024b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
31034b27c08aSLois Curfman McInnes -    f - 2-norm of function
31049b94acceSBarry Smith 
310536851e7fSLois Curfman McInnes    Level: advanced
310636851e7fSLois Curfman McInnes 
31079b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
31089b94acceSBarry Smith 
310985385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
31109b94acceSBarry Smith @*/
31117087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
31129b94acceSBarry Smith {
31137f7931b9SBarry Smith   PetscErrorCode ierr;
31147f7931b9SBarry Smith 
31153a40ed3dSBarry Smith   PetscFunctionBegin;
31160700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
311785385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
31187f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
31197f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
31207f7931b9SBarry Smith   }
312185385478SLisandro Dalcin   snes->ops->converged        = func;
31227f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
312385385478SLisandro Dalcin   snes->cnvP                  = cctx;
31243a40ed3dSBarry Smith   PetscFunctionReturn(0);
31259b94acceSBarry Smith }
31269b94acceSBarry Smith 
31274a2ae208SSatish Balay #undef __FUNCT__
31284a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
312952baeb72SSatish Balay /*@
3130184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
3131184914b5SBarry Smith 
3132184914b5SBarry Smith    Not Collective
3133184914b5SBarry Smith 
3134184914b5SBarry Smith    Input Parameter:
3135184914b5SBarry Smith .  snes - the SNES context
3136184914b5SBarry Smith 
3137184914b5SBarry Smith    Output Parameter:
31384d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
3139184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
3140184914b5SBarry Smith 
3141184914b5SBarry Smith    Level: intermediate
3142184914b5SBarry Smith 
3143184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
3144184914b5SBarry Smith 
3145184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
3146184914b5SBarry Smith 
314785385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
3148184914b5SBarry Smith @*/
31497087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
3150184914b5SBarry Smith {
3151184914b5SBarry Smith   PetscFunctionBegin;
31520700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
31534482741eSBarry Smith   PetscValidPointer(reason,2);
3154184914b5SBarry Smith   *reason = snes->reason;
3155184914b5SBarry Smith   PetscFunctionReturn(0);
3156184914b5SBarry Smith }
3157184914b5SBarry Smith 
31584a2ae208SSatish Balay #undef __FUNCT__
31594a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
3160c9005455SLois Curfman McInnes /*@
3161c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
3162c9005455SLois Curfman McInnes 
31633f9fe445SBarry Smith    Logically Collective on SNES
3164fee21e36SBarry Smith 
3165c7afd0dbSLois Curfman McInnes    Input Parameters:
3166c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
31678c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
3168cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
3169758f92a0SBarry Smith .  na  - size of a and its
317064731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
3171758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
3172c7afd0dbSLois Curfman McInnes 
3173308dcc3eSBarry Smith    Notes:
3174308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
3175308dcc3eSBarry Smith    default array of length 10000 is allocated.
3176308dcc3eSBarry Smith 
3177c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
3178c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
3179c9005455SLois Curfman McInnes    during the section of code that is being timed.
3180c9005455SLois Curfman McInnes 
318136851e7fSLois Curfman McInnes    Level: intermediate
318236851e7fSLois Curfman McInnes 
3183c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
3184758f92a0SBarry Smith 
318508405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
3186758f92a0SBarry Smith 
3187c9005455SLois Curfman McInnes @*/
31887087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
3189c9005455SLois Curfman McInnes {
3190308dcc3eSBarry Smith   PetscErrorCode ierr;
3191308dcc3eSBarry Smith 
31923a40ed3dSBarry Smith   PetscFunctionBegin;
31930700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
31944482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
3195a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
3196308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
3197308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
3198308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
3199308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
3200308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
3201308dcc3eSBarry Smith   }
3202c9005455SLois Curfman McInnes   snes->conv_hist       = a;
3203758f92a0SBarry Smith   snes->conv_hist_its   = its;
3204758f92a0SBarry Smith   snes->conv_hist_max   = na;
3205a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
3206758f92a0SBarry Smith   snes->conv_hist_reset = reset;
3207758f92a0SBarry Smith   PetscFunctionReturn(0);
3208758f92a0SBarry Smith }
3209758f92a0SBarry Smith 
3210308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3211c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
3212c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
3213308dcc3eSBarry Smith EXTERN_C_BEGIN
3214308dcc3eSBarry Smith #undef __FUNCT__
3215308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
3216308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
3217308dcc3eSBarry Smith {
3218308dcc3eSBarry Smith   mxArray        *mat;
3219308dcc3eSBarry Smith   PetscInt       i;
3220308dcc3eSBarry Smith   PetscReal      *ar;
3221308dcc3eSBarry Smith 
3222308dcc3eSBarry Smith   PetscFunctionBegin;
3223308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
3224308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
3225308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
3226308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
3227308dcc3eSBarry Smith   }
3228308dcc3eSBarry Smith   PetscFunctionReturn(mat);
3229308dcc3eSBarry Smith }
3230308dcc3eSBarry Smith EXTERN_C_END
3231308dcc3eSBarry Smith #endif
3232308dcc3eSBarry Smith 
3233308dcc3eSBarry Smith 
32344a2ae208SSatish Balay #undef __FUNCT__
32354a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
32360c4c9dddSBarry Smith /*@C
3237758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
3238758f92a0SBarry Smith 
32393f9fe445SBarry Smith    Not Collective
3240758f92a0SBarry Smith 
3241758f92a0SBarry Smith    Input Parameter:
3242758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
3243758f92a0SBarry Smith 
3244758f92a0SBarry Smith    Output Parameters:
3245758f92a0SBarry Smith .  a   - array to hold history
3246758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
3247758f92a0SBarry Smith          negative if not converged) for each solve.
3248758f92a0SBarry Smith -  na  - size of a and its
3249758f92a0SBarry Smith 
3250758f92a0SBarry Smith    Notes:
3251758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
3252758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
3253758f92a0SBarry Smith 
3254758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
3255758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
3256758f92a0SBarry Smith    during the section of code that is being timed.
3257758f92a0SBarry Smith 
3258758f92a0SBarry Smith    Level: intermediate
3259758f92a0SBarry Smith 
3260758f92a0SBarry Smith .keywords: SNES, get, convergence, history
3261758f92a0SBarry Smith 
3262758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
3263758f92a0SBarry Smith 
3264758f92a0SBarry Smith @*/
32657087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3266758f92a0SBarry Smith {
3267758f92a0SBarry Smith   PetscFunctionBegin;
32680700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3269758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
3270758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
3271758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
32723a40ed3dSBarry Smith   PetscFunctionReturn(0);
3273c9005455SLois Curfman McInnes }
3274c9005455SLois Curfman McInnes 
3275e74ef692SMatthew Knepley #undef __FUNCT__
3276e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
3277ac226902SBarry Smith /*@C
327876b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
3279eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
32807e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
328176b2cf59SMatthew Knepley 
32823f9fe445SBarry Smith   Logically Collective on SNES
328376b2cf59SMatthew Knepley 
328476b2cf59SMatthew Knepley   Input Parameters:
328576b2cf59SMatthew Knepley . snes - The nonlinear solver context
328676b2cf59SMatthew Knepley . func - The function
328776b2cf59SMatthew Knepley 
328876b2cf59SMatthew Knepley   Calling sequence of func:
3289b5d30489SBarry Smith . func (SNES snes, PetscInt step);
329076b2cf59SMatthew Knepley 
329176b2cf59SMatthew Knepley . step - The current step of the iteration
329276b2cf59SMatthew Knepley 
3293fe97e370SBarry Smith   Level: advanced
3294fe97e370SBarry Smith 
3295fe97e370SBarry 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()
3296fe97e370SBarry Smith         This is not used by most users.
329776b2cf59SMatthew Knepley 
329876b2cf59SMatthew Knepley .keywords: SNES, update
3299b5d30489SBarry Smith 
330085385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
330176b2cf59SMatthew Knepley @*/
33027087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
330376b2cf59SMatthew Knepley {
330476b2cf59SMatthew Knepley   PetscFunctionBegin;
33050700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
3306e7788613SBarry Smith   snes->ops->update = func;
330776b2cf59SMatthew Knepley   PetscFunctionReturn(0);
330876b2cf59SMatthew Knepley }
330976b2cf59SMatthew Knepley 
3310e74ef692SMatthew Knepley #undef __FUNCT__
3311e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
331276b2cf59SMatthew Knepley /*@
331376b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
331476b2cf59SMatthew Knepley 
331576b2cf59SMatthew Knepley   Not collective
331676b2cf59SMatthew Knepley 
331776b2cf59SMatthew Knepley   Input Parameters:
331876b2cf59SMatthew Knepley . snes - The nonlinear solver context
331976b2cf59SMatthew Knepley . step - The current step of the iteration
332076b2cf59SMatthew Knepley 
3321205452f4SMatthew Knepley   Level: intermediate
3322205452f4SMatthew Knepley 
332376b2cf59SMatthew Knepley .keywords: SNES, update
3324a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
332576b2cf59SMatthew Knepley @*/
33267087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
332776b2cf59SMatthew Knepley {
332876b2cf59SMatthew Knepley   PetscFunctionBegin;
332976b2cf59SMatthew Knepley   PetscFunctionReturn(0);
333076b2cf59SMatthew Knepley }
333176b2cf59SMatthew Knepley 
33324a2ae208SSatish Balay #undef __FUNCT__
33334a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
33349b94acceSBarry Smith /*
33359b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
33369b94acceSBarry Smith    positive parameter delta.
33379b94acceSBarry Smith 
33389b94acceSBarry Smith     Input Parameters:
3339c7afd0dbSLois Curfman McInnes +   snes - the SNES context
33409b94acceSBarry Smith .   y - approximate solution of linear system
33419b94acceSBarry Smith .   fnorm - 2-norm of current function
3342c7afd0dbSLois Curfman McInnes -   delta - trust region size
33439b94acceSBarry Smith 
33449b94acceSBarry Smith     Output Parameters:
3345c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
33469b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
33479b94acceSBarry Smith     region, and exceeds zero otherwise.
3348c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
33499b94acceSBarry Smith 
33509b94acceSBarry Smith     Note:
33514b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
33529b94acceSBarry Smith     is set to be the maximum allowable step size.
33539b94acceSBarry Smith 
33549b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
33559b94acceSBarry Smith */
3356dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
33579b94acceSBarry Smith {
3358064f8208SBarry Smith   PetscReal      nrm;
3359ea709b57SSatish Balay   PetscScalar    cnorm;
3360dfbe8321SBarry Smith   PetscErrorCode ierr;
33613a40ed3dSBarry Smith 
33623a40ed3dSBarry Smith   PetscFunctionBegin;
33630700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
33640700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3365c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
3366184914b5SBarry Smith 
3367064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
3368064f8208SBarry Smith   if (nrm > *delta) {
3369064f8208SBarry Smith      nrm = *delta/nrm;
3370064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
3371064f8208SBarry Smith      cnorm = nrm;
33722dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
33739b94acceSBarry Smith      *ynorm = *delta;
33749b94acceSBarry Smith   } else {
33759b94acceSBarry Smith      *gpnorm = 0.0;
3376064f8208SBarry Smith      *ynorm = nrm;
33779b94acceSBarry Smith   }
33783a40ed3dSBarry Smith   PetscFunctionReturn(0);
33799b94acceSBarry Smith }
33809b94acceSBarry Smith 
33814a2ae208SSatish Balay #undef __FUNCT__
33824a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
33836ce558aeSBarry Smith /*@C
3384f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
3385f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
33869b94acceSBarry Smith 
3387c7afd0dbSLois Curfman McInnes    Collective on SNES
3388c7afd0dbSLois Curfman McInnes 
3389b2002411SLois Curfman McInnes    Input Parameters:
3390c7afd0dbSLois Curfman McInnes +  snes - the SNES context
33913cebf274SJed Brown .  b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero.
339285385478SLisandro Dalcin -  x - the solution vector.
33939b94acceSBarry Smith 
3394b2002411SLois Curfman McInnes    Notes:
33958ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
33968ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
33978ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
33988ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
33998ddd3da0SLois Curfman McInnes 
340036851e7fSLois Curfman McInnes    Level: beginner
340136851e7fSLois Curfman McInnes 
34029b94acceSBarry Smith .keywords: SNES, nonlinear, solve
34039b94acceSBarry Smith 
3404c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
34059b94acceSBarry Smith @*/
34067087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
34079b94acceSBarry Smith {
3408dfbe8321SBarry Smith   PetscErrorCode ierr;
3409ace3abfcSBarry Smith   PetscBool      flg;
3410eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
3411eabae89aSBarry Smith   PetscViewer    viewer;
3412efd51863SBarry Smith   PetscInt       grid;
3413a69afd8bSBarry Smith   Vec            xcreated = PETSC_NULL;
3414caa4e7f2SJed Brown   DM             dm;
3415052efed2SBarry Smith 
34163a40ed3dSBarry Smith   PetscFunctionBegin;
34170700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3418a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3419a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
34200700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
342185385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
342285385478SLisandro Dalcin 
3423caa4e7f2SJed Brown   if (!x) {
3424caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3425caa4e7f2SJed Brown     ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr);
3426a69afd8bSBarry Smith     x    = xcreated;
3427a69afd8bSBarry Smith   }
3428a69afd8bSBarry Smith 
3429a8248277SBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);}
3430efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
3431efd51863SBarry Smith 
343285385478SLisandro Dalcin     /* set solution vector */
3433efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
34346bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
343585385478SLisandro Dalcin     snes->vec_sol = x;
3436caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3437caa4e7f2SJed Brown 
3438caa4e7f2SJed Brown     /* set affine vector if provided */
343985385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
34406bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
344185385478SLisandro Dalcin     snes->vec_rhs = b;
344285385478SLisandro Dalcin 
344370e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
34443f149594SLisandro Dalcin 
34457eee914bSBarry Smith     if (!grid) {
34467eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
3447d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
3448dd568438SSatish Balay       } else if (snes->dm) {
3449dd568438SSatish Balay         PetscBool ig;
3450dd568438SSatish Balay         ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr);
3451dd568438SSatish Balay         if (ig) {
34527eee914bSBarry Smith           ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr);
34537eee914bSBarry Smith         }
3454d25893d9SBarry Smith       }
3455dd568438SSatish Balay     }
3456d25893d9SBarry Smith 
3457abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
345850ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
3459d5e45103SBarry Smith 
34603f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
34614936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
346285385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
34634936397dSBarry Smith     if (snes->domainerror){
34644936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
34654936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
34664936397dSBarry Smith     }
346717186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
34683f149594SLisandro Dalcin 
346990d69ab7SBarry Smith     flg  = PETSC_FALSE;
3470acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
3471da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
34725968eb51SBarry Smith     if (snes->printreason) {
3473a8248277SBarry Smith       ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
34745968eb51SBarry Smith       if (snes->reason > 0) {
3475c7e7b494SJed 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);
34765968eb51SBarry Smith       } else {
3477c7e7b494SJed 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);
34785968eb51SBarry Smith       }
3479a8248277SBarry Smith       ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
34805968eb51SBarry Smith     }
34815968eb51SBarry Smith 
3482e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
3483efd51863SBarry Smith     if (grid <  snes->gridsequence) {
3484efd51863SBarry Smith       DM  fine;
3485efd51863SBarry Smith       Vec xnew;
3486efd51863SBarry Smith       Mat interp;
3487efd51863SBarry Smith 
3488efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
3489c5c77316SJed Brown       if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
3490e727c939SJed Brown       ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
3491efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
3492efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
3493c833c3b5SJed Brown       ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr);
3494efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
3495efd51863SBarry Smith       x    = xnew;
3496efd51863SBarry Smith 
3497efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
3498efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
3499efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
3500a8248277SBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);
3501efd51863SBarry Smith     }
3502efd51863SBarry Smith   }
3503*3f7e2da0SPeter Brune   /* monitoring and viewing */
3504*3f7e2da0SPeter Brune   flg = PETSC_FALSE;
3505*3f7e2da0SPeter Brune   ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
3506*3f7e2da0SPeter Brune   if (flg && !PetscPreLoadingOn) {
3507*3f7e2da0SPeter Brune     ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
3508*3f7e2da0SPeter Brune     ierr = SNESView(snes,viewer);CHKERRQ(ierr);
3509*3f7e2da0SPeter Brune     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3510*3f7e2da0SPeter Brune   }
3511*3f7e2da0SPeter Brune 
3512*3f7e2da0SPeter Brune   flg = PETSC_FALSE;
3513*3f7e2da0SPeter Brune   ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
3514*3f7e2da0SPeter Brune   if (flg) {
3515*3f7e2da0SPeter Brune     PetscViewer viewer;
3516*3f7e2da0SPeter Brune     ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
3517*3f7e2da0SPeter Brune     ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr);
3518*3f7e2da0SPeter Brune     ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr);
3519*3f7e2da0SPeter Brune     ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr);
3520*3f7e2da0SPeter Brune     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3521*3f7e2da0SPeter Brune   }
3522*3f7e2da0SPeter Brune 
3523a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
35243a40ed3dSBarry Smith   PetscFunctionReturn(0);
35259b94acceSBarry Smith }
35269b94acceSBarry Smith 
35279b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
35289b94acceSBarry Smith 
35294a2ae208SSatish Balay #undef __FUNCT__
35304a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
353182bf6240SBarry Smith /*@C
35324b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
35339b94acceSBarry Smith 
3534fee21e36SBarry Smith    Collective on SNES
3535fee21e36SBarry Smith 
3536c7afd0dbSLois Curfman McInnes    Input Parameters:
3537c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3538454a90a3SBarry Smith -  type - a known method
3539c7afd0dbSLois Curfman McInnes 
3540c7afd0dbSLois Curfman McInnes    Options Database Key:
3541454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
3542c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
3543ae12b187SLois Curfman McInnes 
35449b94acceSBarry Smith    Notes:
3545e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
35464b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
3547c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
35484b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
3549c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
35509b94acceSBarry Smith 
3551ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
3552ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
3553ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
3554ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
3555ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
3556ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
3557ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
3558ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
3559ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
3560b0a32e0cSBarry Smith   appropriate method.
356136851e7fSLois Curfman McInnes 
356236851e7fSLois Curfman McInnes   Level: intermediate
3563a703fe33SLois Curfman McInnes 
3564454a90a3SBarry Smith .keywords: SNES, set, type
3565435da068SBarry Smith 
3566435da068SBarry Smith .seealso: SNESType, SNESCreate()
3567435da068SBarry Smith 
35689b94acceSBarry Smith @*/
35697087cfbeSBarry Smith PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
35709b94acceSBarry Smith {
3571dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
3572ace3abfcSBarry Smith   PetscBool      match;
35733a40ed3dSBarry Smith 
35743a40ed3dSBarry Smith   PetscFunctionBegin;
35750700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35764482741eSBarry Smith   PetscValidCharPointer(type,2);
357782bf6240SBarry Smith 
3578251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
35790f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
358092ff6ae8SBarry Smith 
35814b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
3582e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
358375396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
3584b5c23020SJed Brown   if (snes->ops->destroy) {
3585b5c23020SJed Brown     ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
3586b5c23020SJed Brown     snes->ops->destroy = PETSC_NULL;
3587b5c23020SJed Brown   }
358875396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
358975396ef9SLisandro Dalcin   snes->ops->setup          = 0;
359075396ef9SLisandro Dalcin   snes->ops->solve          = 0;
359175396ef9SLisandro Dalcin   snes->ops->view           = 0;
359275396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
359375396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
359475396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
359575396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
3596454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
359703bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
35989fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
35999fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
36009fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
36019fb22e1aSBarry Smith   }
36029fb22e1aSBarry Smith #endif
36033a40ed3dSBarry Smith   PetscFunctionReturn(0);
36049b94acceSBarry Smith }
36059b94acceSBarry Smith 
3606a847f771SSatish Balay 
36079b94acceSBarry Smith /* --------------------------------------------------------------------- */
36084a2ae208SSatish Balay #undef __FUNCT__
36094a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
361052baeb72SSatish Balay /*@
36119b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
3612f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
36139b94acceSBarry Smith 
3614fee21e36SBarry Smith    Not Collective
3615fee21e36SBarry Smith 
361636851e7fSLois Curfman McInnes    Level: advanced
361736851e7fSLois Curfman McInnes 
36189b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
36199b94acceSBarry Smith 
36209b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
36219b94acceSBarry Smith @*/
36227087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
36239b94acceSBarry Smith {
3624dfbe8321SBarry Smith   PetscErrorCode ierr;
362582bf6240SBarry Smith 
36263a40ed3dSBarry Smith   PetscFunctionBegin;
36271441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
36284c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
36293a40ed3dSBarry Smith   PetscFunctionReturn(0);
36309b94acceSBarry Smith }
36319b94acceSBarry Smith 
36324a2ae208SSatish Balay #undef __FUNCT__
36334a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
36349b94acceSBarry Smith /*@C
36359a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
36369b94acceSBarry Smith 
3637c7afd0dbSLois Curfman McInnes    Not Collective
3638c7afd0dbSLois Curfman McInnes 
36399b94acceSBarry Smith    Input Parameter:
36404b0e389bSBarry Smith .  snes - nonlinear solver context
36419b94acceSBarry Smith 
36429b94acceSBarry Smith    Output Parameter:
36433a7fca6bSBarry Smith .  type - SNES method (a character string)
36449b94acceSBarry Smith 
364536851e7fSLois Curfman McInnes    Level: intermediate
364636851e7fSLois Curfman McInnes 
3647454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
36489b94acceSBarry Smith @*/
36497087cfbeSBarry Smith PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
36509b94acceSBarry Smith {
36513a40ed3dSBarry Smith   PetscFunctionBegin;
36520700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36534482741eSBarry Smith   PetscValidPointer(type,2);
36547adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
36553a40ed3dSBarry Smith   PetscFunctionReturn(0);
36569b94acceSBarry Smith }
36579b94acceSBarry Smith 
36584a2ae208SSatish Balay #undef __FUNCT__
36594a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
366052baeb72SSatish Balay /*@
36619b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
3662c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
36639b94acceSBarry Smith 
3664c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3665c7afd0dbSLois Curfman McInnes 
36669b94acceSBarry Smith    Input Parameter:
36679b94acceSBarry Smith .  snes - the SNES context
36689b94acceSBarry Smith 
36699b94acceSBarry Smith    Output Parameter:
36709b94acceSBarry Smith .  x - the solution
36719b94acceSBarry Smith 
367270e92668SMatthew Knepley    Level: intermediate
367336851e7fSLois Curfman McInnes 
36749b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
36759b94acceSBarry Smith 
367685385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
36779b94acceSBarry Smith @*/
36787087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
36799b94acceSBarry Smith {
36803a40ed3dSBarry Smith   PetscFunctionBegin;
36810700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36824482741eSBarry Smith   PetscValidPointer(x,2);
368385385478SLisandro Dalcin   *x = snes->vec_sol;
368470e92668SMatthew Knepley   PetscFunctionReturn(0);
368570e92668SMatthew Knepley }
368670e92668SMatthew Knepley 
368770e92668SMatthew Knepley #undef __FUNCT__
36884a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
368952baeb72SSatish Balay /*@
36909b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
36919b94acceSBarry Smith    stored.
36929b94acceSBarry Smith 
3693c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3694c7afd0dbSLois Curfman McInnes 
36959b94acceSBarry Smith    Input Parameter:
36969b94acceSBarry Smith .  snes - the SNES context
36979b94acceSBarry Smith 
36989b94acceSBarry Smith    Output Parameter:
36999b94acceSBarry Smith .  x - the solution update
37009b94acceSBarry Smith 
370136851e7fSLois Curfman McInnes    Level: advanced
370236851e7fSLois Curfman McInnes 
37039b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
37049b94acceSBarry Smith 
370585385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
37069b94acceSBarry Smith @*/
37077087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
37089b94acceSBarry Smith {
37093a40ed3dSBarry Smith   PetscFunctionBegin;
37100700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37114482741eSBarry Smith   PetscValidPointer(x,2);
371285385478SLisandro Dalcin   *x = snes->vec_sol_update;
37133a40ed3dSBarry Smith   PetscFunctionReturn(0);
37149b94acceSBarry Smith }
37159b94acceSBarry Smith 
37164a2ae208SSatish Balay #undef __FUNCT__
37174a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
37189b94acceSBarry Smith /*@C
37193638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
37209b94acceSBarry Smith 
3721a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
3722c7afd0dbSLois Curfman McInnes 
37239b94acceSBarry Smith    Input Parameter:
37249b94acceSBarry Smith .  snes - the SNES context
37259b94acceSBarry Smith 
37269b94acceSBarry Smith    Output Parameter:
37277bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
372870e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
372970e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
37309b94acceSBarry Smith 
373136851e7fSLois Curfman McInnes    Level: advanced
373236851e7fSLois Curfman McInnes 
3733a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
37349b94acceSBarry Smith 
37354b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
37369b94acceSBarry Smith @*/
37377087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
37389b94acceSBarry Smith {
3739a63bb30eSJed Brown   PetscErrorCode ierr;
37406cab3a1bSJed Brown   DM             dm;
3741a63bb30eSJed Brown 
37423a40ed3dSBarry Smith   PetscFunctionBegin;
37430700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3744a63bb30eSJed Brown   if (r) {
3745a63bb30eSJed Brown     if (!snes->vec_func) {
3746a63bb30eSJed Brown       if (snes->vec_rhs) {
3747a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
3748a63bb30eSJed Brown       } else if (snes->vec_sol) {
3749a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
3750a63bb30eSJed Brown       } else if (snes->dm) {
3751a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
3752a63bb30eSJed Brown       }
3753a63bb30eSJed Brown     }
3754a63bb30eSJed Brown     *r = snes->vec_func;
3755a63bb30eSJed Brown   }
37566cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
37576cab3a1bSJed Brown   ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr);
37583a40ed3dSBarry Smith   PetscFunctionReturn(0);
37599b94acceSBarry Smith }
37609b94acceSBarry Smith 
3761c79ef259SPeter Brune /*@C
3762c79ef259SPeter Brune    SNESGetGS - Returns the GS function and context.
3763c79ef259SPeter Brune 
3764c79ef259SPeter Brune    Input Parameter:
3765c79ef259SPeter Brune .  snes - the SNES context
3766c79ef259SPeter Brune 
3767c79ef259SPeter Brune    Output Parameter:
3768c79ef259SPeter Brune +  gsfunc - the function (or PETSC_NULL)
3769c79ef259SPeter Brune -  ctx    - the function context (or PETSC_NULL)
3770c79ef259SPeter Brune 
3771c79ef259SPeter Brune    Level: advanced
3772c79ef259SPeter Brune 
3773c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
3774c79ef259SPeter Brune 
3775c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction()
3776c79ef259SPeter Brune @*/
3777c79ef259SPeter Brune 
37784a2ae208SSatish Balay #undef __FUNCT__
3779646217ecSPeter Brune #define __FUNCT__ "SNESGetGS"
3780646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx)
3781646217ecSPeter Brune {
37826cab3a1bSJed Brown   PetscErrorCode ierr;
37836cab3a1bSJed Brown   DM             dm;
37846cab3a1bSJed Brown 
3785646217ecSPeter Brune   PetscFunctionBegin;
3786646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37876cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
37886cab3a1bSJed Brown   ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr);
3789646217ecSPeter Brune   PetscFunctionReturn(0);
3790646217ecSPeter Brune }
3791646217ecSPeter Brune 
37924a2ae208SSatish Balay #undef __FUNCT__
37934a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
37943c7409f5SSatish Balay /*@C
37953c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
3796d850072dSLois Curfman McInnes    SNES options in the database.
37973c7409f5SSatish Balay 
37983f9fe445SBarry Smith    Logically Collective on SNES
3799fee21e36SBarry Smith 
3800c7afd0dbSLois Curfman McInnes    Input Parameter:
3801c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3802c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3803c7afd0dbSLois Curfman McInnes 
3804d850072dSLois Curfman McInnes    Notes:
3805a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3806c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3807d850072dSLois Curfman McInnes 
380836851e7fSLois Curfman McInnes    Level: advanced
380936851e7fSLois Curfman McInnes 
38103c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
3811a86d99e1SLois Curfman McInnes 
3812a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
38133c7409f5SSatish Balay @*/
38147087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
38153c7409f5SSatish Balay {
3816dfbe8321SBarry Smith   PetscErrorCode ierr;
38173c7409f5SSatish Balay 
38183a40ed3dSBarry Smith   PetscFunctionBegin;
38190700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3820639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
38211cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
382294b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
38233a40ed3dSBarry Smith   PetscFunctionReturn(0);
38243c7409f5SSatish Balay }
38253c7409f5SSatish Balay 
38264a2ae208SSatish Balay #undef __FUNCT__
38274a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
38283c7409f5SSatish Balay /*@C
3829f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
3830d850072dSLois Curfman McInnes    SNES options in the database.
38313c7409f5SSatish Balay 
38323f9fe445SBarry Smith    Logically Collective on SNES
3833fee21e36SBarry Smith 
3834c7afd0dbSLois Curfman McInnes    Input Parameters:
3835c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3836c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3837c7afd0dbSLois Curfman McInnes 
3838d850072dSLois Curfman McInnes    Notes:
3839a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3840c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3841d850072dSLois Curfman McInnes 
384236851e7fSLois Curfman McInnes    Level: advanced
384336851e7fSLois Curfman McInnes 
38443c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
3845a86d99e1SLois Curfman McInnes 
3846a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
38473c7409f5SSatish Balay @*/
38487087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
38493c7409f5SSatish Balay {
3850dfbe8321SBarry Smith   PetscErrorCode ierr;
38513c7409f5SSatish Balay 
38523a40ed3dSBarry Smith   PetscFunctionBegin;
38530700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3854639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
38551cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
385694b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
38573a40ed3dSBarry Smith   PetscFunctionReturn(0);
38583c7409f5SSatish Balay }
38593c7409f5SSatish Balay 
38604a2ae208SSatish Balay #undef __FUNCT__
38614a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
38629ab63eb5SSatish Balay /*@C
38633c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
38643c7409f5SSatish Balay    SNES options in the database.
38653c7409f5SSatish Balay 
3866c7afd0dbSLois Curfman McInnes    Not Collective
3867c7afd0dbSLois Curfman McInnes 
38683c7409f5SSatish Balay    Input Parameter:
38693c7409f5SSatish Balay .  snes - the SNES context
38703c7409f5SSatish Balay 
38713c7409f5SSatish Balay    Output Parameter:
38723c7409f5SSatish Balay .  prefix - pointer to the prefix string used
38733c7409f5SSatish Balay 
38744ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
38759ab63eb5SSatish Balay    sufficient length to hold the prefix.
38769ab63eb5SSatish Balay 
387736851e7fSLois Curfman McInnes    Level: advanced
387836851e7fSLois Curfman McInnes 
38793c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
3880a86d99e1SLois Curfman McInnes 
3881a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
38823c7409f5SSatish Balay @*/
38837087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
38843c7409f5SSatish Balay {
3885dfbe8321SBarry Smith   PetscErrorCode ierr;
38863c7409f5SSatish Balay 
38873a40ed3dSBarry Smith   PetscFunctionBegin;
38880700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3889639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
38903a40ed3dSBarry Smith   PetscFunctionReturn(0);
38913c7409f5SSatish Balay }
38923c7409f5SSatish Balay 
3893b2002411SLois Curfman McInnes 
38944a2ae208SSatish Balay #undef __FUNCT__
38954a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
38963cea93caSBarry Smith /*@C
38973cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
38983cea93caSBarry Smith 
38997f6c08e0SMatthew Knepley   Level: advanced
39003cea93caSBarry Smith @*/
39017087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
3902b2002411SLois Curfman McInnes {
3903e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
3904dfbe8321SBarry Smith   PetscErrorCode ierr;
3905b2002411SLois Curfman McInnes 
3906b2002411SLois Curfman McInnes   PetscFunctionBegin;
3907b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3908c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3909b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
3910b2002411SLois Curfman McInnes }
3911da9b6338SBarry Smith 
3912da9b6338SBarry Smith #undef __FUNCT__
3913da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
39147087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
3915da9b6338SBarry Smith {
3916dfbe8321SBarry Smith   PetscErrorCode ierr;
391777431f27SBarry Smith   PetscInt       N,i,j;
3918da9b6338SBarry Smith   Vec            u,uh,fh;
3919da9b6338SBarry Smith   PetscScalar    value;
3920da9b6338SBarry Smith   PetscReal      norm;
3921da9b6338SBarry Smith 
3922da9b6338SBarry Smith   PetscFunctionBegin;
3923da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
3924da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
3925da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
3926da9b6338SBarry Smith 
3927da9b6338SBarry Smith   /* currently only works for sequential */
3928da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
3929da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
3930da9b6338SBarry Smith   for (i=0; i<N; i++) {
3931da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
393277431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
3933da9b6338SBarry Smith     for (j=-10; j<11; j++) {
3934ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
3935da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
39363ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
3937da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
393877431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
3939da9b6338SBarry Smith       value = -value;
3940da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
3941da9b6338SBarry Smith     }
3942da9b6338SBarry Smith   }
39436bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
39446bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
3945da9b6338SBarry Smith   PetscFunctionReturn(0);
3946da9b6338SBarry Smith }
394771f87433Sdalcinl 
394871f87433Sdalcinl #undef __FUNCT__
3949fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
395071f87433Sdalcinl /*@
3951fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
395271f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
395371f87433Sdalcinl    Newton method.
395471f87433Sdalcinl 
39553f9fe445SBarry Smith    Logically Collective on SNES
395671f87433Sdalcinl 
395771f87433Sdalcinl    Input Parameters:
395871f87433Sdalcinl +  snes - SNES context
395971f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
396071f87433Sdalcinl 
396164ba62caSBarry Smith     Options Database:
396264ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
396364ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
396464ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
396564ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
396664ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
396764ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
396864ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
396964ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
397064ba62caSBarry Smith 
397171f87433Sdalcinl    Notes:
397271f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
397371f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
397471f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
397571f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
397671f87433Sdalcinl    solver.
397771f87433Sdalcinl 
397871f87433Sdalcinl    Level: advanced
397971f87433Sdalcinl 
398071f87433Sdalcinl    Reference:
398171f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
398271f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
398371f87433Sdalcinl 
398471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
398571f87433Sdalcinl 
3986fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
398771f87433Sdalcinl @*/
39887087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
398971f87433Sdalcinl {
399071f87433Sdalcinl   PetscFunctionBegin;
39910700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3992acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
399371f87433Sdalcinl   snes->ksp_ewconv = flag;
399471f87433Sdalcinl   PetscFunctionReturn(0);
399571f87433Sdalcinl }
399671f87433Sdalcinl 
399771f87433Sdalcinl #undef __FUNCT__
3998fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
399971f87433Sdalcinl /*@
4000fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
400171f87433Sdalcinl    for computing relative tolerance for linear solvers within an
400271f87433Sdalcinl    inexact Newton method.
400371f87433Sdalcinl 
400471f87433Sdalcinl    Not Collective
400571f87433Sdalcinl 
400671f87433Sdalcinl    Input Parameter:
400771f87433Sdalcinl .  snes - SNES context
400871f87433Sdalcinl 
400971f87433Sdalcinl    Output Parameter:
401071f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
401171f87433Sdalcinl 
401271f87433Sdalcinl    Notes:
401371f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
401471f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
401571f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
401671f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
401771f87433Sdalcinl    solver.
401871f87433Sdalcinl 
401971f87433Sdalcinl    Level: advanced
402071f87433Sdalcinl 
402171f87433Sdalcinl    Reference:
402271f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
402371f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
402471f87433Sdalcinl 
402571f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
402671f87433Sdalcinl 
4027fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
402871f87433Sdalcinl @*/
40297087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
403071f87433Sdalcinl {
403171f87433Sdalcinl   PetscFunctionBegin;
40320700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
403371f87433Sdalcinl   PetscValidPointer(flag,2);
403471f87433Sdalcinl   *flag = snes->ksp_ewconv;
403571f87433Sdalcinl   PetscFunctionReturn(0);
403671f87433Sdalcinl }
403771f87433Sdalcinl 
403871f87433Sdalcinl #undef __FUNCT__
4039fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
404071f87433Sdalcinl /*@
4041fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
404271f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
404371f87433Sdalcinl    Newton method.
404471f87433Sdalcinl 
40453f9fe445SBarry Smith    Logically Collective on SNES
404671f87433Sdalcinl 
404771f87433Sdalcinl    Input Parameters:
404871f87433Sdalcinl +    snes - SNES context
404971f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
405071f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
405171f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
405271f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
405371f87433Sdalcinl              (0 <= gamma2 <= 1)
405471f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
405571f87433Sdalcinl .    alpha2 - power for safeguard
405671f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
405771f87433Sdalcinl 
405871f87433Sdalcinl    Note:
405971f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
406071f87433Sdalcinl 
406171f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
406271f87433Sdalcinl 
406371f87433Sdalcinl    Level: advanced
406471f87433Sdalcinl 
406571f87433Sdalcinl    Reference:
406671f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
406771f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
406871f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
406971f87433Sdalcinl 
407071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
407171f87433Sdalcinl 
4072fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
407371f87433Sdalcinl @*/
40747087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
407571f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
407671f87433Sdalcinl {
4077fa9f3622SBarry Smith   SNESKSPEW *kctx;
407871f87433Sdalcinl   PetscFunctionBegin;
40790700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4080fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4081e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
4082c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
4083c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
4084c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
4085c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
4086c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
4087c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
4088c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
408971f87433Sdalcinl 
409071f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
409171f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
409271f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
409371f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
409471f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
409571f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
409671f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
409771f87433Sdalcinl 
409871f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
4099e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
410071f87433Sdalcinl   }
410171f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
4102e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
410371f87433Sdalcinl   }
410471f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
4105e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
410671f87433Sdalcinl   }
410771f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
4108e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
410971f87433Sdalcinl   }
411071f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
4111e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
411271f87433Sdalcinl   }
411371f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
4114e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
411571f87433Sdalcinl   }
411671f87433Sdalcinl   PetscFunctionReturn(0);
411771f87433Sdalcinl }
411871f87433Sdalcinl 
411971f87433Sdalcinl #undef __FUNCT__
4120fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
412171f87433Sdalcinl /*@
4122fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
412371f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
412471f87433Sdalcinl    Newton method.
412571f87433Sdalcinl 
412671f87433Sdalcinl    Not Collective
412771f87433Sdalcinl 
412871f87433Sdalcinl    Input Parameters:
412971f87433Sdalcinl      snes - SNES context
413071f87433Sdalcinl 
413171f87433Sdalcinl    Output Parameters:
413271f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
413371f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
413471f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
413571f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
413671f87433Sdalcinl              (0 <= gamma2 <= 1)
413771f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
413871f87433Sdalcinl .    alpha2 - power for safeguard
413971f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
414071f87433Sdalcinl 
414171f87433Sdalcinl    Level: advanced
414271f87433Sdalcinl 
414371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
414471f87433Sdalcinl 
4145fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
414671f87433Sdalcinl @*/
41477087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
414871f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
414971f87433Sdalcinl {
4150fa9f3622SBarry Smith   SNESKSPEW *kctx;
415171f87433Sdalcinl   PetscFunctionBegin;
41520700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4153fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4154e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
415571f87433Sdalcinl   if(version)   *version   = kctx->version;
415671f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
415771f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
415871f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
415971f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
416071f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
416171f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
416271f87433Sdalcinl   PetscFunctionReturn(0);
416371f87433Sdalcinl }
416471f87433Sdalcinl 
416571f87433Sdalcinl #undef __FUNCT__
4166fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
4167fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
416871f87433Sdalcinl {
416971f87433Sdalcinl   PetscErrorCode ierr;
4170fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
417171f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
417271f87433Sdalcinl 
417371f87433Sdalcinl   PetscFunctionBegin;
4174e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
417571f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
417671f87433Sdalcinl     rtol = kctx->rtol_0;
417771f87433Sdalcinl   } else {
417871f87433Sdalcinl     if (kctx->version == 1) {
417971f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
418071f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
418171f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
418271f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
418371f87433Sdalcinl     } else if (kctx->version == 2) {
418471f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
418571f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
418671f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
418771f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
418871f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
418971f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
419071f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
419171f87433Sdalcinl       stol = PetscMax(rtol,stol);
419271f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
419371f87433Sdalcinl       /* safeguard: avoid oversolving */
419471f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
419571f87433Sdalcinl       stol = PetscMax(rtol,stol);
419671f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
4197e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
419871f87433Sdalcinl   }
419971f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
420071f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
420171f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
420271f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
420371f87433Sdalcinl   PetscFunctionReturn(0);
420471f87433Sdalcinl }
420571f87433Sdalcinl 
420671f87433Sdalcinl #undef __FUNCT__
4207fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
4208fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
420971f87433Sdalcinl {
421071f87433Sdalcinl   PetscErrorCode ierr;
4211fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
421271f87433Sdalcinl   PCSide         pcside;
421371f87433Sdalcinl   Vec            lres;
421471f87433Sdalcinl 
421571f87433Sdalcinl   PetscFunctionBegin;
4216e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
421771f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
421871f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
421971f87433Sdalcinl   if (kctx->version == 1) {
4220b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
422171f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
422271f87433Sdalcinl       /* KSP residual is true linear residual */
422371f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
422471f87433Sdalcinl     } else {
422571f87433Sdalcinl       /* KSP residual is preconditioned residual */
422671f87433Sdalcinl       /* compute true linear residual norm */
422771f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
422871f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
422971f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
423071f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
42316bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
423271f87433Sdalcinl     }
423371f87433Sdalcinl   }
423471f87433Sdalcinl   PetscFunctionReturn(0);
423571f87433Sdalcinl }
423671f87433Sdalcinl 
423771f87433Sdalcinl #undef __FUNCT__
423871f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
423971f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
424071f87433Sdalcinl {
424171f87433Sdalcinl   PetscErrorCode ierr;
424271f87433Sdalcinl 
424371f87433Sdalcinl   PetscFunctionBegin;
4244fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
424571f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
4246fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
424771f87433Sdalcinl   PetscFunctionReturn(0);
424871f87433Sdalcinl }
42496c699258SBarry Smith 
42506c699258SBarry Smith #undef __FUNCT__
42516c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
42526c699258SBarry Smith /*@
42536c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
42546c699258SBarry Smith 
42553f9fe445SBarry Smith    Logically Collective on SNES
42566c699258SBarry Smith 
42576c699258SBarry Smith    Input Parameters:
42586c699258SBarry Smith +  snes - the preconditioner context
42596c699258SBarry Smith -  dm - the dm
42606c699258SBarry Smith 
42616c699258SBarry Smith    Level: intermediate
42626c699258SBarry Smith 
42636c699258SBarry Smith 
42646c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
42656c699258SBarry Smith @*/
42667087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
42676c699258SBarry Smith {
42686c699258SBarry Smith   PetscErrorCode ierr;
4269345fed2cSBarry Smith   KSP            ksp;
42706cab3a1bSJed Brown   SNESDM         sdm;
42716c699258SBarry Smith 
42726c699258SBarry Smith   PetscFunctionBegin;
42730700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4274d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
42756cab3a1bSJed Brown   if (snes->dm) {               /* Move the SNESDM context over to the new DM unless the new DM already has one */
42766cab3a1bSJed Brown     PetscContainer oldcontainer,container;
42776cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr);
42786cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr);
42796cab3a1bSJed Brown     if (oldcontainer && !container) {
42806cab3a1bSJed Brown       ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr);
42816cab3a1bSJed Brown       ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr);
42826cab3a1bSJed Brown       if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */
42836cab3a1bSJed Brown         sdm->originaldm = dm;
42846cab3a1bSJed Brown       }
42856cab3a1bSJed Brown     }
42866bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
42876cab3a1bSJed Brown   }
42886c699258SBarry Smith   snes->dm = dm;
4289345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4290345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4291f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
42922c155ee1SBarry Smith   if (snes->pc) {
42932c155ee1SBarry Smith     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
42942c155ee1SBarry Smith   }
42956c699258SBarry Smith   PetscFunctionReturn(0);
42966c699258SBarry Smith }
42976c699258SBarry Smith 
42986c699258SBarry Smith #undef __FUNCT__
42996c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
43006c699258SBarry Smith /*@
43016c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
43026c699258SBarry Smith 
43033f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
43046c699258SBarry Smith 
43056c699258SBarry Smith    Input Parameter:
43066c699258SBarry Smith . snes - the preconditioner context
43076c699258SBarry Smith 
43086c699258SBarry Smith    Output Parameter:
43096c699258SBarry Smith .  dm - the dm
43106c699258SBarry Smith 
43116c699258SBarry Smith    Level: intermediate
43126c699258SBarry Smith 
43136c699258SBarry Smith 
43146c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
43156c699258SBarry Smith @*/
43167087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
43176c699258SBarry Smith {
43186cab3a1bSJed Brown   PetscErrorCode ierr;
43196cab3a1bSJed Brown 
43206c699258SBarry Smith   PetscFunctionBegin;
43210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
43226cab3a1bSJed Brown   if (!snes->dm) {
43236cab3a1bSJed Brown     ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr);
43246cab3a1bSJed Brown   }
43256c699258SBarry Smith   *dm = snes->dm;
43266c699258SBarry Smith   PetscFunctionReturn(0);
43276c699258SBarry Smith }
43280807856dSBarry Smith 
432931823bd8SMatthew G Knepley #undef __FUNCT__
433031823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
433131823bd8SMatthew G Knepley /*@
4332fd4b34e9SJed Brown   SNESSetPC - Sets the nonlinear preconditioner to be used.
433331823bd8SMatthew G Knepley 
433431823bd8SMatthew G Knepley   Collective on SNES
433531823bd8SMatthew G Knepley 
433631823bd8SMatthew G Knepley   Input Parameters:
433731823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
433831823bd8SMatthew G Knepley - pc   - the preconditioner object
433931823bd8SMatthew G Knepley 
434031823bd8SMatthew G Knepley   Notes:
434131823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
434231823bd8SMatthew G Knepley   to configure it using the API).
434331823bd8SMatthew G Knepley 
434431823bd8SMatthew G Knepley   Level: developer
434531823bd8SMatthew G Knepley 
434631823bd8SMatthew G Knepley .keywords: SNES, set, precondition
434731823bd8SMatthew G Knepley .seealso: SNESGetPC()
434831823bd8SMatthew G Knepley @*/
434931823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
435031823bd8SMatthew G Knepley {
435131823bd8SMatthew G Knepley   PetscErrorCode ierr;
435231823bd8SMatthew G Knepley 
435331823bd8SMatthew G Knepley   PetscFunctionBegin;
435431823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
435531823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
435631823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
435731823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4358bf11d3b6SBarry Smith   ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr);
435931823bd8SMatthew G Knepley   snes->pc = pc;
436031823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
436131823bd8SMatthew G Knepley   PetscFunctionReturn(0);
436231823bd8SMatthew G Knepley }
436331823bd8SMatthew G Knepley 
436431823bd8SMatthew G Knepley #undef __FUNCT__
436531823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
436631823bd8SMatthew G Knepley /*@
4367fd4b34e9SJed Brown   SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().
436831823bd8SMatthew G Knepley 
436931823bd8SMatthew G Knepley   Not Collective
437031823bd8SMatthew G Knepley 
437131823bd8SMatthew G Knepley   Input Parameter:
437231823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
437331823bd8SMatthew G Knepley 
437431823bd8SMatthew G Knepley   Output Parameter:
437531823bd8SMatthew G Knepley . pc - preconditioner context
437631823bd8SMatthew G Knepley 
437731823bd8SMatthew G Knepley   Level: developer
437831823bd8SMatthew G Knepley 
437931823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
438031823bd8SMatthew G Knepley .seealso: SNESSetPC()
438131823bd8SMatthew G Knepley @*/
438231823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
438331823bd8SMatthew G Knepley {
438431823bd8SMatthew G Knepley   PetscErrorCode              ierr;
4385a64e098fSPeter Brune   const char                  *optionsprefix;
438631823bd8SMatthew G Knepley 
438731823bd8SMatthew G Knepley   PetscFunctionBegin;
438831823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
438931823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
439031823bd8SMatthew G Knepley   if (!snes->pc) {
439131823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm,&snes->pc);CHKERRQ(ierr);
43924a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);CHKERRQ(ierr);
439331823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes,snes->pc);CHKERRQ(ierr);
4394a64e098fSPeter Brune     ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr);
4395a64e098fSPeter Brune     ierr = SNESSetOptionsPrefix(snes->pc,optionsprefix);CHKERRQ(ierr);
4396a64e098fSPeter Brune     ierr = SNESAppendOptionsPrefix(snes->pc,"npc_");CHKERRQ(ierr);
439731823bd8SMatthew G Knepley   }
439831823bd8SMatthew G Knepley   *pc = snes->pc;
439931823bd8SMatthew G Knepley   PetscFunctionReturn(0);
440031823bd8SMatthew G Knepley }
440131823bd8SMatthew G Knepley 
44029e764e56SPeter Brune #undef __FUNCT__
4403f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch"
44049e764e56SPeter Brune /*@
44058141a3b9SPeter Brune   SNESSetSNESLineSearch - Sets the linesearch on the SNES instance.
44069e764e56SPeter Brune 
44079e764e56SPeter Brune   Collective on SNES
44089e764e56SPeter Brune 
44099e764e56SPeter Brune   Input Parameters:
44109e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
44119e764e56SPeter Brune - linesearch   - the linesearch object
44129e764e56SPeter Brune 
44139e764e56SPeter Brune   Notes:
4414f1c6b773SPeter Brune   Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example,
44159e764e56SPeter Brune   to configure it using the API).
44169e764e56SPeter Brune 
44179e764e56SPeter Brune   Level: developer
44189e764e56SPeter Brune 
44199e764e56SPeter Brune .keywords: SNES, set, linesearch
4420f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch()
44219e764e56SPeter Brune @*/
4422f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch)
44239e764e56SPeter Brune {
44249e764e56SPeter Brune   PetscErrorCode ierr;
44259e764e56SPeter Brune 
44269e764e56SPeter Brune   PetscFunctionBegin;
44279e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4428f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
44299e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
44309e764e56SPeter Brune   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
4431f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
44329e764e56SPeter Brune   snes->linesearch = linesearch;
44339e764e56SPeter Brune   ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
44349e764e56SPeter Brune   PetscFunctionReturn(0);
44359e764e56SPeter Brune }
44369e764e56SPeter Brune 
44379e764e56SPeter Brune #undef __FUNCT__
4438f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch"
4439ea5d4fccSPeter Brune /*@C
44408141a3b9SPeter Brune   SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch()
44418141a3b9SPeter Brune   or creates a default line search instance associated with the SNES and returns it.
44429e764e56SPeter Brune 
44439e764e56SPeter Brune   Not Collective
44449e764e56SPeter Brune 
44459e764e56SPeter Brune   Input Parameter:
44469e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
44479e764e56SPeter Brune 
44489e764e56SPeter Brune   Output Parameter:
44499e764e56SPeter Brune . linesearch - linesearch context
44509e764e56SPeter Brune 
44519e764e56SPeter Brune   Level: developer
44529e764e56SPeter Brune 
44539e764e56SPeter Brune .keywords: SNES, get, linesearch
4454f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch()
44559e764e56SPeter Brune @*/
4456f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch)
44579e764e56SPeter Brune {
44589e764e56SPeter Brune   PetscErrorCode ierr;
44599e764e56SPeter Brune   const char     *optionsprefix;
44609e764e56SPeter Brune 
44619e764e56SPeter Brune   PetscFunctionBegin;
44629e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
44639e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
44649e764e56SPeter Brune   if (!snes->linesearch) {
44659e764e56SPeter Brune     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
4466f1c6b773SPeter Brune     ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr);
4467f1c6b773SPeter Brune     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
4468b1dca40bSPeter Brune     ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr);
44699e764e56SPeter Brune     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
44709e764e56SPeter Brune     ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
44719e764e56SPeter Brune   }
44729e764e56SPeter Brune   *linesearch = snes->linesearch;
44739e764e56SPeter Brune   PetscFunctionReturn(0);
44749e764e56SPeter Brune }
44759e764e56SPeter Brune 
447669b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4477c6db04a5SJed Brown #include <mex.h>
447869b4f73cSBarry Smith 
44798f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
44808f6e6473SBarry Smith 
44810807856dSBarry Smith #undef __FUNCT__
44820807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
44830807856dSBarry Smith /*
44840807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
44850807856dSBarry Smith                          SNESSetFunctionMatlab().
44860807856dSBarry Smith 
44870807856dSBarry Smith    Collective on SNES
44880807856dSBarry Smith 
44890807856dSBarry Smith    Input Parameters:
44900807856dSBarry Smith +  snes - the SNES context
44910807856dSBarry Smith -  x - input vector
44920807856dSBarry Smith 
44930807856dSBarry Smith    Output Parameter:
44940807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
44950807856dSBarry Smith 
44960807856dSBarry Smith    Notes:
44970807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
44980807856dSBarry Smith    implementations, so most users would not generally call this routine
44990807856dSBarry Smith    themselves.
45000807856dSBarry Smith 
45010807856dSBarry Smith    Level: developer
45020807856dSBarry Smith 
45030807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
45040807856dSBarry Smith 
45050807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
450661b2408cSBarry Smith */
45077087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
45080807856dSBarry Smith {
4509e650e774SBarry Smith   PetscErrorCode    ierr;
45108f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
45118f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
45128f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
451391621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
4514e650e774SBarry Smith 
45150807856dSBarry Smith   PetscFunctionBegin;
45160807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
45170807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
45180807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
45190807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
45200807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
45210807856dSBarry Smith 
45220807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
4523e650e774SBarry Smith 
452491621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4525e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4526e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
452791621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
452891621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
452991621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
45308f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
45318f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
4532b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
4533e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4534e650e774SBarry Smith   mxDestroyArray(prhs[0]);
4535e650e774SBarry Smith   mxDestroyArray(prhs[1]);
4536e650e774SBarry Smith   mxDestroyArray(prhs[2]);
45378f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
4538e650e774SBarry Smith   mxDestroyArray(plhs[0]);
45390807856dSBarry Smith   PetscFunctionReturn(0);
45400807856dSBarry Smith }
45410807856dSBarry Smith 
45420807856dSBarry Smith 
45430807856dSBarry Smith #undef __FUNCT__
45440807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
454561b2408cSBarry Smith /*
45460807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
45470807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4548e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
45490807856dSBarry Smith 
45500807856dSBarry Smith    Logically Collective on SNES
45510807856dSBarry Smith 
45520807856dSBarry Smith    Input Parameters:
45530807856dSBarry Smith +  snes - the SNES context
45540807856dSBarry Smith .  r - vector to store function value
45550807856dSBarry Smith -  func - function evaluation routine
45560807856dSBarry Smith 
45570807856dSBarry Smith    Calling sequence of func:
455861b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
45590807856dSBarry Smith 
45600807856dSBarry Smith 
45610807856dSBarry Smith    Notes:
45620807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
45630807856dSBarry Smith $      f'(x) x = -f(x),
45640807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
45650807856dSBarry Smith 
45660807856dSBarry Smith    Level: beginner
45670807856dSBarry Smith 
45680807856dSBarry Smith .keywords: SNES, nonlinear, set, function
45690807856dSBarry Smith 
45700807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
457161b2408cSBarry Smith */
45727087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
45730807856dSBarry Smith {
45740807856dSBarry Smith   PetscErrorCode    ierr;
45758f6e6473SBarry Smith   SNESMatlabContext *sctx;
45760807856dSBarry Smith 
45770807856dSBarry Smith   PetscFunctionBegin;
45788f6e6473SBarry Smith   /* currently sctx is memory bleed */
45798f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
45808f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
45818f6e6473SBarry Smith   /*
45828f6e6473SBarry Smith      This should work, but it doesn't
45838f6e6473SBarry Smith   sctx->ctx = ctx;
45848f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
45858f6e6473SBarry Smith   */
45868f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
45878f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
45880807856dSBarry Smith   PetscFunctionReturn(0);
45890807856dSBarry Smith }
459069b4f73cSBarry Smith 
459161b2408cSBarry Smith #undef __FUNCT__
459261b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
459361b2408cSBarry Smith /*
459461b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
459561b2408cSBarry Smith                          SNESSetJacobianMatlab().
459661b2408cSBarry Smith 
459761b2408cSBarry Smith    Collective on SNES
459861b2408cSBarry Smith 
459961b2408cSBarry Smith    Input Parameters:
460061b2408cSBarry Smith +  snes - the SNES context
460161b2408cSBarry Smith .  x - input vector
460261b2408cSBarry Smith .  A, B - the matrices
460361b2408cSBarry Smith -  ctx - user context
460461b2408cSBarry Smith 
460561b2408cSBarry Smith    Output Parameter:
460661b2408cSBarry Smith .  flag - structure of the matrix
460761b2408cSBarry Smith 
460861b2408cSBarry Smith    Level: developer
460961b2408cSBarry Smith 
461061b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
461161b2408cSBarry Smith 
461261b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
461361b2408cSBarry Smith @*/
46147087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
461561b2408cSBarry Smith {
461661b2408cSBarry Smith   PetscErrorCode    ierr;
461761b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
461861b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
461961b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
462061b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
462161b2408cSBarry Smith 
462261b2408cSBarry Smith   PetscFunctionBegin;
462361b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
462461b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
462561b2408cSBarry Smith 
462661b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
462761b2408cSBarry Smith 
462861b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
462961b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
463061b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
463161b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
463261b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
463361b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
463461b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
463561b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
463661b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
463761b2408cSBarry Smith   prhs[5] =  sctx->ctx;
4638b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
463961b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
464061b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
464161b2408cSBarry Smith   mxDestroyArray(prhs[0]);
464261b2408cSBarry Smith   mxDestroyArray(prhs[1]);
464361b2408cSBarry Smith   mxDestroyArray(prhs[2]);
464461b2408cSBarry Smith   mxDestroyArray(prhs[3]);
464561b2408cSBarry Smith   mxDestroyArray(prhs[4]);
464661b2408cSBarry Smith   mxDestroyArray(plhs[0]);
464761b2408cSBarry Smith   mxDestroyArray(plhs[1]);
464861b2408cSBarry Smith   PetscFunctionReturn(0);
464961b2408cSBarry Smith }
465061b2408cSBarry Smith 
465161b2408cSBarry Smith 
465261b2408cSBarry Smith #undef __FUNCT__
465361b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
465461b2408cSBarry Smith /*
465561b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
465661b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4657e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
465861b2408cSBarry Smith 
465961b2408cSBarry Smith    Logically Collective on SNES
466061b2408cSBarry Smith 
466161b2408cSBarry Smith    Input Parameters:
466261b2408cSBarry Smith +  snes - the SNES context
466361b2408cSBarry Smith .  A,B - Jacobian matrices
466461b2408cSBarry Smith .  func - function evaluation routine
466561b2408cSBarry Smith -  ctx - user context
466661b2408cSBarry Smith 
466761b2408cSBarry Smith    Calling sequence of func:
466861b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
466961b2408cSBarry Smith 
467061b2408cSBarry Smith 
467161b2408cSBarry Smith    Level: developer
467261b2408cSBarry Smith 
467361b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
467461b2408cSBarry Smith 
467561b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
467661b2408cSBarry Smith */
46777087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
467861b2408cSBarry Smith {
467961b2408cSBarry Smith   PetscErrorCode    ierr;
468061b2408cSBarry Smith   SNESMatlabContext *sctx;
468161b2408cSBarry Smith 
468261b2408cSBarry Smith   PetscFunctionBegin;
468361b2408cSBarry Smith   /* currently sctx is memory bleed */
468461b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
468561b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
468661b2408cSBarry Smith   /*
468761b2408cSBarry Smith      This should work, but it doesn't
468861b2408cSBarry Smith   sctx->ctx = ctx;
468961b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
469061b2408cSBarry Smith   */
469161b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
469261b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
469361b2408cSBarry Smith   PetscFunctionReturn(0);
469461b2408cSBarry Smith }
469569b4f73cSBarry Smith 
4696f9eb7ae2SShri Abhyankar #undef __FUNCT__
4697f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
4698f9eb7ae2SShri Abhyankar /*
4699f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
4700f9eb7ae2SShri Abhyankar 
4701f9eb7ae2SShri Abhyankar    Collective on SNES
4702f9eb7ae2SShri Abhyankar 
4703f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
4704f9eb7ae2SShri Abhyankar @*/
47057087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
4706f9eb7ae2SShri Abhyankar {
4707f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
470848f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
4709f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
4710f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
4711f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
4712f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
4713f9eb7ae2SShri Abhyankar 
4714f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4715f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4716f9eb7ae2SShri Abhyankar 
4717f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4718f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4719f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
4720f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
4721f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
4722f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
4723f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
4724f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
4725f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
4726f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4727f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
4728f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
4729f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
4730f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
4731f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
4732f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
4733f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4734f9eb7ae2SShri Abhyankar }
4735f9eb7ae2SShri Abhyankar 
4736f9eb7ae2SShri Abhyankar 
4737f9eb7ae2SShri Abhyankar #undef __FUNCT__
4738f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
4739f9eb7ae2SShri Abhyankar /*
4740e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
4741f9eb7ae2SShri Abhyankar 
4742f9eb7ae2SShri Abhyankar    Level: developer
4743f9eb7ae2SShri Abhyankar 
4744f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
4745f9eb7ae2SShri Abhyankar 
4746f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
4747f9eb7ae2SShri Abhyankar */
47487087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
4749f9eb7ae2SShri Abhyankar {
4750f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
4751f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
4752f9eb7ae2SShri Abhyankar 
4753f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4754f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
4755f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
4756f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4757f9eb7ae2SShri Abhyankar   /*
4758f9eb7ae2SShri Abhyankar      This should work, but it doesn't
4759f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
4760f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
4761f9eb7ae2SShri Abhyankar   */
4762f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
4763f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4764f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4765f9eb7ae2SShri Abhyankar }
4766f9eb7ae2SShri Abhyankar 
476769b4f73cSBarry Smith #endif
4768