xref: /petsc/src/snes/interface/snes.c (revision 17842b4f1bb08bf56fc24f250590a405b343fd7f)
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) {
398*17842b4fSJed 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 
34697adad957SLisandro Dalcin     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
3470eabae89aSBarry Smith     if (flg && !PetscPreLoadingOn) {
34717adad957SLisandro Dalcin       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
3472eabae89aSBarry Smith       ierr = SNESView(snes,viewer);CHKERRQ(ierr);
34736bf464f9SBarry Smith       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3474eabae89aSBarry Smith     }
3475eabae89aSBarry Smith 
347690d69ab7SBarry Smith     flg  = PETSC_FALSE;
3477acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
3478da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
34795968eb51SBarry Smith     if (snes->printreason) {
3480a8248277SBarry Smith       ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
34815968eb51SBarry Smith       if (snes->reason > 0) {
3482c7e7b494SJed 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);
34835968eb51SBarry Smith       } else {
3484c7e7b494SJed 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);
34855968eb51SBarry Smith       }
3486a8248277SBarry Smith       ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
34875968eb51SBarry Smith     }
34885968eb51SBarry Smith 
34898501fc72SJed Brown     flg = PETSC_FALSE;
34908501fc72SJed Brown     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
34918501fc72SJed Brown     if (flg) {
34928501fc72SJed Brown       PetscViewer viewer;
34938501fc72SJed Brown       ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
34948501fc72SJed Brown       ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr);
34958501fc72SJed Brown       ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr);
34968501fc72SJed Brown       ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr);
34978501fc72SJed Brown       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
34988501fc72SJed Brown     }
34998501fc72SJed Brown 
3500e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
3501efd51863SBarry Smith     if (grid <  snes->gridsequence) {
3502efd51863SBarry Smith       DM  fine;
3503efd51863SBarry Smith       Vec xnew;
3504efd51863SBarry Smith       Mat interp;
3505efd51863SBarry Smith 
3506efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
3507c5c77316SJed Brown       if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
3508e727c939SJed Brown       ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
3509efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
3510efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
3511c833c3b5SJed Brown       ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr);
3512efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
3513efd51863SBarry Smith       x    = xnew;
3514efd51863SBarry Smith 
3515efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
3516efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
3517efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
3518a8248277SBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);
3519efd51863SBarry Smith     }
3520efd51863SBarry Smith   }
3521a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
35223a40ed3dSBarry Smith   PetscFunctionReturn(0);
35239b94acceSBarry Smith }
35249b94acceSBarry Smith 
35259b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
35269b94acceSBarry Smith 
35274a2ae208SSatish Balay #undef __FUNCT__
35284a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
352982bf6240SBarry Smith /*@C
35304b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
35319b94acceSBarry Smith 
3532fee21e36SBarry Smith    Collective on SNES
3533fee21e36SBarry Smith 
3534c7afd0dbSLois Curfman McInnes    Input Parameters:
3535c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3536454a90a3SBarry Smith -  type - a known method
3537c7afd0dbSLois Curfman McInnes 
3538c7afd0dbSLois Curfman McInnes    Options Database Key:
3539454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
3540c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
3541ae12b187SLois Curfman McInnes 
35429b94acceSBarry Smith    Notes:
3543e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
35444b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
3545c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
35464b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
3547c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
35489b94acceSBarry Smith 
3549ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
3550ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
3551ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
3552ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
3553ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
3554ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
3555ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
3556ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
3557ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
3558b0a32e0cSBarry Smith   appropriate method.
355936851e7fSLois Curfman McInnes 
356036851e7fSLois Curfman McInnes   Level: intermediate
3561a703fe33SLois Curfman McInnes 
3562454a90a3SBarry Smith .keywords: SNES, set, type
3563435da068SBarry Smith 
3564435da068SBarry Smith .seealso: SNESType, SNESCreate()
3565435da068SBarry Smith 
35669b94acceSBarry Smith @*/
35677087cfbeSBarry Smith PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
35689b94acceSBarry Smith {
3569dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
3570ace3abfcSBarry Smith   PetscBool      match;
35713a40ed3dSBarry Smith 
35723a40ed3dSBarry Smith   PetscFunctionBegin;
35730700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35744482741eSBarry Smith   PetscValidCharPointer(type,2);
357582bf6240SBarry Smith 
3576251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
35770f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
357892ff6ae8SBarry Smith 
35794b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
3580e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
358175396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
3582b5c23020SJed Brown   if (snes->ops->destroy) {
3583b5c23020SJed Brown     ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
3584b5c23020SJed Brown     snes->ops->destroy = PETSC_NULL;
3585b5c23020SJed Brown   }
358675396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
358775396ef9SLisandro Dalcin   snes->ops->setup          = 0;
358875396ef9SLisandro Dalcin   snes->ops->solve          = 0;
358975396ef9SLisandro Dalcin   snes->ops->view           = 0;
359075396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
359175396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
359275396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
359375396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
3594454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
359503bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
35969fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
35979fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
35989fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
35999fb22e1aSBarry Smith   }
36009fb22e1aSBarry Smith #endif
36013a40ed3dSBarry Smith   PetscFunctionReturn(0);
36029b94acceSBarry Smith }
36039b94acceSBarry Smith 
3604a847f771SSatish Balay 
36059b94acceSBarry Smith /* --------------------------------------------------------------------- */
36064a2ae208SSatish Balay #undef __FUNCT__
36074a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
360852baeb72SSatish Balay /*@
36099b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
3610f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
36119b94acceSBarry Smith 
3612fee21e36SBarry Smith    Not Collective
3613fee21e36SBarry Smith 
361436851e7fSLois Curfman McInnes    Level: advanced
361536851e7fSLois Curfman McInnes 
36169b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
36179b94acceSBarry Smith 
36189b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
36199b94acceSBarry Smith @*/
36207087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
36219b94acceSBarry Smith {
3622dfbe8321SBarry Smith   PetscErrorCode ierr;
362382bf6240SBarry Smith 
36243a40ed3dSBarry Smith   PetscFunctionBegin;
36251441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
36264c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
36273a40ed3dSBarry Smith   PetscFunctionReturn(0);
36289b94acceSBarry Smith }
36299b94acceSBarry Smith 
36304a2ae208SSatish Balay #undef __FUNCT__
36314a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
36329b94acceSBarry Smith /*@C
36339a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
36349b94acceSBarry Smith 
3635c7afd0dbSLois Curfman McInnes    Not Collective
3636c7afd0dbSLois Curfman McInnes 
36379b94acceSBarry Smith    Input Parameter:
36384b0e389bSBarry Smith .  snes - nonlinear solver context
36399b94acceSBarry Smith 
36409b94acceSBarry Smith    Output Parameter:
36413a7fca6bSBarry Smith .  type - SNES method (a character string)
36429b94acceSBarry Smith 
364336851e7fSLois Curfman McInnes    Level: intermediate
364436851e7fSLois Curfman McInnes 
3645454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
36469b94acceSBarry Smith @*/
36477087cfbeSBarry Smith PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
36489b94acceSBarry Smith {
36493a40ed3dSBarry Smith   PetscFunctionBegin;
36500700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36514482741eSBarry Smith   PetscValidPointer(type,2);
36527adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
36533a40ed3dSBarry Smith   PetscFunctionReturn(0);
36549b94acceSBarry Smith }
36559b94acceSBarry Smith 
36564a2ae208SSatish Balay #undef __FUNCT__
36574a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
365852baeb72SSatish Balay /*@
36599b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
3660c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
36619b94acceSBarry Smith 
3662c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3663c7afd0dbSLois Curfman McInnes 
36649b94acceSBarry Smith    Input Parameter:
36659b94acceSBarry Smith .  snes - the SNES context
36669b94acceSBarry Smith 
36679b94acceSBarry Smith    Output Parameter:
36689b94acceSBarry Smith .  x - the solution
36699b94acceSBarry Smith 
367070e92668SMatthew Knepley    Level: intermediate
367136851e7fSLois Curfman McInnes 
36729b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
36739b94acceSBarry Smith 
367485385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
36759b94acceSBarry Smith @*/
36767087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
36779b94acceSBarry Smith {
36783a40ed3dSBarry Smith   PetscFunctionBegin;
36790700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36804482741eSBarry Smith   PetscValidPointer(x,2);
368185385478SLisandro Dalcin   *x = snes->vec_sol;
368270e92668SMatthew Knepley   PetscFunctionReturn(0);
368370e92668SMatthew Knepley }
368470e92668SMatthew Knepley 
368570e92668SMatthew Knepley #undef __FUNCT__
36864a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
368752baeb72SSatish Balay /*@
36889b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
36899b94acceSBarry Smith    stored.
36909b94acceSBarry Smith 
3691c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3692c7afd0dbSLois Curfman McInnes 
36939b94acceSBarry Smith    Input Parameter:
36949b94acceSBarry Smith .  snes - the SNES context
36959b94acceSBarry Smith 
36969b94acceSBarry Smith    Output Parameter:
36979b94acceSBarry Smith .  x - the solution update
36989b94acceSBarry Smith 
369936851e7fSLois Curfman McInnes    Level: advanced
370036851e7fSLois Curfman McInnes 
37019b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
37029b94acceSBarry Smith 
370385385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
37049b94acceSBarry Smith @*/
37057087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
37069b94acceSBarry Smith {
37073a40ed3dSBarry Smith   PetscFunctionBegin;
37080700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37094482741eSBarry Smith   PetscValidPointer(x,2);
371085385478SLisandro Dalcin   *x = snes->vec_sol_update;
37113a40ed3dSBarry Smith   PetscFunctionReturn(0);
37129b94acceSBarry Smith }
37139b94acceSBarry Smith 
37144a2ae208SSatish Balay #undef __FUNCT__
37154a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
37169b94acceSBarry Smith /*@C
37173638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
37189b94acceSBarry Smith 
3719a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
3720c7afd0dbSLois Curfman McInnes 
37219b94acceSBarry Smith    Input Parameter:
37229b94acceSBarry Smith .  snes - the SNES context
37239b94acceSBarry Smith 
37249b94acceSBarry Smith    Output Parameter:
37257bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
372670e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
372770e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
37289b94acceSBarry Smith 
372936851e7fSLois Curfman McInnes    Level: advanced
373036851e7fSLois Curfman McInnes 
3731a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
37329b94acceSBarry Smith 
37334b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
37349b94acceSBarry Smith @*/
37357087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
37369b94acceSBarry Smith {
3737a63bb30eSJed Brown   PetscErrorCode ierr;
37386cab3a1bSJed Brown   DM             dm;
3739a63bb30eSJed Brown 
37403a40ed3dSBarry Smith   PetscFunctionBegin;
37410700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3742a63bb30eSJed Brown   if (r) {
3743a63bb30eSJed Brown     if (!snes->vec_func) {
3744a63bb30eSJed Brown       if (snes->vec_rhs) {
3745a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
3746a63bb30eSJed Brown       } else if (snes->vec_sol) {
3747a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
3748a63bb30eSJed Brown       } else if (snes->dm) {
3749a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
3750a63bb30eSJed Brown       }
3751a63bb30eSJed Brown     }
3752a63bb30eSJed Brown     *r = snes->vec_func;
3753a63bb30eSJed Brown   }
37546cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
37556cab3a1bSJed Brown   ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr);
37563a40ed3dSBarry Smith   PetscFunctionReturn(0);
37579b94acceSBarry Smith }
37589b94acceSBarry Smith 
3759c79ef259SPeter Brune /*@C
3760c79ef259SPeter Brune    SNESGetGS - Returns the GS function and context.
3761c79ef259SPeter Brune 
3762c79ef259SPeter Brune    Input Parameter:
3763c79ef259SPeter Brune .  snes - the SNES context
3764c79ef259SPeter Brune 
3765c79ef259SPeter Brune    Output Parameter:
3766c79ef259SPeter Brune +  gsfunc - the function (or PETSC_NULL)
3767c79ef259SPeter Brune -  ctx    - the function context (or PETSC_NULL)
3768c79ef259SPeter Brune 
3769c79ef259SPeter Brune    Level: advanced
3770c79ef259SPeter Brune 
3771c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
3772c79ef259SPeter Brune 
3773c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction()
3774c79ef259SPeter Brune @*/
3775c79ef259SPeter Brune 
37764a2ae208SSatish Balay #undef __FUNCT__
3777646217ecSPeter Brune #define __FUNCT__ "SNESGetGS"
3778646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx)
3779646217ecSPeter Brune {
37806cab3a1bSJed Brown   PetscErrorCode ierr;
37816cab3a1bSJed Brown   DM             dm;
37826cab3a1bSJed Brown 
3783646217ecSPeter Brune   PetscFunctionBegin;
3784646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37856cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
37866cab3a1bSJed Brown   ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr);
3787646217ecSPeter Brune   PetscFunctionReturn(0);
3788646217ecSPeter Brune }
3789646217ecSPeter Brune 
37904a2ae208SSatish Balay #undef __FUNCT__
37914a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
37923c7409f5SSatish Balay /*@C
37933c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
3794d850072dSLois Curfman McInnes    SNES options in the database.
37953c7409f5SSatish Balay 
37963f9fe445SBarry Smith    Logically Collective on SNES
3797fee21e36SBarry Smith 
3798c7afd0dbSLois Curfman McInnes    Input Parameter:
3799c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3800c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3801c7afd0dbSLois Curfman McInnes 
3802d850072dSLois Curfman McInnes    Notes:
3803a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3804c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3805d850072dSLois Curfman McInnes 
380636851e7fSLois Curfman McInnes    Level: advanced
380736851e7fSLois Curfman McInnes 
38083c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
3809a86d99e1SLois Curfman McInnes 
3810a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
38113c7409f5SSatish Balay @*/
38127087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
38133c7409f5SSatish Balay {
3814dfbe8321SBarry Smith   PetscErrorCode ierr;
38153c7409f5SSatish Balay 
38163a40ed3dSBarry Smith   PetscFunctionBegin;
38170700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3818639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
38191cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
382094b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
38213a40ed3dSBarry Smith   PetscFunctionReturn(0);
38223c7409f5SSatish Balay }
38233c7409f5SSatish Balay 
38244a2ae208SSatish Balay #undef __FUNCT__
38254a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
38263c7409f5SSatish Balay /*@C
3827f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
3828d850072dSLois Curfman McInnes    SNES options in the database.
38293c7409f5SSatish Balay 
38303f9fe445SBarry Smith    Logically Collective on SNES
3831fee21e36SBarry Smith 
3832c7afd0dbSLois Curfman McInnes    Input Parameters:
3833c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3834c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3835c7afd0dbSLois Curfman McInnes 
3836d850072dSLois Curfman McInnes    Notes:
3837a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3838c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3839d850072dSLois Curfman McInnes 
384036851e7fSLois Curfman McInnes    Level: advanced
384136851e7fSLois Curfman McInnes 
38423c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
3843a86d99e1SLois Curfman McInnes 
3844a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
38453c7409f5SSatish Balay @*/
38467087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
38473c7409f5SSatish Balay {
3848dfbe8321SBarry Smith   PetscErrorCode ierr;
38493c7409f5SSatish Balay 
38503a40ed3dSBarry Smith   PetscFunctionBegin;
38510700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3852639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
38531cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
385494b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
38553a40ed3dSBarry Smith   PetscFunctionReturn(0);
38563c7409f5SSatish Balay }
38573c7409f5SSatish Balay 
38584a2ae208SSatish Balay #undef __FUNCT__
38594a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
38609ab63eb5SSatish Balay /*@C
38613c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
38623c7409f5SSatish Balay    SNES options in the database.
38633c7409f5SSatish Balay 
3864c7afd0dbSLois Curfman McInnes    Not Collective
3865c7afd0dbSLois Curfman McInnes 
38663c7409f5SSatish Balay    Input Parameter:
38673c7409f5SSatish Balay .  snes - the SNES context
38683c7409f5SSatish Balay 
38693c7409f5SSatish Balay    Output Parameter:
38703c7409f5SSatish Balay .  prefix - pointer to the prefix string used
38713c7409f5SSatish Balay 
38724ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
38739ab63eb5SSatish Balay    sufficient length to hold the prefix.
38749ab63eb5SSatish Balay 
387536851e7fSLois Curfman McInnes    Level: advanced
387636851e7fSLois Curfman McInnes 
38773c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
3878a86d99e1SLois Curfman McInnes 
3879a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
38803c7409f5SSatish Balay @*/
38817087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
38823c7409f5SSatish Balay {
3883dfbe8321SBarry Smith   PetscErrorCode ierr;
38843c7409f5SSatish Balay 
38853a40ed3dSBarry Smith   PetscFunctionBegin;
38860700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3887639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
38883a40ed3dSBarry Smith   PetscFunctionReturn(0);
38893c7409f5SSatish Balay }
38903c7409f5SSatish Balay 
3891b2002411SLois Curfman McInnes 
38924a2ae208SSatish Balay #undef __FUNCT__
38934a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
38943cea93caSBarry Smith /*@C
38953cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
38963cea93caSBarry Smith 
38977f6c08e0SMatthew Knepley   Level: advanced
38983cea93caSBarry Smith @*/
38997087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
3900b2002411SLois Curfman McInnes {
3901e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
3902dfbe8321SBarry Smith   PetscErrorCode ierr;
3903b2002411SLois Curfman McInnes 
3904b2002411SLois Curfman McInnes   PetscFunctionBegin;
3905b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3906c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3907b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
3908b2002411SLois Curfman McInnes }
3909da9b6338SBarry Smith 
3910da9b6338SBarry Smith #undef __FUNCT__
3911da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
39127087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
3913da9b6338SBarry Smith {
3914dfbe8321SBarry Smith   PetscErrorCode ierr;
391577431f27SBarry Smith   PetscInt       N,i,j;
3916da9b6338SBarry Smith   Vec            u,uh,fh;
3917da9b6338SBarry Smith   PetscScalar    value;
3918da9b6338SBarry Smith   PetscReal      norm;
3919da9b6338SBarry Smith 
3920da9b6338SBarry Smith   PetscFunctionBegin;
3921da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
3922da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
3923da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
3924da9b6338SBarry Smith 
3925da9b6338SBarry Smith   /* currently only works for sequential */
3926da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
3927da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
3928da9b6338SBarry Smith   for (i=0; i<N; i++) {
3929da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
393077431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
3931da9b6338SBarry Smith     for (j=-10; j<11; j++) {
3932ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
3933da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
39343ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
3935da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
393677431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
3937da9b6338SBarry Smith       value = -value;
3938da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
3939da9b6338SBarry Smith     }
3940da9b6338SBarry Smith   }
39416bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
39426bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
3943da9b6338SBarry Smith   PetscFunctionReturn(0);
3944da9b6338SBarry Smith }
394571f87433Sdalcinl 
394671f87433Sdalcinl #undef __FUNCT__
3947fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
394871f87433Sdalcinl /*@
3949fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
395071f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
395171f87433Sdalcinl    Newton method.
395271f87433Sdalcinl 
39533f9fe445SBarry Smith    Logically Collective on SNES
395471f87433Sdalcinl 
395571f87433Sdalcinl    Input Parameters:
395671f87433Sdalcinl +  snes - SNES context
395771f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
395871f87433Sdalcinl 
395964ba62caSBarry Smith     Options Database:
396064ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
396164ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
396264ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
396364ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
396464ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
396564ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
396664ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
396764ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
396864ba62caSBarry Smith 
396971f87433Sdalcinl    Notes:
397071f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
397171f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
397271f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
397371f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
397471f87433Sdalcinl    solver.
397571f87433Sdalcinl 
397671f87433Sdalcinl    Level: advanced
397771f87433Sdalcinl 
397871f87433Sdalcinl    Reference:
397971f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
398071f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
398171f87433Sdalcinl 
398271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
398371f87433Sdalcinl 
3984fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
398571f87433Sdalcinl @*/
39867087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
398771f87433Sdalcinl {
398871f87433Sdalcinl   PetscFunctionBegin;
39890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3990acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
399171f87433Sdalcinl   snes->ksp_ewconv = flag;
399271f87433Sdalcinl   PetscFunctionReturn(0);
399371f87433Sdalcinl }
399471f87433Sdalcinl 
399571f87433Sdalcinl #undef __FUNCT__
3996fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
399771f87433Sdalcinl /*@
3998fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
399971f87433Sdalcinl    for computing relative tolerance for linear solvers within an
400071f87433Sdalcinl    inexact Newton method.
400171f87433Sdalcinl 
400271f87433Sdalcinl    Not Collective
400371f87433Sdalcinl 
400471f87433Sdalcinl    Input Parameter:
400571f87433Sdalcinl .  snes - SNES context
400671f87433Sdalcinl 
400771f87433Sdalcinl    Output Parameter:
400871f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
400971f87433Sdalcinl 
401071f87433Sdalcinl    Notes:
401171f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
401271f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
401371f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
401471f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
401571f87433Sdalcinl    solver.
401671f87433Sdalcinl 
401771f87433Sdalcinl    Level: advanced
401871f87433Sdalcinl 
401971f87433Sdalcinl    Reference:
402071f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
402171f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
402271f87433Sdalcinl 
402371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
402471f87433Sdalcinl 
4025fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
402671f87433Sdalcinl @*/
40277087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
402871f87433Sdalcinl {
402971f87433Sdalcinl   PetscFunctionBegin;
40300700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
403171f87433Sdalcinl   PetscValidPointer(flag,2);
403271f87433Sdalcinl   *flag = snes->ksp_ewconv;
403371f87433Sdalcinl   PetscFunctionReturn(0);
403471f87433Sdalcinl }
403571f87433Sdalcinl 
403671f87433Sdalcinl #undef __FUNCT__
4037fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
403871f87433Sdalcinl /*@
4039fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
404071f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
404171f87433Sdalcinl    Newton method.
404271f87433Sdalcinl 
40433f9fe445SBarry Smith    Logically Collective on SNES
404471f87433Sdalcinl 
404571f87433Sdalcinl    Input Parameters:
404671f87433Sdalcinl +    snes - SNES context
404771f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
404871f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
404971f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
405071f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
405171f87433Sdalcinl              (0 <= gamma2 <= 1)
405271f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
405371f87433Sdalcinl .    alpha2 - power for safeguard
405471f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
405571f87433Sdalcinl 
405671f87433Sdalcinl    Note:
405771f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
405871f87433Sdalcinl 
405971f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
406071f87433Sdalcinl 
406171f87433Sdalcinl    Level: advanced
406271f87433Sdalcinl 
406371f87433Sdalcinl    Reference:
406471f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
406571f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
406671f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
406771f87433Sdalcinl 
406871f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
406971f87433Sdalcinl 
4070fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
407171f87433Sdalcinl @*/
40727087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
407371f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
407471f87433Sdalcinl {
4075fa9f3622SBarry Smith   SNESKSPEW *kctx;
407671f87433Sdalcinl   PetscFunctionBegin;
40770700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4078fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4079e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
4080c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
4081c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
4082c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
4083c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
4084c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
4085c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
4086c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
408771f87433Sdalcinl 
408871f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
408971f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
409071f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
409171f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
409271f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
409371f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
409471f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
409571f87433Sdalcinl 
409671f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
4097e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
409871f87433Sdalcinl   }
409971f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
4100e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
410171f87433Sdalcinl   }
410271f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
4103e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
410471f87433Sdalcinl   }
410571f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
4106e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
410771f87433Sdalcinl   }
410871f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
4109e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
411071f87433Sdalcinl   }
411171f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
4112e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
411371f87433Sdalcinl   }
411471f87433Sdalcinl   PetscFunctionReturn(0);
411571f87433Sdalcinl }
411671f87433Sdalcinl 
411771f87433Sdalcinl #undef __FUNCT__
4118fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
411971f87433Sdalcinl /*@
4120fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
412171f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
412271f87433Sdalcinl    Newton method.
412371f87433Sdalcinl 
412471f87433Sdalcinl    Not Collective
412571f87433Sdalcinl 
412671f87433Sdalcinl    Input Parameters:
412771f87433Sdalcinl      snes - SNES context
412871f87433Sdalcinl 
412971f87433Sdalcinl    Output Parameters:
413071f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
413171f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
413271f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
413371f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
413471f87433Sdalcinl              (0 <= gamma2 <= 1)
413571f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
413671f87433Sdalcinl .    alpha2 - power for safeguard
413771f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
413871f87433Sdalcinl 
413971f87433Sdalcinl    Level: advanced
414071f87433Sdalcinl 
414171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
414271f87433Sdalcinl 
4143fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
414471f87433Sdalcinl @*/
41457087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
414671f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
414771f87433Sdalcinl {
4148fa9f3622SBarry Smith   SNESKSPEW *kctx;
414971f87433Sdalcinl   PetscFunctionBegin;
41500700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4151fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4152e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
415371f87433Sdalcinl   if(version)   *version   = kctx->version;
415471f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
415571f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
415671f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
415771f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
415871f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
415971f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
416071f87433Sdalcinl   PetscFunctionReturn(0);
416171f87433Sdalcinl }
416271f87433Sdalcinl 
416371f87433Sdalcinl #undef __FUNCT__
4164fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
4165fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
416671f87433Sdalcinl {
416771f87433Sdalcinl   PetscErrorCode ierr;
4168fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
416971f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
417071f87433Sdalcinl 
417171f87433Sdalcinl   PetscFunctionBegin;
4172e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
417371f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
417471f87433Sdalcinl     rtol = kctx->rtol_0;
417571f87433Sdalcinl   } else {
417671f87433Sdalcinl     if (kctx->version == 1) {
417771f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
417871f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
417971f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
418071f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
418171f87433Sdalcinl     } else if (kctx->version == 2) {
418271f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
418371f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
418471f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
418571f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
418671f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
418771f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
418871f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
418971f87433Sdalcinl       stol = PetscMax(rtol,stol);
419071f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
419171f87433Sdalcinl       /* safeguard: avoid oversolving */
419271f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
419371f87433Sdalcinl       stol = PetscMax(rtol,stol);
419471f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
4195e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
419671f87433Sdalcinl   }
419771f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
419871f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
419971f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
420071f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
420171f87433Sdalcinl   PetscFunctionReturn(0);
420271f87433Sdalcinl }
420371f87433Sdalcinl 
420471f87433Sdalcinl #undef __FUNCT__
4205fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
4206fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
420771f87433Sdalcinl {
420871f87433Sdalcinl   PetscErrorCode ierr;
4209fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
421071f87433Sdalcinl   PCSide         pcside;
421171f87433Sdalcinl   Vec            lres;
421271f87433Sdalcinl 
421371f87433Sdalcinl   PetscFunctionBegin;
4214e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
421571f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
421671f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
421771f87433Sdalcinl   if (kctx->version == 1) {
4218b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
421971f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
422071f87433Sdalcinl       /* KSP residual is true linear residual */
422171f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
422271f87433Sdalcinl     } else {
422371f87433Sdalcinl       /* KSP residual is preconditioned residual */
422471f87433Sdalcinl       /* compute true linear residual norm */
422571f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
422671f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
422771f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
422871f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
42296bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
423071f87433Sdalcinl     }
423171f87433Sdalcinl   }
423271f87433Sdalcinl   PetscFunctionReturn(0);
423371f87433Sdalcinl }
423471f87433Sdalcinl 
423571f87433Sdalcinl #undef __FUNCT__
423671f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
423771f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
423871f87433Sdalcinl {
423971f87433Sdalcinl   PetscErrorCode ierr;
424071f87433Sdalcinl 
424171f87433Sdalcinl   PetscFunctionBegin;
4242fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
424371f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
4244fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
424571f87433Sdalcinl   PetscFunctionReturn(0);
424671f87433Sdalcinl }
42476c699258SBarry Smith 
42486c699258SBarry Smith #undef __FUNCT__
42496c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
42506c699258SBarry Smith /*@
42516c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
42526c699258SBarry Smith 
42533f9fe445SBarry Smith    Logically Collective on SNES
42546c699258SBarry Smith 
42556c699258SBarry Smith    Input Parameters:
42566c699258SBarry Smith +  snes - the preconditioner context
42576c699258SBarry Smith -  dm - the dm
42586c699258SBarry Smith 
42596c699258SBarry Smith    Level: intermediate
42606c699258SBarry Smith 
42616c699258SBarry Smith 
42626c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
42636c699258SBarry Smith @*/
42647087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
42656c699258SBarry Smith {
42666c699258SBarry Smith   PetscErrorCode ierr;
4267345fed2cSBarry Smith   KSP            ksp;
42686cab3a1bSJed Brown   SNESDM         sdm;
42696c699258SBarry Smith 
42706c699258SBarry Smith   PetscFunctionBegin;
42710700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4272d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
42736cab3a1bSJed Brown   if (snes->dm) {               /* Move the SNESDM context over to the new DM unless the new DM already has one */
42746cab3a1bSJed Brown     PetscContainer oldcontainer,container;
42756cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr);
42766cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr);
42776cab3a1bSJed Brown     if (oldcontainer && !container) {
42786cab3a1bSJed Brown       ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr);
42796cab3a1bSJed Brown       ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr);
42806cab3a1bSJed Brown       if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */
42816cab3a1bSJed Brown         sdm->originaldm = dm;
42826cab3a1bSJed Brown       }
42836cab3a1bSJed Brown     }
42846bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
42856cab3a1bSJed Brown   }
42866c699258SBarry Smith   snes->dm = dm;
4287345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4288345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4289f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
42902c155ee1SBarry Smith   if (snes->pc) {
42912c155ee1SBarry Smith     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
42922c155ee1SBarry Smith   }
42936c699258SBarry Smith   PetscFunctionReturn(0);
42946c699258SBarry Smith }
42956c699258SBarry Smith 
42966c699258SBarry Smith #undef __FUNCT__
42976c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
42986c699258SBarry Smith /*@
42996c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
43006c699258SBarry Smith 
43013f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
43026c699258SBarry Smith 
43036c699258SBarry Smith    Input Parameter:
43046c699258SBarry Smith . snes - the preconditioner context
43056c699258SBarry Smith 
43066c699258SBarry Smith    Output Parameter:
43076c699258SBarry Smith .  dm - the dm
43086c699258SBarry Smith 
43096c699258SBarry Smith    Level: intermediate
43106c699258SBarry Smith 
43116c699258SBarry Smith 
43126c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
43136c699258SBarry Smith @*/
43147087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
43156c699258SBarry Smith {
43166cab3a1bSJed Brown   PetscErrorCode ierr;
43176cab3a1bSJed Brown 
43186c699258SBarry Smith   PetscFunctionBegin;
43190700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
43206cab3a1bSJed Brown   if (!snes->dm) {
43216cab3a1bSJed Brown     ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr);
43226cab3a1bSJed Brown   }
43236c699258SBarry Smith   *dm = snes->dm;
43246c699258SBarry Smith   PetscFunctionReturn(0);
43256c699258SBarry Smith }
43260807856dSBarry Smith 
432731823bd8SMatthew G Knepley #undef __FUNCT__
432831823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
432931823bd8SMatthew G Knepley /*@
4330fd4b34e9SJed Brown   SNESSetPC - Sets the nonlinear preconditioner to be used.
433131823bd8SMatthew G Knepley 
433231823bd8SMatthew G Knepley   Collective on SNES
433331823bd8SMatthew G Knepley 
433431823bd8SMatthew G Knepley   Input Parameters:
433531823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
433631823bd8SMatthew G Knepley - pc   - the preconditioner object
433731823bd8SMatthew G Knepley 
433831823bd8SMatthew G Knepley   Notes:
433931823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
434031823bd8SMatthew G Knepley   to configure it using the API).
434131823bd8SMatthew G Knepley 
434231823bd8SMatthew G Knepley   Level: developer
434331823bd8SMatthew G Knepley 
434431823bd8SMatthew G Knepley .keywords: SNES, set, precondition
434531823bd8SMatthew G Knepley .seealso: SNESGetPC()
434631823bd8SMatthew G Knepley @*/
434731823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
434831823bd8SMatthew G Knepley {
434931823bd8SMatthew G Knepley   PetscErrorCode ierr;
435031823bd8SMatthew G Knepley 
435131823bd8SMatthew G Knepley   PetscFunctionBegin;
435231823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
435331823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
435431823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
435531823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4356bf11d3b6SBarry Smith   ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr);
435731823bd8SMatthew G Knepley   snes->pc = pc;
435831823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
435931823bd8SMatthew G Knepley   PetscFunctionReturn(0);
436031823bd8SMatthew G Knepley }
436131823bd8SMatthew G Knepley 
436231823bd8SMatthew G Knepley #undef __FUNCT__
436331823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
436431823bd8SMatthew G Knepley /*@
4365fd4b34e9SJed Brown   SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().
436631823bd8SMatthew G Knepley 
436731823bd8SMatthew G Knepley   Not Collective
436831823bd8SMatthew G Knepley 
436931823bd8SMatthew G Knepley   Input Parameter:
437031823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
437131823bd8SMatthew G Knepley 
437231823bd8SMatthew G Knepley   Output Parameter:
437331823bd8SMatthew G Knepley . pc - preconditioner context
437431823bd8SMatthew G Knepley 
437531823bd8SMatthew G Knepley   Level: developer
437631823bd8SMatthew G Knepley 
437731823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
437831823bd8SMatthew G Knepley .seealso: SNESSetPC()
437931823bd8SMatthew G Knepley @*/
438031823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
438131823bd8SMatthew G Knepley {
438231823bd8SMatthew G Knepley   PetscErrorCode              ierr;
4383a64e098fSPeter Brune   const char                  *optionsprefix;
438431823bd8SMatthew G Knepley 
438531823bd8SMatthew G Knepley   PetscFunctionBegin;
438631823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
438731823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
438831823bd8SMatthew G Knepley   if (!snes->pc) {
438931823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm,&snes->pc);CHKERRQ(ierr);
43904a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);CHKERRQ(ierr);
439131823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes,snes->pc);CHKERRQ(ierr);
4392a64e098fSPeter Brune     ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr);
4393a64e098fSPeter Brune     ierr = SNESSetOptionsPrefix(snes->pc,optionsprefix);CHKERRQ(ierr);
4394a64e098fSPeter Brune     ierr = SNESAppendOptionsPrefix(snes->pc,"npc_");CHKERRQ(ierr);
439531823bd8SMatthew G Knepley   }
439631823bd8SMatthew G Knepley   *pc = snes->pc;
439731823bd8SMatthew G Knepley   PetscFunctionReturn(0);
439831823bd8SMatthew G Knepley }
439931823bd8SMatthew G Knepley 
44009e764e56SPeter Brune #undef __FUNCT__
4401f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch"
44029e764e56SPeter Brune /*@
44038141a3b9SPeter Brune   SNESSetSNESLineSearch - Sets the linesearch on the SNES instance.
44049e764e56SPeter Brune 
44059e764e56SPeter Brune   Collective on SNES
44069e764e56SPeter Brune 
44079e764e56SPeter Brune   Input Parameters:
44089e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
44099e764e56SPeter Brune - linesearch   - the linesearch object
44109e764e56SPeter Brune 
44119e764e56SPeter Brune   Notes:
4412f1c6b773SPeter Brune   Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example,
44139e764e56SPeter Brune   to configure it using the API).
44149e764e56SPeter Brune 
44159e764e56SPeter Brune   Level: developer
44169e764e56SPeter Brune 
44179e764e56SPeter Brune .keywords: SNES, set, linesearch
4418f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch()
44199e764e56SPeter Brune @*/
4420f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch)
44219e764e56SPeter Brune {
44229e764e56SPeter Brune   PetscErrorCode ierr;
44239e764e56SPeter Brune 
44249e764e56SPeter Brune   PetscFunctionBegin;
44259e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4426f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
44279e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
44289e764e56SPeter Brune   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
4429f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
44309e764e56SPeter Brune   snes->linesearch = linesearch;
44319e764e56SPeter Brune   ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
44329e764e56SPeter Brune   PetscFunctionReturn(0);
44339e764e56SPeter Brune }
44349e764e56SPeter Brune 
44359e764e56SPeter Brune #undef __FUNCT__
4436f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch"
4437ea5d4fccSPeter Brune /*@C
44388141a3b9SPeter Brune   SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch()
44398141a3b9SPeter Brune   or creates a default line search instance associated with the SNES and returns it.
44409e764e56SPeter Brune 
44419e764e56SPeter Brune   Not Collective
44429e764e56SPeter Brune 
44439e764e56SPeter Brune   Input Parameter:
44449e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
44459e764e56SPeter Brune 
44469e764e56SPeter Brune   Output Parameter:
44479e764e56SPeter Brune . linesearch - linesearch context
44489e764e56SPeter Brune 
44499e764e56SPeter Brune   Level: developer
44509e764e56SPeter Brune 
44519e764e56SPeter Brune .keywords: SNES, get, linesearch
4452f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch()
44539e764e56SPeter Brune @*/
4454f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch)
44559e764e56SPeter Brune {
44569e764e56SPeter Brune   PetscErrorCode ierr;
44579e764e56SPeter Brune   const char     *optionsprefix;
44589e764e56SPeter Brune 
44599e764e56SPeter Brune   PetscFunctionBegin;
44609e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
44619e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
44629e764e56SPeter Brune   if (!snes->linesearch) {
44639e764e56SPeter Brune     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
4464f1c6b773SPeter Brune     ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr);
4465f1c6b773SPeter Brune     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
4466b1dca40bSPeter Brune     ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr);
44679e764e56SPeter Brune     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
44689e764e56SPeter Brune     ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
44699e764e56SPeter Brune   }
44709e764e56SPeter Brune   *linesearch = snes->linesearch;
44719e764e56SPeter Brune   PetscFunctionReturn(0);
44729e764e56SPeter Brune }
44739e764e56SPeter Brune 
447469b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4475c6db04a5SJed Brown #include <mex.h>
447669b4f73cSBarry Smith 
44778f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
44788f6e6473SBarry Smith 
44790807856dSBarry Smith #undef __FUNCT__
44800807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
44810807856dSBarry Smith /*
44820807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
44830807856dSBarry Smith                          SNESSetFunctionMatlab().
44840807856dSBarry Smith 
44850807856dSBarry Smith    Collective on SNES
44860807856dSBarry Smith 
44870807856dSBarry Smith    Input Parameters:
44880807856dSBarry Smith +  snes - the SNES context
44890807856dSBarry Smith -  x - input vector
44900807856dSBarry Smith 
44910807856dSBarry Smith    Output Parameter:
44920807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
44930807856dSBarry Smith 
44940807856dSBarry Smith    Notes:
44950807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
44960807856dSBarry Smith    implementations, so most users would not generally call this routine
44970807856dSBarry Smith    themselves.
44980807856dSBarry Smith 
44990807856dSBarry Smith    Level: developer
45000807856dSBarry Smith 
45010807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
45020807856dSBarry Smith 
45030807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
450461b2408cSBarry Smith */
45057087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
45060807856dSBarry Smith {
4507e650e774SBarry Smith   PetscErrorCode    ierr;
45088f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
45098f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
45108f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
451191621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
4512e650e774SBarry Smith 
45130807856dSBarry Smith   PetscFunctionBegin;
45140807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
45150807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
45160807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
45170807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
45180807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
45190807856dSBarry Smith 
45200807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
4521e650e774SBarry Smith 
452291621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4523e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4524e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
452591621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
452691621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
452791621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
45288f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
45298f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
4530b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
4531e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4532e650e774SBarry Smith   mxDestroyArray(prhs[0]);
4533e650e774SBarry Smith   mxDestroyArray(prhs[1]);
4534e650e774SBarry Smith   mxDestroyArray(prhs[2]);
45358f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
4536e650e774SBarry Smith   mxDestroyArray(plhs[0]);
45370807856dSBarry Smith   PetscFunctionReturn(0);
45380807856dSBarry Smith }
45390807856dSBarry Smith 
45400807856dSBarry Smith 
45410807856dSBarry Smith #undef __FUNCT__
45420807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
454361b2408cSBarry Smith /*
45440807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
45450807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4546e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
45470807856dSBarry Smith 
45480807856dSBarry Smith    Logically Collective on SNES
45490807856dSBarry Smith 
45500807856dSBarry Smith    Input Parameters:
45510807856dSBarry Smith +  snes - the SNES context
45520807856dSBarry Smith .  r - vector to store function value
45530807856dSBarry Smith -  func - function evaluation routine
45540807856dSBarry Smith 
45550807856dSBarry Smith    Calling sequence of func:
455661b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
45570807856dSBarry Smith 
45580807856dSBarry Smith 
45590807856dSBarry Smith    Notes:
45600807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
45610807856dSBarry Smith $      f'(x) x = -f(x),
45620807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
45630807856dSBarry Smith 
45640807856dSBarry Smith    Level: beginner
45650807856dSBarry Smith 
45660807856dSBarry Smith .keywords: SNES, nonlinear, set, function
45670807856dSBarry Smith 
45680807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
456961b2408cSBarry Smith */
45707087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
45710807856dSBarry Smith {
45720807856dSBarry Smith   PetscErrorCode    ierr;
45738f6e6473SBarry Smith   SNESMatlabContext *sctx;
45740807856dSBarry Smith 
45750807856dSBarry Smith   PetscFunctionBegin;
45768f6e6473SBarry Smith   /* currently sctx is memory bleed */
45778f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
45788f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
45798f6e6473SBarry Smith   /*
45808f6e6473SBarry Smith      This should work, but it doesn't
45818f6e6473SBarry Smith   sctx->ctx = ctx;
45828f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
45838f6e6473SBarry Smith   */
45848f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
45858f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
45860807856dSBarry Smith   PetscFunctionReturn(0);
45870807856dSBarry Smith }
458869b4f73cSBarry Smith 
458961b2408cSBarry Smith #undef __FUNCT__
459061b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
459161b2408cSBarry Smith /*
459261b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
459361b2408cSBarry Smith                          SNESSetJacobianMatlab().
459461b2408cSBarry Smith 
459561b2408cSBarry Smith    Collective on SNES
459661b2408cSBarry Smith 
459761b2408cSBarry Smith    Input Parameters:
459861b2408cSBarry Smith +  snes - the SNES context
459961b2408cSBarry Smith .  x - input vector
460061b2408cSBarry Smith .  A, B - the matrices
460161b2408cSBarry Smith -  ctx - user context
460261b2408cSBarry Smith 
460361b2408cSBarry Smith    Output Parameter:
460461b2408cSBarry Smith .  flag - structure of the matrix
460561b2408cSBarry Smith 
460661b2408cSBarry Smith    Level: developer
460761b2408cSBarry Smith 
460861b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
460961b2408cSBarry Smith 
461061b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
461161b2408cSBarry Smith @*/
46127087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
461361b2408cSBarry Smith {
461461b2408cSBarry Smith   PetscErrorCode    ierr;
461561b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
461661b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
461761b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
461861b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
461961b2408cSBarry Smith 
462061b2408cSBarry Smith   PetscFunctionBegin;
462161b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
462261b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
462361b2408cSBarry Smith 
462461b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
462561b2408cSBarry Smith 
462661b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
462761b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
462861b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
462961b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
463061b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
463161b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
463261b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
463361b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
463461b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
463561b2408cSBarry Smith   prhs[5] =  sctx->ctx;
4636b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
463761b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
463861b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
463961b2408cSBarry Smith   mxDestroyArray(prhs[0]);
464061b2408cSBarry Smith   mxDestroyArray(prhs[1]);
464161b2408cSBarry Smith   mxDestroyArray(prhs[2]);
464261b2408cSBarry Smith   mxDestroyArray(prhs[3]);
464361b2408cSBarry Smith   mxDestroyArray(prhs[4]);
464461b2408cSBarry Smith   mxDestroyArray(plhs[0]);
464561b2408cSBarry Smith   mxDestroyArray(plhs[1]);
464661b2408cSBarry Smith   PetscFunctionReturn(0);
464761b2408cSBarry Smith }
464861b2408cSBarry Smith 
464961b2408cSBarry Smith 
465061b2408cSBarry Smith #undef __FUNCT__
465161b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
465261b2408cSBarry Smith /*
465361b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
465461b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4655e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
465661b2408cSBarry Smith 
465761b2408cSBarry Smith    Logically Collective on SNES
465861b2408cSBarry Smith 
465961b2408cSBarry Smith    Input Parameters:
466061b2408cSBarry Smith +  snes - the SNES context
466161b2408cSBarry Smith .  A,B - Jacobian matrices
466261b2408cSBarry Smith .  func - function evaluation routine
466361b2408cSBarry Smith -  ctx - user context
466461b2408cSBarry Smith 
466561b2408cSBarry Smith    Calling sequence of func:
466661b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
466761b2408cSBarry Smith 
466861b2408cSBarry Smith 
466961b2408cSBarry Smith    Level: developer
467061b2408cSBarry Smith 
467161b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
467261b2408cSBarry Smith 
467361b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
467461b2408cSBarry Smith */
46757087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
467661b2408cSBarry Smith {
467761b2408cSBarry Smith   PetscErrorCode    ierr;
467861b2408cSBarry Smith   SNESMatlabContext *sctx;
467961b2408cSBarry Smith 
468061b2408cSBarry Smith   PetscFunctionBegin;
468161b2408cSBarry Smith   /* currently sctx is memory bleed */
468261b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
468361b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
468461b2408cSBarry Smith   /*
468561b2408cSBarry Smith      This should work, but it doesn't
468661b2408cSBarry Smith   sctx->ctx = ctx;
468761b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
468861b2408cSBarry Smith   */
468961b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
469061b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
469161b2408cSBarry Smith   PetscFunctionReturn(0);
469261b2408cSBarry Smith }
469369b4f73cSBarry Smith 
4694f9eb7ae2SShri Abhyankar #undef __FUNCT__
4695f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
4696f9eb7ae2SShri Abhyankar /*
4697f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
4698f9eb7ae2SShri Abhyankar 
4699f9eb7ae2SShri Abhyankar    Collective on SNES
4700f9eb7ae2SShri Abhyankar 
4701f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
4702f9eb7ae2SShri Abhyankar @*/
47037087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
4704f9eb7ae2SShri Abhyankar {
4705f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
470648f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
4707f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
4708f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
4709f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
4710f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
4711f9eb7ae2SShri Abhyankar 
4712f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4713f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4714f9eb7ae2SShri Abhyankar 
4715f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4716f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4717f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
4718f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
4719f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
4720f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
4721f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
4722f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
4723f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
4724f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4725f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
4726f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
4727f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
4728f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
4729f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
4730f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
4731f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4732f9eb7ae2SShri Abhyankar }
4733f9eb7ae2SShri Abhyankar 
4734f9eb7ae2SShri Abhyankar 
4735f9eb7ae2SShri Abhyankar #undef __FUNCT__
4736f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
4737f9eb7ae2SShri Abhyankar /*
4738e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
4739f9eb7ae2SShri Abhyankar 
4740f9eb7ae2SShri Abhyankar    Level: developer
4741f9eb7ae2SShri Abhyankar 
4742f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
4743f9eb7ae2SShri Abhyankar 
4744f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
4745f9eb7ae2SShri Abhyankar */
47467087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
4747f9eb7ae2SShri Abhyankar {
4748f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
4749f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
4750f9eb7ae2SShri Abhyankar 
4751f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4752f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
4753f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
4754f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4755f9eb7ae2SShri Abhyankar   /*
4756f9eb7ae2SShri Abhyankar      This should work, but it doesn't
4757f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
4758f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
4759f9eb7ae2SShri Abhyankar   */
4760f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
4761f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4762f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4763f9eb7ae2SShri Abhyankar }
4764f9eb7ae2SShri Abhyankar 
476569b4f73cSBarry Smith #endif
4766