xref: /petsc/src/snes/interface/snes.c (revision 6e2a1849809b3ca2524fc1dd9632236f97487fc2)
19b94acceSBarry Smith 
2b45d2f2cSJed Brown #include <petsc-private/snesimpl.h>      /*I "petscsnes.h"  I*/
36cab3a1bSJed Brown #include <petscdmshell.h>                /*I "petscdmshell.h" I*/
4a64e098fSPeter Brune #include <petscsys.h>                    /*I "petscsys.h" I*/
59b94acceSBarry Smith 
6ace3abfcSBarry Smith PetscBool  SNESRegisterAllCalled = PETSC_FALSE;
78ba1e511SMatthew Knepley PetscFList SNESList              = PETSC_NULL;
88ba1e511SMatthew Knepley 
98ba1e511SMatthew Knepley /* Logging support */
107087cfbeSBarry Smith PetscClassId  SNES_CLASSID;
11f1c6b773SPeter Brune PetscLogEvent  SNES_Solve, SNES_FunctionEval, SNES_JacobianEval, SNES_GSEval;
12a09944afSBarry Smith 
13a09944afSBarry Smith #undef __FUNCT__
14e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged"
15e113a28aSBarry Smith /*@
16e113a28aSBarry Smith    SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged.
17e113a28aSBarry Smith 
183f9fe445SBarry Smith    Logically Collective on SNES
19e113a28aSBarry Smith 
20e113a28aSBarry Smith    Input Parameters:
21e113a28aSBarry Smith +  snes - iterative context obtained from SNESCreate()
22e113a28aSBarry Smith -  flg - PETSC_TRUE indicates you want the error generated
23e113a28aSBarry Smith 
24e113a28aSBarry Smith    Options database keys:
25e113a28aSBarry Smith .  -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false)
26e113a28aSBarry Smith 
27e113a28aSBarry Smith    Level: intermediate
28e113a28aSBarry Smith 
29e113a28aSBarry Smith    Notes:
30e113a28aSBarry Smith     Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve()
31e113a28aSBarry Smith     to determine if it has converged.
32e113a28aSBarry Smith 
33e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
34e113a28aSBarry Smith 
35e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
36e113a28aSBarry Smith @*/
377087cfbeSBarry Smith PetscErrorCode  SNESSetErrorIfNotConverged(SNES snes,PetscBool  flg)
38e113a28aSBarry Smith {
39e113a28aSBarry Smith   PetscFunctionBegin;
40e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
41acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flg,2);
42e113a28aSBarry Smith   snes->errorifnotconverged = flg;
43dd568438SSatish Balay 
44e113a28aSBarry Smith   PetscFunctionReturn(0);
45e113a28aSBarry Smith }
46e113a28aSBarry Smith 
47e113a28aSBarry Smith #undef __FUNCT__
48e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged"
49e113a28aSBarry Smith /*@
50e113a28aSBarry Smith    SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge?
51e113a28aSBarry Smith 
52e113a28aSBarry Smith    Not Collective
53e113a28aSBarry Smith 
54e113a28aSBarry Smith    Input Parameter:
55e113a28aSBarry Smith .  snes - iterative context obtained from SNESCreate()
56e113a28aSBarry Smith 
57e113a28aSBarry Smith    Output Parameter:
58e113a28aSBarry Smith .  flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE
59e113a28aSBarry Smith 
60e113a28aSBarry Smith    Level: intermediate
61e113a28aSBarry Smith 
62e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
63e113a28aSBarry Smith 
64e113a28aSBarry Smith .seealso:  SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
65e113a28aSBarry Smith @*/
667087cfbeSBarry Smith PetscErrorCode  SNESGetErrorIfNotConverged(SNES snes,PetscBool  *flag)
67e113a28aSBarry Smith {
68e113a28aSBarry Smith   PetscFunctionBegin;
69e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
70e113a28aSBarry Smith   PetscValidPointer(flag,2);
71e113a28aSBarry Smith   *flag = snes->errorifnotconverged;
72e113a28aSBarry Smith   PetscFunctionReturn(0);
73e113a28aSBarry Smith }
74e113a28aSBarry Smith 
75e113a28aSBarry Smith #undef __FUNCT__
764936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError"
77e725d27bSBarry Smith /*@
784936397dSBarry Smith    SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not
794936397dSBarry Smith      in the functions domain. For example, negative pressure.
804936397dSBarry Smith 
813f9fe445SBarry Smith    Logically Collective on SNES
824936397dSBarry Smith 
834936397dSBarry Smith    Input Parameters:
846a388c36SPeter Brune .  snes - the SNES context
854936397dSBarry Smith 
8628529972SSatish Balay    Level: advanced
874936397dSBarry Smith 
884936397dSBarry Smith .keywords: SNES, view
894936397dSBarry Smith 
904936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction()
914936397dSBarry Smith @*/
927087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionDomainError(SNES snes)
934936397dSBarry Smith {
944936397dSBarry Smith   PetscFunctionBegin;
950700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
964936397dSBarry Smith   snes->domainerror = PETSC_TRUE;
974936397dSBarry Smith   PetscFunctionReturn(0);
984936397dSBarry Smith }
994936397dSBarry Smith 
1006a388c36SPeter Brune 
1016a388c36SPeter Brune #undef __FUNCT__
1026a388c36SPeter Brune #define __FUNCT__ "SNESGetFunctionDomainError"
1036a388c36SPeter Brune /*@
104c77b2880SPeter Brune    SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction;
1056a388c36SPeter Brune 
1066a388c36SPeter Brune    Logically Collective on SNES
1076a388c36SPeter Brune 
1086a388c36SPeter Brune    Input Parameters:
1096a388c36SPeter Brune .  snes - the SNES context
1106a388c36SPeter Brune 
1116a388c36SPeter Brune    Output Parameters:
1126a388c36SPeter Brune .  domainerror Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise.
1136a388c36SPeter Brune 
1146a388c36SPeter Brune    Level: advanced
1156a388c36SPeter Brune 
1166a388c36SPeter Brune .keywords: SNES, view
1176a388c36SPeter Brune 
1186a388c36SPeter Brune .seealso: SNESSetFunctionDomainError, SNESComputeFunction()
1196a388c36SPeter Brune @*/
1206a388c36SPeter Brune PetscErrorCode  SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror)
1216a388c36SPeter Brune {
1226a388c36SPeter Brune   PetscFunctionBegin;
1236a388c36SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1246a388c36SPeter Brune   PetscValidPointer(domainerror, 2);
1256a388c36SPeter Brune   *domainerror = snes->domainerror;
1266a388c36SPeter Brune   PetscFunctionReturn(0);
1276a388c36SPeter Brune }
1286a388c36SPeter Brune 
1296a388c36SPeter Brune 
1304936397dSBarry Smith #undef __FUNCT__
1314a2ae208SSatish Balay #define __FUNCT__ "SNESView"
1327e2c5f70SBarry Smith /*@C
1339b94acceSBarry Smith    SNESView - Prints the SNES data structure.
1349b94acceSBarry Smith 
1354c49b128SBarry Smith    Collective on SNES
136fee21e36SBarry Smith 
137c7afd0dbSLois Curfman McInnes    Input Parameters:
138c7afd0dbSLois Curfman McInnes +  SNES - the SNES context
139c7afd0dbSLois Curfman McInnes -  viewer - visualization context
140c7afd0dbSLois Curfman McInnes 
1419b94acceSBarry Smith    Options Database Key:
142c8a8ba5cSLois Curfman McInnes .  -snes_view - Calls SNESView() at end of SNESSolve()
1439b94acceSBarry Smith 
1449b94acceSBarry Smith    Notes:
1459b94acceSBarry Smith    The available visualization contexts include
146b0a32e0cSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
147b0a32e0cSBarry Smith -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
148c8a8ba5cSLois Curfman McInnes          output where only the first processor opens
149c8a8ba5cSLois Curfman McInnes          the file.  All other processors send their
150c8a8ba5cSLois Curfman McInnes          data to the first processor to print.
1519b94acceSBarry Smith 
1523e081fefSLois Curfman McInnes    The user can open an alternative visualization context with
153b0a32e0cSBarry Smith    PetscViewerASCIIOpen() - output to a specified file.
1549b94acceSBarry Smith 
15536851e7fSLois Curfman McInnes    Level: beginner
15636851e7fSLois Curfman McInnes 
1579b94acceSBarry Smith .keywords: SNES, view
1589b94acceSBarry Smith 
159b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen()
1609b94acceSBarry Smith @*/
1617087cfbeSBarry Smith PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
1629b94acceSBarry Smith {
163fa9f3622SBarry Smith   SNESKSPEW           *kctx;
164dfbe8321SBarry Smith   PetscErrorCode      ierr;
16594b7f48cSBarry Smith   KSP                 ksp;
1667f1410a3SPeter Brune   SNESLineSearch      linesearch;
167ace3abfcSBarry Smith   PetscBool           iascii,isstring;
1689b94acceSBarry Smith 
1693a40ed3dSBarry Smith   PetscFunctionBegin;
1700700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1713050cee2SBarry Smith   if (!viewer) {
1727adad957SLisandro Dalcin     ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
1733050cee2SBarry Smith   }
1740700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
175c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,viewer,2);
17674679c65SBarry Smith 
177251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
178251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
17932077d6dSBarry Smith   if (iascii) {
180317d6ea6SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr);
181e7788613SBarry Smith     if (snes->ops->view) {
182b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
183e7788613SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
184b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1850ef38995SBarry Smith     }
18677431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr);
187a83599f4SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%G, absolute=%G, solution=%G\n",
188c60f73f4SPeter Brune                  snes->rtol,snes->abstol,snes->stol);CHKERRQ(ierr);
18977431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr);
19077431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr);
1919b94acceSBarry Smith     if (snes->ksp_ewconv) {
192fa9f3622SBarry Smith       kctx = (SNESKSPEW *)snes->kspconvctx;
1939b94acceSBarry Smith       if (kctx) {
19477431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr);
195a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr);
196a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr);
1979b94acceSBarry Smith       }
1989b94acceSBarry Smith     }
199eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
200eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");CHKERRQ(ierr);
201eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
202eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr);
203eb1f6c34SBarry Smith     }
204eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
205eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");CHKERRQ(ierr);
206eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
20742f4f86dSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr);
208eb1f6c34SBarry Smith     }
2090f5bd95cSBarry Smith   } else if (isstring) {
210317d6ea6SBarry Smith     const char *type;
211454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
212b0a32e0cSBarry Smith     ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr);
21319bcc07fSBarry Smith   }
21442f4f86dSBarry Smith   if (snes->pc && snes->usespc) {
2154a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2164a0c5b0cSMatthew G Knepley     ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr);
2174a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2184a0c5b0cSMatthew G Knepley   }
2192c155ee1SBarry Smith   if (snes->usesksp) {
2202c155ee1SBarry Smith     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
221b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
22294b7f48cSBarry Smith     ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
223b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2242c155ee1SBarry Smith   }
2257f1410a3SPeter Brune   if (snes->linesearch) {
2267f1410a3SPeter Brune     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2277f1410a3SPeter Brune     ierr = SNESGetSNESLineSearch(snes, &linesearch);CHKERRQ(ierr);
2287f1410a3SPeter Brune     ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr);
2297f1410a3SPeter Brune     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2307f1410a3SPeter Brune   }
2313a40ed3dSBarry Smith   PetscFunctionReturn(0);
2329b94acceSBarry Smith }
2339b94acceSBarry Smith 
23476b2cf59SMatthew Knepley /*
23576b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
23676b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
23776b2cf59SMatthew Knepley */
23876b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
239a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
2406849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
24176b2cf59SMatthew Knepley 
242e74ef692SMatthew Knepley #undef __FUNCT__
243e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker"
244ac226902SBarry Smith /*@C
24576b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
24676b2cf59SMatthew Knepley 
24776b2cf59SMatthew Knepley   Not Collective
24876b2cf59SMatthew Knepley 
24976b2cf59SMatthew Knepley   Input Parameter:
25076b2cf59SMatthew Knepley . snescheck - function that checks for options
25176b2cf59SMatthew Knepley 
25276b2cf59SMatthew Knepley   Level: developer
25376b2cf59SMatthew Knepley 
25476b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
25576b2cf59SMatthew Knepley @*/
2567087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
25776b2cf59SMatthew Knepley {
25876b2cf59SMatthew Knepley   PetscFunctionBegin;
25976b2cf59SMatthew Knepley   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
260e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
26176b2cf59SMatthew Knepley   }
26276b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
26376b2cf59SMatthew Knepley   PetscFunctionReturn(0);
26476b2cf59SMatthew Knepley }
26576b2cf59SMatthew Knepley 
2667087cfbeSBarry Smith extern PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
267aa3661deSLisandro Dalcin 
268aa3661deSLisandro Dalcin #undef __FUNCT__
269aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private"
270ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool  hasOperator, PetscInt version)
271aa3661deSLisandro Dalcin {
272aa3661deSLisandro Dalcin   Mat            J;
273aa3661deSLisandro Dalcin   KSP            ksp;
274aa3661deSLisandro Dalcin   PC             pc;
275ace3abfcSBarry Smith   PetscBool      match;
276aa3661deSLisandro Dalcin   PetscErrorCode ierr;
277aa3661deSLisandro Dalcin 
278aa3661deSLisandro Dalcin   PetscFunctionBegin;
2790700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
280aa3661deSLisandro Dalcin 
28198613b67SLisandro Dalcin   if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
28298613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
28398613b67SLisandro Dalcin     ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr);
28498613b67SLisandro Dalcin   }
28598613b67SLisandro Dalcin 
286aa3661deSLisandro Dalcin   if (version == 1) {
287aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
28898613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
2899c6ac3b3SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
290aa3661deSLisandro Dalcin   } else if (version == 2) {
291e32f2f54SBarry Smith     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
29282a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
293aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
294aa3661deSLisandro Dalcin #else
295e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
296aa3661deSLisandro Dalcin #endif
297a8248277SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
298aa3661deSLisandro Dalcin 
299aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
300d3462f78SMatthew Knepley   if (hasOperator) {
301aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
302aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
303aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
304aa3661deSLisandro Dalcin   } else {
305aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
306aa3661deSLisandro Dalcin        provided preconditioner matrix with the default matrix free version. */
3076cab3a1bSJed Brown     void *functx;
3086cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
3096cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
310aa3661deSLisandro Dalcin     /* Force no preconditioner */
311aa3661deSLisandro Dalcin     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
312aa3661deSLisandro Dalcin     ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
313251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
314aa3661deSLisandro Dalcin     if (!match) {
315aa3661deSLisandro Dalcin       ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
316aa3661deSLisandro Dalcin       ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
317aa3661deSLisandro Dalcin     }
318aa3661deSLisandro Dalcin   }
3196bf464f9SBarry Smith   ierr = MatDestroy(&J);CHKERRQ(ierr);
320aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
321aa3661deSLisandro Dalcin }
322aa3661deSLisandro Dalcin 
3234a2ae208SSatish Balay #undef __FUNCT__
324dfe15315SJed Brown #define __FUNCT__ "DMRestrictHook_SNESVecSol"
325dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx)
326dfe15315SJed Brown {
327dfe15315SJed Brown   SNES snes = (SNES)ctx;
328dfe15315SJed Brown   PetscErrorCode ierr;
329dfe15315SJed Brown   Vec Xfine,Xfine_named = PETSC_NULL,Xcoarse;
330dfe15315SJed Brown 
331dfe15315SJed Brown   PetscFunctionBegin;
332dfe15315SJed Brown   if (dmfine == snes->dm) Xfine = snes->vec_sol;
333dfe15315SJed Brown   else {
334dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);
335dfe15315SJed Brown     Xfine = Xfine_named;
336dfe15315SJed Brown   }
337dfe15315SJed Brown   ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
338dfe15315SJed Brown   ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr);
339dfe15315SJed Brown   ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr);
340dfe15315SJed Brown   ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
341dfe15315SJed Brown   if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);}
342dfe15315SJed Brown   PetscFunctionReturn(0);
343dfe15315SJed Brown }
344dfe15315SJed Brown 
345dfe15315SJed Brown #undef __FUNCT__
346caa4e7f2SJed Brown #define __FUNCT__ "KSPComputeOperators_SNES"
347a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can
348a6950cb2SJed Brown  * safely call SNESGetDM() in their residual evaluation routine. */
349caa4e7f2SJed Brown static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,MatStructure *mstruct,void *ctx)
350caa4e7f2SJed Brown {
351caa4e7f2SJed Brown   SNES snes = (SNES)ctx;
352caa4e7f2SJed Brown   PetscErrorCode ierr;
353caa4e7f2SJed Brown   Mat Asave = A,Bsave = B;
354dfe15315SJed Brown   Vec X,Xnamed = PETSC_NULL;
355dfe15315SJed Brown   DM dmsave;
356caa4e7f2SJed Brown 
357caa4e7f2SJed Brown   PetscFunctionBegin;
358dfe15315SJed Brown   dmsave = snes->dm;
359dfe15315SJed Brown   ierr = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr);
360dfe15315SJed Brown   if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */
361dfe15315SJed Brown   else {                                     /* We are on a coarser level, this vec was initialized using a DM restrict hook */
362dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
363dfe15315SJed Brown     X = Xnamed;
364dfe15315SJed Brown   }
365dfe15315SJed Brown   ierr = SNESComputeJacobian(snes,X,&A,&B,mstruct);CHKERRQ(ierr);
366caa4e7f2SJed Brown   if (A != Asave || B != Bsave) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_SUP,"No support for changing matrices at this time");
367dfe15315SJed Brown   if (Xnamed) {
368dfe15315SJed Brown     ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
369dfe15315SJed Brown   }
370dfe15315SJed Brown   snes->dm = dmsave;
371caa4e7f2SJed Brown   PetscFunctionReturn(0);
372caa4e7f2SJed Brown }
373caa4e7f2SJed Brown 
374caa4e7f2SJed Brown #undef __FUNCT__
3756cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices"
3766cab3a1bSJed Brown /*@
3776cab3a1bSJed Brown    SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX()
3786cab3a1bSJed Brown 
3796cab3a1bSJed Brown    Collective
3806cab3a1bSJed Brown 
3816cab3a1bSJed Brown    Input Arguments:
3826cab3a1bSJed Brown .  snes - snes to configure
3836cab3a1bSJed Brown 
3846cab3a1bSJed Brown    Level: developer
3856cab3a1bSJed Brown 
3866cab3a1bSJed Brown .seealso: SNESSetUp()
3876cab3a1bSJed Brown @*/
3886cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes)
3896cab3a1bSJed Brown {
3906cab3a1bSJed Brown   PetscErrorCode ierr;
3916cab3a1bSJed Brown   DM             dm;
3926cab3a1bSJed Brown   SNESDM         sdm;
3936cab3a1bSJed Brown 
3946cab3a1bSJed Brown   PetscFunctionBegin;
3956cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3966cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
397caa4e7f2SJed Brown   if (!sdm->computejacobian) {
3986cab3a1bSJed Brown     Mat J,B;
3996cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4006cab3a1bSJed Brown     if (snes->mf_operator) {
4016cab3a1bSJed Brown       ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4026cab3a1bSJed Brown       ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4036cab3a1bSJed Brown       ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4046cab3a1bSJed Brown     } else {
4056cab3a1bSJed Brown       J = B;
4066cab3a1bSJed Brown       ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
4076cab3a1bSJed Brown     }
4086cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr);
4096cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
4106cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
4116cab3a1bSJed Brown   } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) {
4126cab3a1bSJed Brown     Mat J;
4136cab3a1bSJed Brown     void *functx;
4146cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4156cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4166cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4176cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
4186cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
4196cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
420caa4e7f2SJed Brown   } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
4216cab3a1bSJed Brown     Mat J,B;
4226cab3a1bSJed Brown     void *functx;
4236cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4246cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4256cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4266cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4276cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
4286cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,functx);CHKERRQ(ierr);
4296cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
4306cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
431caa4e7f2SJed Brown   } else if (!snes->jacobian_pre) {
4326cab3a1bSJed Brown     Mat J,B;
4336cab3a1bSJed Brown     J = snes->jacobian;
4346cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4356cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
4366cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
4376cab3a1bSJed Brown   }
438caa4e7f2SJed Brown   {
43960a3618bSJed Brown     PetscBool flg = PETSC_FALSE;
440caa4e7f2SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_kspcompute",&flg,PETSC_NULL);CHKERRQ(ierr);
441caa4e7f2SJed Brown     if (flg) {                  /* Plan to transition to this model */
442caa4e7f2SJed Brown       KSP ksp;
443caa4e7f2SJed Brown       ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
444caa4e7f2SJed Brown       ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr);
445dfe15315SJed Brown       ierr = DMCoarsenHookAdd(snes->dm,PETSC_NULL,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr);
446caa4e7f2SJed Brown     }
447caa4e7f2SJed Brown   }
4486cab3a1bSJed Brown   PetscFunctionReturn(0);
4496cab3a1bSJed Brown }
4506cab3a1bSJed Brown 
4516cab3a1bSJed Brown #undef __FUNCT__
4524a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions"
4539b94acceSBarry Smith /*@
45494b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
4559b94acceSBarry Smith 
456c7afd0dbSLois Curfman McInnes    Collective on SNES
457c7afd0dbSLois Curfman McInnes 
4589b94acceSBarry Smith    Input Parameter:
4599b94acceSBarry Smith .  snes - the SNES context
4609b94acceSBarry Smith 
46136851e7fSLois Curfman McInnes    Options Database Keys:
462ea630c6eSPeter Brune +  -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas
46382738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
46482738288SBarry Smith                 of the change in the solution between steps
46570441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
466b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
467b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
468b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
4694839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
470ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
471a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
472e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
473b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
4742492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
47582738288SBarry Smith                                solver; hence iterations will continue until max_it
4761fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
47782738288SBarry Smith                                of convergence test
478e8105e01SRichard Katz .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
479e8105e01SRichard Katz                                        filename given prints to stdout
480a6570f20SBarry Smith .  -snes_monitor_solution - plots solution at each iteration
481a6570f20SBarry Smith .  -snes_monitor_residual - plots residual (not its norm) at each iteration
482a6570f20SBarry Smith .  -snes_monitor_solution_update - plots update to solution at each iteration
483a6570f20SBarry Smith .  -snes_monitor_draw - plots residual norm at each iteration
484e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
4855968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
486fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
48782738288SBarry Smith 
48882738288SBarry Smith     Options Database for Eisenstat-Walker method:
489fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
4904b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
49136851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
49236851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
49336851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
49436851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
49536851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
49636851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
49782738288SBarry Smith 
49811ca99fdSLois Curfman McInnes    Notes:
49911ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
5000598bfebSBarry Smith    the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>.
50183e2fdc7SBarry Smith 
50236851e7fSLois Curfman McInnes    Level: beginner
50336851e7fSLois Curfman McInnes 
5049b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
5059b94acceSBarry Smith 
50669ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
5079b94acceSBarry Smith @*/
5087087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
5099b94acceSBarry Smith {
510872b6db9SPeter Brune   PetscBool               flg,mf,mf_operator,pcset;
511efd51863SBarry Smith   PetscInt                i,indx,lag,mf_version,grids;
512aa3661deSLisandro Dalcin   MatStructure            matflag;
51385385478SLisandro Dalcin   const char              *deft = SNESLS;
51485385478SLisandro Dalcin   const char              *convtests[] = {"default","skip"};
51585385478SLisandro Dalcin   SNESKSPEW               *kctx = NULL;
516e8105e01SRichard Katz   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
517649052a6SBarry Smith   PetscViewer             monviewer;
51885385478SLisandro Dalcin   PetscErrorCode          ierr;
519a64e098fSPeter Brune   const char              *optionsprefix;
5209b94acceSBarry Smith 
5213a40ed3dSBarry Smith   PetscFunctionBegin;
5220700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
523ca161407SBarry Smith 
524186905e3SBarry Smith   if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
5253194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
5267adad957SLisandro Dalcin     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
527b0a32e0cSBarry Smith     ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
528d64ed03dSBarry Smith     if (flg) {
529186905e3SBarry Smith       ierr = SNESSetType(snes,type);CHKERRQ(ierr);
5307adad957SLisandro Dalcin     } else if (!((PetscObject)snes)->type_name) {
531186905e3SBarry Smith       ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
532d64ed03dSBarry Smith     }
53390d69ab7SBarry Smith     /* not used here, but called so will go into help messaage */
534909c8a9fSBarry Smith     ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr);
53593c39befSBarry Smith 
536c60f73f4SPeter Brune     ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);CHKERRQ(ierr);
53757034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr);
538186905e3SBarry Smith 
53957034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr);
540b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr);
541b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr);
54224254dc1SJed Brown     ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr);
543ddf469c8SBarry Smith     ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr);
544acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr);
54585385478SLisandro Dalcin 
546a8054027SBarry Smith     ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
547a8054027SBarry Smith     if (flg) {
548a8054027SBarry Smith       ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
549a8054027SBarry Smith     }
550e35cf81dSBarry Smith     ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
551e35cf81dSBarry Smith     if (flg) {
552e35cf81dSBarry Smith       ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
553e35cf81dSBarry Smith     }
554efd51863SBarry Smith     ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
555efd51863SBarry Smith     if (flg) {
556efd51863SBarry Smith       ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
557efd51863SBarry Smith     }
558a8054027SBarry Smith 
55985385478SLisandro Dalcin     ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
56085385478SLisandro Dalcin     if (flg) {
56185385478SLisandro Dalcin       switch (indx) {
5627f7931b9SBarry Smith       case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break;
5637f7931b9SBarry Smith       case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);    break;
56485385478SLisandro Dalcin       }
56585385478SLisandro Dalcin     }
56685385478SLisandro Dalcin 
567acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr);
568186905e3SBarry Smith 
569fdacfa88SPeter Brune     ierr = PetscOptionsEList("-snes_norm_type","SNES Norm type","SNESSetNormType",SNESNormTypes,5,"function",&indx,&flg);CHKERRQ(ierr);
570fdacfa88SPeter Brune     if (flg) { ierr = SNESSetNormType(snes,(SNESNormType)indx);CHKERRQ(ierr); }
571fdacfa88SPeter Brune 
57285385478SLisandro Dalcin     kctx = (SNESKSPEW *)snes->kspconvctx;
57385385478SLisandro Dalcin 
574acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr);
575186905e3SBarry Smith 
576fa9f3622SBarry Smith     ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr);
577fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr);
578fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr);
579fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr);
580fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr);
581fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr);
582fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr);
583186905e3SBarry Smith 
58490d69ab7SBarry Smith     flg  = PETSC_FALSE;
585acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
586a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
587eabae89aSBarry Smith 
588a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
589e8105e01SRichard Katz     if (flg) {
590649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
591649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
592e8105e01SRichard Katz     }
593eabae89aSBarry Smith 
594b271bb04SBarry Smith     ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
595b271bb04SBarry Smith     if (flg) {
596b271bb04SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr);
597b271bb04SBarry Smith     }
598b271bb04SBarry Smith 
599a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
600eabae89aSBarry Smith     if (flg) {
601649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
602f1bef1bcSMatthew Knepley       ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr);
603e8105e01SRichard Katz     }
604eabae89aSBarry Smith 
605a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
606eabae89aSBarry Smith     if (flg) {
607649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
608649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
609eabae89aSBarry Smith     }
610eabae89aSBarry Smith 
6115180491cSLisandro Dalcin     ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
6125180491cSLisandro Dalcin     if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);}
6135180491cSLisandro Dalcin 
61490d69ab7SBarry Smith     flg  = PETSC_FALSE;
615acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
616a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
61790d69ab7SBarry Smith     flg  = PETSC_FALSE;
618acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
619a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
62090d69ab7SBarry Smith     flg  = PETSC_FALSE;
621acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
622a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
62390d69ab7SBarry Smith     flg  = PETSC_FALSE;
624acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
625a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
62690d69ab7SBarry Smith     flg  = PETSC_FALSE;
627acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
628b271bb04SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
629e24b481bSBarry Smith 
63090d69ab7SBarry Smith     flg  = PETSC_FALSE;
631acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
6324b27c08aSLois Curfman McInnes     if (flg) {
6336cab3a1bSJed Brown       void *functx;
6346cab3a1bSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
6356cab3a1bSJed Brown       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr);
636ae15b995SBarry Smith       ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
6379b94acceSBarry Smith     }
638639f9d9dSBarry Smith 
639aa3661deSLisandro Dalcin     mf = mf_operator = PETSC_FALSE;
640aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
641acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr);
642a8248277SBarry Smith     if (flg && mf_operator) {
643a8248277SBarry Smith       snes->mf_operator = PETSC_TRUE;
644a8248277SBarry Smith       mf = PETSC_TRUE;
645a8248277SBarry Smith     }
646aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
647acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr);
648aa3661deSLisandro Dalcin     if (!flg && mf_operator) mf = PETSC_TRUE;
649aa3661deSLisandro Dalcin     mf_version = 1;
650aa3661deSLisandro Dalcin     ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr);
651aa3661deSLisandro Dalcin 
652d28543b3SPeter Brune 
65389b92e6fSPeter Brune     /* GS Options */
65489b92e6fSPeter Brune     ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr);
65589b92e6fSPeter Brune 
65676b2cf59SMatthew Knepley     for(i = 0; i < numberofsetfromoptions; i++) {
65776b2cf59SMatthew Knepley       ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
65876b2cf59SMatthew Knepley     }
65976b2cf59SMatthew Knepley 
660e7788613SBarry Smith     if (snes->ops->setfromoptions) {
661e7788613SBarry Smith       ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr);
662639f9d9dSBarry Smith     }
6635d973c19SBarry Smith 
6645d973c19SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
6655d973c19SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr);
666b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
6674bbc92c1SBarry Smith 
668aa3661deSLisandro Dalcin   if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); }
6691cee3971SBarry Smith 
6701cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
671aa3661deSLisandro Dalcin   ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
672aa3661deSLisandro Dalcin   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr);
67385385478SLisandro Dalcin   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
67493993e2dSLois Curfman McInnes 
6759e764e56SPeter Brune   if (!snes->linesearch) {
676f1c6b773SPeter Brune     ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
6779e764e56SPeter Brune   }
678f1c6b773SPeter Brune   ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr);
6799e764e56SPeter Brune 
68051e86f29SPeter Brune   /* if someone has set the SNES PC type, create it. */
68151e86f29SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
68251e86f29SPeter Brune   ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr);
68351e86f29SPeter Brune   if (pcset && (!snes->pc)) {
68451e86f29SPeter Brune     ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr);
68551e86f29SPeter Brune   }
6863a40ed3dSBarry Smith   PetscFunctionReturn(0);
6879b94acceSBarry Smith }
6889b94acceSBarry Smith 
689d25893d9SBarry Smith #undef __FUNCT__
690d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext"
691d25893d9SBarry Smith /*@
692d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
693d25893d9SBarry Smith    the nonlinear solvers.
694d25893d9SBarry Smith 
695d25893d9SBarry Smith    Logically Collective on SNES
696d25893d9SBarry Smith 
697d25893d9SBarry Smith    Input Parameters:
698d25893d9SBarry Smith +  snes - the SNES context
699d25893d9SBarry Smith .  compute - function to compute the context
700d25893d9SBarry Smith -  destroy - function to destroy the context
701d25893d9SBarry Smith 
702d25893d9SBarry Smith    Level: intermediate
703d25893d9SBarry Smith 
704d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
705d25893d9SBarry Smith 
706d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
707d25893d9SBarry Smith @*/
708d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
709d25893d9SBarry Smith {
710d25893d9SBarry Smith   PetscFunctionBegin;
711d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
712d25893d9SBarry Smith   snes->ops->usercompute = compute;
713d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
714d25893d9SBarry Smith   PetscFunctionReturn(0);
715d25893d9SBarry Smith }
716a847f771SSatish Balay 
7174a2ae208SSatish Balay #undef __FUNCT__
7184a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
719b07ff414SBarry Smith /*@
7209b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
7219b94acceSBarry Smith    the nonlinear solvers.
7229b94acceSBarry Smith 
7233f9fe445SBarry Smith    Logically Collective on SNES
724fee21e36SBarry Smith 
725c7afd0dbSLois Curfman McInnes    Input Parameters:
726c7afd0dbSLois Curfman McInnes +  snes - the SNES context
727c7afd0dbSLois Curfman McInnes -  usrP - optional user context
728c7afd0dbSLois Curfman McInnes 
72936851e7fSLois Curfman McInnes    Level: intermediate
73036851e7fSLois Curfman McInnes 
7319b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
7329b94acceSBarry Smith 
733ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext()
7349b94acceSBarry Smith @*/
7357087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
7369b94acceSBarry Smith {
7371b2093e4SBarry Smith   PetscErrorCode ierr;
738b07ff414SBarry Smith   KSP            ksp;
7391b2093e4SBarry Smith 
7403a40ed3dSBarry Smith   PetscFunctionBegin;
7410700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
742b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
743b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
7449b94acceSBarry Smith   snes->user = usrP;
7453a40ed3dSBarry Smith   PetscFunctionReturn(0);
7469b94acceSBarry Smith }
74774679c65SBarry Smith 
7484a2ae208SSatish Balay #undef __FUNCT__
7494a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
750b07ff414SBarry Smith /*@
7519b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
7529b94acceSBarry Smith    nonlinear solvers.
7539b94acceSBarry Smith 
754c7afd0dbSLois Curfman McInnes    Not Collective
755c7afd0dbSLois Curfman McInnes 
7569b94acceSBarry Smith    Input Parameter:
7579b94acceSBarry Smith .  snes - SNES context
7589b94acceSBarry Smith 
7599b94acceSBarry Smith    Output Parameter:
7609b94acceSBarry Smith .  usrP - user context
7619b94acceSBarry Smith 
76236851e7fSLois Curfman McInnes    Level: intermediate
76336851e7fSLois Curfman McInnes 
7649b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
7659b94acceSBarry Smith 
7669b94acceSBarry Smith .seealso: SNESSetApplicationContext()
7679b94acceSBarry Smith @*/
768e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
7699b94acceSBarry Smith {
7703a40ed3dSBarry Smith   PetscFunctionBegin;
7710700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
772e71120c6SJed Brown   *(void**)usrP = snes->user;
7733a40ed3dSBarry Smith   PetscFunctionReturn(0);
7749b94acceSBarry Smith }
77574679c65SBarry Smith 
7764a2ae208SSatish Balay #undef __FUNCT__
7774a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
7789b94acceSBarry Smith /*@
779c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
780c8228a4eSBarry Smith    at this time.
7819b94acceSBarry Smith 
782c7afd0dbSLois Curfman McInnes    Not Collective
783c7afd0dbSLois Curfman McInnes 
7849b94acceSBarry Smith    Input Parameter:
7859b94acceSBarry Smith .  snes - SNES context
7869b94acceSBarry Smith 
7879b94acceSBarry Smith    Output Parameter:
7889b94acceSBarry Smith .  iter - iteration number
7899b94acceSBarry Smith 
790c8228a4eSBarry Smith    Notes:
791c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
792c8228a4eSBarry Smith 
793c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
79408405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
79508405cd6SLois Curfman McInnes .vb
79608405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
79708405cd6SLois Curfman McInnes       if (!(it % 2)) {
79808405cd6SLois Curfman McInnes         [compute Jacobian here]
79908405cd6SLois Curfman McInnes       }
80008405cd6SLois Curfman McInnes .ve
801c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
80208405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
803c8228a4eSBarry Smith 
80436851e7fSLois Curfman McInnes    Level: intermediate
80536851e7fSLois Curfman McInnes 
8062b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
8072b668275SBarry Smith 
808b850b91aSLisandro Dalcin .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
8099b94acceSBarry Smith @*/
8107087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
8119b94acceSBarry Smith {
8123a40ed3dSBarry Smith   PetscFunctionBegin;
8130700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8144482741eSBarry Smith   PetscValidIntPointer(iter,2);
8159b94acceSBarry Smith   *iter = snes->iter;
8163a40ed3dSBarry Smith   PetscFunctionReturn(0);
8179b94acceSBarry Smith }
81874679c65SBarry Smith 
8194a2ae208SSatish Balay #undef __FUNCT__
820360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber"
821360c497dSPeter Brune /*@
822360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
823360c497dSPeter Brune 
824360c497dSPeter Brune    Not Collective
825360c497dSPeter Brune 
826360c497dSPeter Brune    Input Parameter:
827360c497dSPeter Brune .  snes - SNES context
828360c497dSPeter Brune .  iter - iteration number
829360c497dSPeter Brune 
830360c497dSPeter Brune    Level: developer
831360c497dSPeter Brune 
832360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number,
833360c497dSPeter Brune 
834360c497dSPeter Brune .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
835360c497dSPeter Brune @*/
836360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
837360c497dSPeter Brune {
838360c497dSPeter Brune   PetscErrorCode ierr;
839360c497dSPeter Brune 
840360c497dSPeter Brune   PetscFunctionBegin;
841360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
842360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
843360c497dSPeter Brune   snes->iter = iter;
844360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
845360c497dSPeter Brune   PetscFunctionReturn(0);
846360c497dSPeter Brune }
847360c497dSPeter Brune 
848360c497dSPeter Brune #undef __FUNCT__
8494a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm"
8509b94acceSBarry Smith /*@
8519b94acceSBarry Smith    SNESGetFunctionNorm - Gets the norm of the current function that was set
8529b94acceSBarry Smith    with SNESSSetFunction().
8539b94acceSBarry Smith 
854c7afd0dbSLois Curfman McInnes    Collective on SNES
855c7afd0dbSLois Curfman McInnes 
8569b94acceSBarry Smith    Input Parameter:
8579b94acceSBarry Smith .  snes - SNES context
8589b94acceSBarry Smith 
8599b94acceSBarry Smith    Output Parameter:
8609b94acceSBarry Smith .  fnorm - 2-norm of function
8619b94acceSBarry Smith 
86236851e7fSLois Curfman McInnes    Level: intermediate
86336851e7fSLois Curfman McInnes 
8649b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm
865a86d99e1SLois Curfman McInnes 
866b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
8679b94acceSBarry Smith @*/
8687087cfbeSBarry Smith PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
8699b94acceSBarry Smith {
8703a40ed3dSBarry Smith   PetscFunctionBegin;
8710700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8724482741eSBarry Smith   PetscValidScalarPointer(fnorm,2);
8739b94acceSBarry Smith   *fnorm = snes->norm;
8743a40ed3dSBarry Smith   PetscFunctionReturn(0);
8759b94acceSBarry Smith }
87674679c65SBarry Smith 
877360c497dSPeter Brune 
878360c497dSPeter Brune #undef __FUNCT__
879360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm"
880360c497dSPeter Brune /*@
881360c497dSPeter Brune    SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm().
882360c497dSPeter Brune 
883360c497dSPeter Brune    Collective on SNES
884360c497dSPeter Brune 
885360c497dSPeter Brune    Input Parameter:
886360c497dSPeter Brune .  snes - SNES context
887360c497dSPeter Brune .  fnorm - 2-norm of function
888360c497dSPeter Brune 
889360c497dSPeter Brune    Level: developer
890360c497dSPeter Brune 
891360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm
892360c497dSPeter Brune 
893360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm().
894360c497dSPeter Brune @*/
895360c497dSPeter Brune PetscErrorCode  SNESSetFunctionNorm(SNES snes,PetscReal fnorm)
896360c497dSPeter Brune {
897360c497dSPeter Brune 
898360c497dSPeter Brune   PetscErrorCode ierr;
899360c497dSPeter Brune 
900360c497dSPeter Brune   PetscFunctionBegin;
901360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
902360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
903360c497dSPeter Brune   snes->norm = fnorm;
904360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
905360c497dSPeter Brune   PetscFunctionReturn(0);
906360c497dSPeter Brune }
907360c497dSPeter Brune 
9084a2ae208SSatish Balay #undef __FUNCT__
909b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
9109b94acceSBarry Smith /*@
911b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
9129b94acceSBarry Smith    attempted by the nonlinear solver.
9139b94acceSBarry Smith 
914c7afd0dbSLois Curfman McInnes    Not Collective
915c7afd0dbSLois Curfman McInnes 
9169b94acceSBarry Smith    Input Parameter:
9179b94acceSBarry Smith .  snes - SNES context
9189b94acceSBarry Smith 
9199b94acceSBarry Smith    Output Parameter:
9209b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
9219b94acceSBarry Smith 
922c96a6f78SLois Curfman McInnes    Notes:
923c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
924c96a6f78SLois Curfman McInnes 
92536851e7fSLois Curfman McInnes    Level: intermediate
92636851e7fSLois Curfman McInnes 
9279b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
92858ebbce7SBarry Smith 
929e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
93058ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
9319b94acceSBarry Smith @*/
9327087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
9339b94acceSBarry Smith {
9343a40ed3dSBarry Smith   PetscFunctionBegin;
9350700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9364482741eSBarry Smith   PetscValidIntPointer(nfails,2);
93750ffb88aSMatthew Knepley   *nfails = snes->numFailures;
93850ffb88aSMatthew Knepley   PetscFunctionReturn(0);
93950ffb88aSMatthew Knepley }
94050ffb88aSMatthew Knepley 
94150ffb88aSMatthew Knepley #undef __FUNCT__
942b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
94350ffb88aSMatthew Knepley /*@
944b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
94550ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
94650ffb88aSMatthew Knepley 
94750ffb88aSMatthew Knepley    Not Collective
94850ffb88aSMatthew Knepley 
94950ffb88aSMatthew Knepley    Input Parameters:
95050ffb88aSMatthew Knepley +  snes     - SNES context
95150ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
95250ffb88aSMatthew Knepley 
95350ffb88aSMatthew Knepley    Level: intermediate
95450ffb88aSMatthew Knepley 
95550ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
95658ebbce7SBarry Smith 
957e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
95858ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
95950ffb88aSMatthew Knepley @*/
9607087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
96150ffb88aSMatthew Knepley {
96250ffb88aSMatthew Knepley   PetscFunctionBegin;
9630700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
96450ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
96550ffb88aSMatthew Knepley   PetscFunctionReturn(0);
96650ffb88aSMatthew Knepley }
96750ffb88aSMatthew Knepley 
96850ffb88aSMatthew Knepley #undef __FUNCT__
969b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
97050ffb88aSMatthew Knepley /*@
971b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
97250ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
97350ffb88aSMatthew Knepley 
97450ffb88aSMatthew Knepley    Not Collective
97550ffb88aSMatthew Knepley 
97650ffb88aSMatthew Knepley    Input Parameter:
97750ffb88aSMatthew Knepley .  snes     - SNES context
97850ffb88aSMatthew Knepley 
97950ffb88aSMatthew Knepley    Output Parameter:
98050ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
98150ffb88aSMatthew Knepley 
98250ffb88aSMatthew Knepley    Level: intermediate
98350ffb88aSMatthew Knepley 
98450ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
98558ebbce7SBarry Smith 
986e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
98758ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
98858ebbce7SBarry Smith 
98950ffb88aSMatthew Knepley @*/
9907087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
99150ffb88aSMatthew Knepley {
99250ffb88aSMatthew Knepley   PetscFunctionBegin;
9930700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9944482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
99550ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
9963a40ed3dSBarry Smith   PetscFunctionReturn(0);
9979b94acceSBarry Smith }
998a847f771SSatish Balay 
9994a2ae208SSatish Balay #undef __FUNCT__
10002541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
10012541af92SBarry Smith /*@
10022541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
10032541af92SBarry Smith      done by SNES.
10042541af92SBarry Smith 
10052541af92SBarry Smith    Not Collective
10062541af92SBarry Smith 
10072541af92SBarry Smith    Input Parameter:
10082541af92SBarry Smith .  snes     - SNES context
10092541af92SBarry Smith 
10102541af92SBarry Smith    Output Parameter:
10112541af92SBarry Smith .  nfuncs - number of evaluations
10122541af92SBarry Smith 
10132541af92SBarry Smith    Level: intermediate
10142541af92SBarry Smith 
10152541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
101658ebbce7SBarry Smith 
1017e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
10182541af92SBarry Smith @*/
10197087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
10202541af92SBarry Smith {
10212541af92SBarry Smith   PetscFunctionBegin;
10220700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10232541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
10242541af92SBarry Smith   *nfuncs = snes->nfuncs;
10252541af92SBarry Smith   PetscFunctionReturn(0);
10262541af92SBarry Smith }
10272541af92SBarry Smith 
10282541af92SBarry Smith #undef __FUNCT__
10293d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
10303d4c4710SBarry Smith /*@
10313d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
10323d4c4710SBarry Smith    linear solvers.
10333d4c4710SBarry Smith 
10343d4c4710SBarry Smith    Not Collective
10353d4c4710SBarry Smith 
10363d4c4710SBarry Smith    Input Parameter:
10373d4c4710SBarry Smith .  snes - SNES context
10383d4c4710SBarry Smith 
10393d4c4710SBarry Smith    Output Parameter:
10403d4c4710SBarry Smith .  nfails - number of failed solves
10413d4c4710SBarry Smith 
10423d4c4710SBarry Smith    Notes:
10433d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
10443d4c4710SBarry Smith 
10453d4c4710SBarry Smith    Level: intermediate
10463d4c4710SBarry Smith 
10473d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
104858ebbce7SBarry Smith 
1049e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
10503d4c4710SBarry Smith @*/
10517087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
10523d4c4710SBarry Smith {
10533d4c4710SBarry Smith   PetscFunctionBegin;
10540700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10553d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
10563d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
10573d4c4710SBarry Smith   PetscFunctionReturn(0);
10583d4c4710SBarry Smith }
10593d4c4710SBarry Smith 
10603d4c4710SBarry Smith #undef __FUNCT__
10613d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
10623d4c4710SBarry Smith /*@
10633d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
10643d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
10653d4c4710SBarry Smith 
10663f9fe445SBarry Smith    Logically Collective on SNES
10673d4c4710SBarry Smith 
10683d4c4710SBarry Smith    Input Parameters:
10693d4c4710SBarry Smith +  snes     - SNES context
10703d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
10713d4c4710SBarry Smith 
10723d4c4710SBarry Smith    Level: intermediate
10733d4c4710SBarry Smith 
1074a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
10753d4c4710SBarry Smith 
10763d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
10773d4c4710SBarry Smith 
107858ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
10793d4c4710SBarry Smith @*/
10807087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
10813d4c4710SBarry Smith {
10823d4c4710SBarry Smith   PetscFunctionBegin;
10830700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1084c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
10853d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
10863d4c4710SBarry Smith   PetscFunctionReturn(0);
10873d4c4710SBarry Smith }
10883d4c4710SBarry Smith 
10893d4c4710SBarry Smith #undef __FUNCT__
10903d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
10913d4c4710SBarry Smith /*@
10923d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
10933d4c4710SBarry Smith      are allowed before SNES terminates
10943d4c4710SBarry Smith 
10953d4c4710SBarry Smith    Not Collective
10963d4c4710SBarry Smith 
10973d4c4710SBarry Smith    Input Parameter:
10983d4c4710SBarry Smith .  snes     - SNES context
10993d4c4710SBarry Smith 
11003d4c4710SBarry Smith    Output Parameter:
11013d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
11023d4c4710SBarry Smith 
11033d4c4710SBarry Smith    Level: intermediate
11043d4c4710SBarry Smith 
11053d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
11063d4c4710SBarry Smith 
11073d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
11083d4c4710SBarry Smith 
1109e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
11103d4c4710SBarry Smith @*/
11117087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
11123d4c4710SBarry Smith {
11133d4c4710SBarry Smith   PetscFunctionBegin;
11140700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11153d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
11163d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
11173d4c4710SBarry Smith   PetscFunctionReturn(0);
11183d4c4710SBarry Smith }
11193d4c4710SBarry Smith 
11203d4c4710SBarry Smith #undef __FUNCT__
1121b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
1122c96a6f78SLois Curfman McInnes /*@
1123b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1124c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1125c96a6f78SLois Curfman McInnes 
1126c7afd0dbSLois Curfman McInnes    Not Collective
1127c7afd0dbSLois Curfman McInnes 
1128c96a6f78SLois Curfman McInnes    Input Parameter:
1129c96a6f78SLois Curfman McInnes .  snes - SNES context
1130c96a6f78SLois Curfman McInnes 
1131c96a6f78SLois Curfman McInnes    Output Parameter:
1132c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1133c96a6f78SLois Curfman McInnes 
1134c96a6f78SLois Curfman McInnes    Notes:
1135c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1136c96a6f78SLois Curfman McInnes 
113736851e7fSLois Curfman McInnes    Level: intermediate
113836851e7fSLois Curfman McInnes 
1139c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
11402b668275SBarry Smith 
11418c7482ecSBarry Smith .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
1142c96a6f78SLois Curfman McInnes @*/
11437087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
1144c96a6f78SLois Curfman McInnes {
11453a40ed3dSBarry Smith   PetscFunctionBegin;
11460700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11474482741eSBarry Smith   PetscValidIntPointer(lits,2);
1148c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
11493a40ed3dSBarry Smith   PetscFunctionReturn(0);
1150c96a6f78SLois Curfman McInnes }
1151c96a6f78SLois Curfman McInnes 
11524a2ae208SSatish Balay #undef __FUNCT__
115394b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP"
115452baeb72SSatish Balay /*@
115594b7f48cSBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
11569b94acceSBarry Smith 
115794b7f48cSBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
1158c7afd0dbSLois Curfman McInnes 
11599b94acceSBarry Smith    Input Parameter:
11609b94acceSBarry Smith .  snes - the SNES context
11619b94acceSBarry Smith 
11629b94acceSBarry Smith    Output Parameter:
116394b7f48cSBarry Smith .  ksp - the KSP context
11649b94acceSBarry Smith 
11659b94acceSBarry Smith    Notes:
116694b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
11679b94acceSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
11682999313aSBarry Smith    PC contexts as well.
11699b94acceSBarry Smith 
117036851e7fSLois Curfman McInnes    Level: beginner
117136851e7fSLois Curfman McInnes 
117294b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
11739b94acceSBarry Smith 
11742999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
11759b94acceSBarry Smith @*/
11767087cfbeSBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
11779b94acceSBarry Smith {
11781cee3971SBarry Smith   PetscErrorCode ierr;
11791cee3971SBarry Smith 
11803a40ed3dSBarry Smith   PetscFunctionBegin;
11810700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11824482741eSBarry Smith   PetscValidPointer(ksp,2);
11831cee3971SBarry Smith 
11841cee3971SBarry Smith   if (!snes->ksp) {
11851cee3971SBarry Smith     ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr);
11861cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
11871cee3971SBarry Smith     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
11881cee3971SBarry Smith   }
118994b7f48cSBarry Smith   *ksp = snes->ksp;
11903a40ed3dSBarry Smith   PetscFunctionReturn(0);
11919b94acceSBarry Smith }
119282bf6240SBarry Smith 
11934a2ae208SSatish Balay #undef __FUNCT__
11942999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
11952999313aSBarry Smith /*@
11962999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
11972999313aSBarry Smith 
11982999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
11992999313aSBarry Smith 
12002999313aSBarry Smith    Input Parameters:
12012999313aSBarry Smith +  snes - the SNES context
12022999313aSBarry Smith -  ksp - the KSP context
12032999313aSBarry Smith 
12042999313aSBarry Smith    Notes:
12052999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
12062999313aSBarry Smith    so this routine is rarely needed.
12072999313aSBarry Smith 
12082999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
12092999313aSBarry Smith    decreased by one.
12102999313aSBarry Smith 
12112999313aSBarry Smith    Level: developer
12122999313aSBarry Smith 
12132999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
12142999313aSBarry Smith 
12152999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
12162999313aSBarry Smith @*/
12177087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
12182999313aSBarry Smith {
12192999313aSBarry Smith   PetscErrorCode ierr;
12202999313aSBarry Smith 
12212999313aSBarry Smith   PetscFunctionBegin;
12220700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12230700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
12242999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
12257dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1226906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
12272999313aSBarry Smith   snes->ksp = ksp;
12282999313aSBarry Smith   PetscFunctionReturn(0);
12292999313aSBarry Smith }
12302999313aSBarry Smith 
12317adad957SLisandro Dalcin #if 0
12322999313aSBarry Smith #undef __FUNCT__
12334a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc"
12346849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
1235e24b481bSBarry Smith {
1236e24b481bSBarry Smith   PetscFunctionBegin;
1237e24b481bSBarry Smith   PetscFunctionReturn(0);
1238e24b481bSBarry Smith }
12397adad957SLisandro Dalcin #endif
1240e24b481bSBarry Smith 
12419b94acceSBarry Smith /* -----------------------------------------------------------*/
12424a2ae208SSatish Balay #undef __FUNCT__
12434a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
124452baeb72SSatish Balay /*@
12459b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
12469b94acceSBarry Smith 
1247c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1248c7afd0dbSLois Curfman McInnes 
1249c7afd0dbSLois Curfman McInnes    Input Parameters:
1250906ed7ccSBarry Smith .  comm - MPI communicator
12519b94acceSBarry Smith 
12529b94acceSBarry Smith    Output Parameter:
12539b94acceSBarry Smith .  outsnes - the new SNES context
12549b94acceSBarry Smith 
1255c7afd0dbSLois Curfman McInnes    Options Database Keys:
1256c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1257c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1258c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1259c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1260c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1261c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1262c1f60f51SBarry Smith 
126336851e7fSLois Curfman McInnes    Level: beginner
126436851e7fSLois Curfman McInnes 
12659b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
12669b94acceSBarry Smith 
1267a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1268a8054027SBarry Smith 
12699b94acceSBarry Smith @*/
12707087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
12719b94acceSBarry Smith {
1272dfbe8321SBarry Smith   PetscErrorCode      ierr;
12739b94acceSBarry Smith   SNES                snes;
1274fa9f3622SBarry Smith   SNESKSPEW           *kctx;
127537fcc0dbSBarry Smith 
12763a40ed3dSBarry Smith   PetscFunctionBegin;
1277ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
12788ba1e511SMatthew Knepley   *outsnes = PETSC_NULL;
12798ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
12808ba1e511SMatthew Knepley   ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr);
12818ba1e511SMatthew Knepley #endif
12828ba1e511SMatthew Knepley 
12833194b578SJed Brown   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
12847adad957SLisandro Dalcin 
128585385478SLisandro Dalcin   snes->ops->converged    = SNESDefaultConverged;
12862c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
128788976e71SPeter Brune   snes->tolerancesset     = PETSC_FALSE;
12889b94acceSBarry Smith   snes->max_its           = 50;
12899750a799SBarry Smith   snes->max_funcs         = 10000;
12909b94acceSBarry Smith   snes->norm              = 0.0;
1291fdacfa88SPeter Brune   snes->normtype          = SNES_NORM_FUNCTION;
1292b4874afaSBarry Smith   snes->rtol              = 1.e-8;
1293b4874afaSBarry Smith   snes->ttol              = 0.0;
129470441072SBarry Smith   snes->abstol            = 1.e-50;
1295c60f73f4SPeter Brune   snes->stol              = 1.e-8;
12964b27c08aSLois Curfman McInnes   snes->deltatol          = 1.e-12;
12979b94acceSBarry Smith   snes->nfuncs            = 0;
129850ffb88aSMatthew Knepley   snes->numFailures       = 0;
129950ffb88aSMatthew Knepley   snes->maxFailures       = 1;
13007a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1301e35cf81dSBarry Smith   snes->lagjacobian       = 1;
1302a8054027SBarry Smith   snes->lagpreconditioner = 1;
1303639f9d9dSBarry Smith   snes->numbermonitors    = 0;
13049b94acceSBarry Smith   snes->data              = 0;
13054dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1306186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
13076f24a144SLois Curfman McInnes   snes->nwork             = 0;
130858c9b817SLisandro Dalcin   snes->work              = 0;
130958c9b817SLisandro Dalcin   snes->nvwork            = 0;
131058c9b817SLisandro Dalcin   snes->vwork             = 0;
1311758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1312758f92a0SBarry Smith   snes->conv_hist_max     = 0;
1313758f92a0SBarry Smith   snes->conv_hist         = PETSC_NULL;
1314758f92a0SBarry Smith   snes->conv_hist_its     = PETSC_NULL;
1315758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1316e4ed7901SPeter Brune   snes->vec_func_init_set = PETSC_FALSE;
1317e4ed7901SPeter Brune   snes->norm_init         = 0.;
1318e4ed7901SPeter Brune   snes->norm_init_set     = PETSC_FALSE;
1319184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
132089b92e6fSPeter Brune   snes->gssweeps          = 1;
13219b94acceSBarry Smith 
13223d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
13233d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
13243d4c4710SBarry Smith 
13259b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
132638f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr);
13279b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
13289b94acceSBarry Smith   kctx->version     = 2;
13299b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
13309b94acceSBarry Smith                              this was too large for some test cases */
133175567043SBarry Smith   kctx->rtol_last   = 0.0;
13329b94acceSBarry Smith   kctx->rtol_max    = .9;
13339b94acceSBarry Smith   kctx->gamma       = 1.0;
133462d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
133571f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
13369b94acceSBarry Smith   kctx->threshold   = .1;
133775567043SBarry Smith   kctx->lresid_last = 0.0;
133875567043SBarry Smith   kctx->norm_last   = 0.0;
13399b94acceSBarry Smith 
13409b94acceSBarry Smith   *outsnes = snes;
13413a40ed3dSBarry Smith   PetscFunctionReturn(0);
13429b94acceSBarry Smith }
13439b94acceSBarry Smith 
13444a2ae208SSatish Balay #undef __FUNCT__
13454a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
13469b94acceSBarry Smith /*@C
13479b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
13489b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
13499b94acceSBarry Smith    equations.
13509b94acceSBarry Smith 
13513f9fe445SBarry Smith    Logically Collective on SNES
1352fee21e36SBarry Smith 
1353c7afd0dbSLois Curfman McInnes    Input Parameters:
1354c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1355c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1356de044059SHong Zhang .  func - function evaluation routine
1357c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1358c7afd0dbSLois Curfman McInnes          function evaluation routine (may be PETSC_NULL)
13599b94acceSBarry Smith 
1360c7afd0dbSLois Curfman McInnes    Calling sequence of func:
13618d76a1e5SLois Curfman McInnes $    func (SNES snes,Vec x,Vec f,void *ctx);
1362c7afd0dbSLois Curfman McInnes 
1363c586c404SJed Brown +  snes - the SNES context
1364c586c404SJed Brown .  x - state at which to evaluate residual
1365c586c404SJed Brown .  f - vector to put residual
1366c7afd0dbSLois Curfman McInnes -  ctx - optional user-defined function context
13679b94acceSBarry Smith 
13689b94acceSBarry Smith    Notes:
13699b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
13709b94acceSBarry Smith $      f'(x) x = -f(x),
1371c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
13729b94acceSBarry Smith 
137336851e7fSLois Curfman McInnes    Level: beginner
137436851e7fSLois Curfman McInnes 
13759b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
13769b94acceSBarry Smith 
13778b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard()
13789b94acceSBarry Smith @*/
13797087cfbeSBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
13809b94acceSBarry Smith {
138185385478SLisandro Dalcin   PetscErrorCode ierr;
13826cab3a1bSJed Brown   DM             dm;
13836cab3a1bSJed Brown 
13843a40ed3dSBarry Smith   PetscFunctionBegin;
13850700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1386d2a683ecSLisandro Dalcin   if (r) {
1387d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1388d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
138985385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
13906bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
139185385478SLisandro Dalcin     snes->vec_func = r;
1392d2a683ecSLisandro Dalcin   }
13936cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
13946cab3a1bSJed Brown   ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr);
13953a40ed3dSBarry Smith   PetscFunctionReturn(0);
13969b94acceSBarry Smith }
13979b94acceSBarry Smith 
1398646217ecSPeter Brune 
1399646217ecSPeter Brune #undef __FUNCT__
1400e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction"
1401e4ed7901SPeter Brune /*@C
1402e4ed7901SPeter Brune    SNESSetInitialFunction - Sets the function vector to be used as the
1403e4ed7901SPeter Brune    function norm at the initialization of the method.  In some
1404e4ed7901SPeter Brune    instances, the user has precomputed the function before calling
1405e4ed7901SPeter Brune    SNESSolve.  This function allows one to avoid a redundant call
1406e4ed7901SPeter Brune    to SNESComputeFunction in that case.
1407e4ed7901SPeter Brune 
1408e4ed7901SPeter Brune    Logically Collective on SNES
1409e4ed7901SPeter Brune 
1410e4ed7901SPeter Brune    Input Parameters:
1411e4ed7901SPeter Brune +  snes - the SNES context
1412e4ed7901SPeter Brune -  f - vector to store function value
1413e4ed7901SPeter Brune 
1414e4ed7901SPeter Brune    Notes:
1415e4ed7901SPeter Brune    This should not be modified during the solution procedure.
1416e4ed7901SPeter Brune 
1417e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1418e4ed7901SPeter Brune 
1419e4ed7901SPeter Brune    Level: developer
1420e4ed7901SPeter Brune 
1421e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function
1422e4ed7901SPeter Brune 
1423e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm()
1424e4ed7901SPeter Brune @*/
1425e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunction(SNES snes, Vec f)
1426e4ed7901SPeter Brune {
1427e4ed7901SPeter Brune   PetscErrorCode ierr;
1428e4ed7901SPeter Brune   Vec            vec_func;
1429e4ed7901SPeter Brune 
1430e4ed7901SPeter Brune   PetscFunctionBegin;
1431e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1432e4ed7901SPeter Brune   PetscValidHeaderSpecific(f,VEC_CLASSID,2);
1433e4ed7901SPeter Brune   PetscCheckSameComm(snes,1,f,2);
1434e4ed7901SPeter Brune   ierr = SNESGetFunction(snes,&vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
1435e4ed7901SPeter Brune   ierr = VecCopy(f, vec_func);CHKERRQ(ierr);
1436217b9c2eSPeter Brune   snes->vec_func_init_set = PETSC_TRUE;
1437e4ed7901SPeter Brune   PetscFunctionReturn(0);
1438e4ed7901SPeter Brune }
1439e4ed7901SPeter Brune 
1440e4ed7901SPeter Brune 
1441e4ed7901SPeter Brune #undef __FUNCT__
1442e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunctionNorm"
1443e4ed7901SPeter Brune /*@C
1444e4ed7901SPeter Brune    SNESSetInitialFunctionNorm - Sets the function norm to be used as the function norm
1445e4ed7901SPeter Brune    at the initialization of the  method.  In some instances, the user has precomputed
1446e4ed7901SPeter Brune    the function and its norm before calling SNESSolve.  This function allows one to
1447e4ed7901SPeter Brune    avoid a redundant call to SNESComputeFunction() and VecNorm() in that case.
1448e4ed7901SPeter Brune 
1449e4ed7901SPeter Brune    Logically Collective on SNES
1450e4ed7901SPeter Brune 
1451e4ed7901SPeter Brune    Input Parameters:
1452e4ed7901SPeter Brune +  snes - the SNES context
1453e4ed7901SPeter Brune -  fnorm - the norm of F as set by SNESSetInitialFunction()
1454e4ed7901SPeter Brune 
1455e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1456e4ed7901SPeter Brune 
1457e4ed7901SPeter Brune    Level: developer
1458e4ed7901SPeter Brune 
1459e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function, norm
1460e4ed7901SPeter Brune 
1461e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction()
1462e4ed7901SPeter Brune @*/
1463e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm)
1464e4ed7901SPeter Brune {
1465e4ed7901SPeter Brune   PetscFunctionBegin;
1466e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1467e4ed7901SPeter Brune   snes->norm_init = fnorm;
1468e4ed7901SPeter Brune   snes->norm_init_set = PETSC_TRUE;
1469e4ed7901SPeter Brune   PetscFunctionReturn(0);
1470e4ed7901SPeter Brune }
1471e4ed7901SPeter Brune 
1472e4ed7901SPeter Brune #undef __FUNCT__
1473534ebe21SPeter Brune #define __FUNCT__ "SNESSetNormType"
1474534ebe21SPeter Brune /*@
1475534ebe21SPeter Brune    SNESSetNormType - Sets the SNESNormType used in covergence and monitoring
1476534ebe21SPeter Brune    of the SNES method.
1477534ebe21SPeter Brune 
1478534ebe21SPeter Brune    Logically Collective on SNES
1479534ebe21SPeter Brune 
1480534ebe21SPeter Brune    Input Parameters:
1481534ebe21SPeter Brune +  snes - the SNES context
1482534ebe21SPeter Brune -  normtype - the type of the norm used
1483534ebe21SPeter Brune 
1484534ebe21SPeter Brune    Notes:
1485534ebe21SPeter Brune    Only certain SNES methods support certain SNESNormTypes.  Most require evaluation
1486534ebe21SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
1487534ebe21SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1488534ebe21SPeter Brune    (SNESGS) and the like do not require the norm of the function to be computed, and therfore
1489534ebe21SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
1490534ebe21SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
1491534ebe21SPeter Brune    their solution.
1492534ebe21SPeter Brune 
1493534ebe21SPeter Brune    Level: developer
1494534ebe21SPeter Brune 
1495534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1496534ebe21SPeter Brune 
1497534ebe21SPeter Brune .seealso: SNESGetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType
1498534ebe21SPeter Brune @*/
1499534ebe21SPeter Brune PetscErrorCode  SNESSetNormType(SNES snes, SNESNormType normtype)
1500534ebe21SPeter Brune {
1501534ebe21SPeter Brune   PetscFunctionBegin;
1502534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1503534ebe21SPeter Brune   snes->normtype = normtype;
1504534ebe21SPeter Brune   PetscFunctionReturn(0);
1505534ebe21SPeter Brune }
1506534ebe21SPeter Brune 
1507534ebe21SPeter Brune 
1508534ebe21SPeter Brune #undef __FUNCT__
1509534ebe21SPeter Brune #define __FUNCT__ "SNESGetNormType"
1510534ebe21SPeter Brune /*@
1511534ebe21SPeter Brune    SNESGetNormType - Gets the SNESNormType used in covergence and monitoring
1512534ebe21SPeter Brune    of the SNES method.
1513534ebe21SPeter Brune 
1514534ebe21SPeter Brune    Logically Collective on SNES
1515534ebe21SPeter Brune 
1516534ebe21SPeter Brune    Input Parameters:
1517534ebe21SPeter Brune +  snes - the SNES context
1518534ebe21SPeter Brune -  normtype - the type of the norm used
1519534ebe21SPeter Brune 
1520534ebe21SPeter Brune    Level: advanced
1521534ebe21SPeter Brune 
1522534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1523534ebe21SPeter Brune 
1524534ebe21SPeter Brune .seealso: SNESSetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType
1525534ebe21SPeter Brune @*/
1526534ebe21SPeter Brune PetscErrorCode  SNESGetNormType(SNES snes, SNESNormType *normtype)
1527534ebe21SPeter Brune {
1528534ebe21SPeter Brune   PetscFunctionBegin;
1529534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1530534ebe21SPeter Brune   *normtype = snes->normtype;
1531534ebe21SPeter Brune   PetscFunctionReturn(0);
1532534ebe21SPeter Brune }
1533534ebe21SPeter Brune 
1534534ebe21SPeter Brune #undef __FUNCT__
1535646217ecSPeter Brune #define __FUNCT__ "SNESSetGS"
1536c79ef259SPeter Brune /*@C
1537c79ef259SPeter Brune    SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for
1538c79ef259SPeter Brune    use with composed nonlinear solvers.
1539c79ef259SPeter Brune 
1540c79ef259SPeter Brune    Input Parameters:
1541c79ef259SPeter Brune +  snes   - the SNES context
1542c79ef259SPeter Brune .  gsfunc - function evaluation routine
1543c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
1544c79ef259SPeter Brune             smoother evaluation routine (may be PETSC_NULL)
1545c79ef259SPeter Brune 
1546c79ef259SPeter Brune    Calling sequence of func:
1547c79ef259SPeter Brune $    func (SNES snes,Vec x,Vec b,void *ctx);
1548c79ef259SPeter Brune 
1549c79ef259SPeter Brune +  X   - solution vector
1550c79ef259SPeter Brune .  B   - RHS vector
1551d28543b3SPeter Brune -  ctx - optional user-defined Gauss-Seidel context
1552c79ef259SPeter Brune 
1553c79ef259SPeter Brune    Notes:
1554c79ef259SPeter Brune    The GS routines are used by the composed nonlinear solver to generate
1555c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
1556c79ef259SPeter Brune 
1557d28543b3SPeter Brune    Level: intermediate
1558c79ef259SPeter Brune 
1559d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel
1560c79ef259SPeter Brune 
1561c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS()
1562c79ef259SPeter Brune @*/
15636cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx)
15646cab3a1bSJed Brown {
15656cab3a1bSJed Brown   PetscErrorCode ierr;
15666cab3a1bSJed Brown   DM dm;
15676cab3a1bSJed Brown 
1568646217ecSPeter Brune   PetscFunctionBegin;
15696cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15706cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
15716cab3a1bSJed Brown   ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr);
1572646217ecSPeter Brune   PetscFunctionReturn(0);
1573646217ecSPeter Brune }
1574646217ecSPeter Brune 
1575d25893d9SBarry Smith #undef __FUNCT__
157689b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps"
157789b92e6fSPeter Brune /*@
157889b92e6fSPeter Brune    SNESSetGSSweeps - Sets the number of sweeps of GS to use.
157989b92e6fSPeter Brune 
158089b92e6fSPeter Brune    Input Parameters:
158189b92e6fSPeter Brune +  snes   - the SNES context
158289b92e6fSPeter Brune -  sweeps  - the number of sweeps of GS to perform.
158389b92e6fSPeter Brune 
158489b92e6fSPeter Brune    Level: intermediate
158589b92e6fSPeter Brune 
158689b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
158789b92e6fSPeter Brune 
158889b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps()
158989b92e6fSPeter Brune @*/
159089b92e6fSPeter Brune 
159189b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) {
159289b92e6fSPeter Brune   PetscFunctionBegin;
159389b92e6fSPeter Brune   snes->gssweeps = sweeps;
159489b92e6fSPeter Brune   PetscFunctionReturn(0);
159589b92e6fSPeter Brune }
159689b92e6fSPeter Brune 
159789b92e6fSPeter Brune 
159889b92e6fSPeter Brune #undef __FUNCT__
159989b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps"
160089b92e6fSPeter Brune /*@
160189b92e6fSPeter Brune    SNESGetGSSweeps - Gets the number of sweeps GS will use.
160289b92e6fSPeter Brune 
160389b92e6fSPeter Brune    Input Parameters:
160489b92e6fSPeter Brune .  snes   - the SNES context
160589b92e6fSPeter Brune 
160689b92e6fSPeter Brune    Output Parameters:
160789b92e6fSPeter Brune .  sweeps  - the number of sweeps of GS to perform.
160889b92e6fSPeter Brune 
160989b92e6fSPeter Brune    Level: intermediate
161089b92e6fSPeter Brune 
161189b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
161289b92e6fSPeter Brune 
161389b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps()
161489b92e6fSPeter Brune @*/
161589b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) {
161689b92e6fSPeter Brune   PetscFunctionBegin;
161789b92e6fSPeter Brune   *sweeps = snes->gssweeps;
161889b92e6fSPeter Brune   PetscFunctionReturn(0);
161989b92e6fSPeter Brune }
162089b92e6fSPeter Brune 
162189b92e6fSPeter Brune #undef __FUNCT__
16228b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction"
16238b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
16248b0a5094SBarry Smith {
16258b0a5094SBarry Smith   PetscErrorCode ierr;
16266cab3a1bSJed Brown   void *functx,*jacctx;
16276cab3a1bSJed Brown 
16288b0a5094SBarry Smith   PetscFunctionBegin;
16296cab3a1bSJed Brown   ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
16306cab3a1bSJed Brown   ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr);
16318b0a5094SBarry Smith   /*  A(x)*x - b(x) */
16326cab3a1bSJed Brown   ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr);
16336cab3a1bSJed Brown   ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr);
16348b0a5094SBarry Smith   ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
16358b0a5094SBarry Smith   ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
16368b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
16378b0a5094SBarry Smith   ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr);
16388b0a5094SBarry Smith   PetscFunctionReturn(0);
16398b0a5094SBarry Smith }
16408b0a5094SBarry Smith 
16418b0a5094SBarry Smith #undef __FUNCT__
16428b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian"
16438b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
16448b0a5094SBarry Smith {
16458b0a5094SBarry Smith   PetscFunctionBegin;
16468b0a5094SBarry Smith   *flag = snes->matstruct;
16478b0a5094SBarry Smith   PetscFunctionReturn(0);
16488b0a5094SBarry Smith }
16498b0a5094SBarry Smith 
16508b0a5094SBarry Smith #undef __FUNCT__
16518b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard"
16528b0a5094SBarry Smith /*@C
16530d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
16548b0a5094SBarry Smith 
16558b0a5094SBarry Smith    Logically Collective on SNES
16568b0a5094SBarry Smith 
16578b0a5094SBarry Smith    Input Parameters:
16588b0a5094SBarry Smith +  snes - the SNES context
16598b0a5094SBarry Smith .  r - vector to store function value
16608b0a5094SBarry Smith .  func - function evaluation routine
16618b0a5094SBarry 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)
16628b0a5094SBarry Smith .  mat - matrix to store A
16638b0a5094SBarry Smith .  mfunc  - function to compute matrix value
16648b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
16658b0a5094SBarry Smith          function evaluation routine (may be PETSC_NULL)
16668b0a5094SBarry Smith 
16678b0a5094SBarry Smith    Calling sequence of func:
16688b0a5094SBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
16698b0a5094SBarry Smith 
16708b0a5094SBarry Smith +  f - function vector
16718b0a5094SBarry Smith -  ctx - optional user-defined function context
16728b0a5094SBarry Smith 
16738b0a5094SBarry Smith    Calling sequence of mfunc:
16748b0a5094SBarry Smith $     mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx);
16758b0a5094SBarry Smith 
16768b0a5094SBarry Smith +  x - input vector
16778b0a5094SBarry 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(),
16788b0a5094SBarry Smith           normally just pass mat in this location
16798b0a5094SBarry Smith .  mat - form A(x) matrix
16808b0a5094SBarry Smith .  flag - flag indicating information about the preconditioner matrix
16818b0a5094SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
16828b0a5094SBarry Smith -  ctx - [optional] user-defined Jacobian context
16838b0a5094SBarry Smith 
16848b0a5094SBarry Smith    Notes:
16858b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
16868b0a5094SBarry Smith 
16878b0a5094SBarry 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}
16888b0a5094SBarry 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.
16898b0a5094SBarry Smith 
16908b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
16918b0a5094SBarry Smith 
16920d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
16930d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
16948b0a5094SBarry Smith 
16958b0a5094SBarry 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
16968b0a5094SBarry 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
16978b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
16988b0a5094SBarry Smith 
16998b0a5094SBarry Smith    Level: beginner
17008b0a5094SBarry Smith 
17018b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function
17028b0a5094SBarry Smith 
17030d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard()
17048b0a5094SBarry Smith @*/
17058b0a5094SBarry 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)
17068b0a5094SBarry Smith {
17078b0a5094SBarry Smith   PetscErrorCode ierr;
17088b0a5094SBarry Smith   PetscFunctionBegin;
17098b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
17108b0a5094SBarry Smith   snes->ops->computepfunction = func;
17118b0a5094SBarry Smith   snes->ops->computepjacobian = mfunc;
17128b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
17138b0a5094SBarry Smith   ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
17148b0a5094SBarry Smith   PetscFunctionReturn(0);
17158b0a5094SBarry Smith }
17168b0a5094SBarry Smith 
17178b0a5094SBarry Smith #undef __FUNCT__
1718d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess"
1719d25893d9SBarry Smith /*@C
1720d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1721d25893d9SBarry Smith 
1722d25893d9SBarry Smith    Logically Collective on SNES
1723d25893d9SBarry Smith 
1724d25893d9SBarry Smith    Input Parameters:
1725d25893d9SBarry Smith +  snes - the SNES context
1726d25893d9SBarry Smith .  func - function evaluation routine
1727d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
1728d25893d9SBarry Smith          function evaluation routine (may be PETSC_NULL)
1729d25893d9SBarry Smith 
1730d25893d9SBarry Smith    Calling sequence of func:
1731d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
1732d25893d9SBarry Smith 
1733d25893d9SBarry Smith .  f - function vector
1734d25893d9SBarry Smith -  ctx - optional user-defined function context
1735d25893d9SBarry Smith 
1736d25893d9SBarry Smith    Level: intermediate
1737d25893d9SBarry Smith 
1738d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
1739d25893d9SBarry Smith 
1740d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1741d25893d9SBarry Smith @*/
1742d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1743d25893d9SBarry Smith {
1744d25893d9SBarry Smith   PetscFunctionBegin;
1745d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1746d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
1747d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
1748d25893d9SBarry Smith   PetscFunctionReturn(0);
1749d25893d9SBarry Smith }
1750d25893d9SBarry Smith 
17513ab0aad5SBarry Smith /* --------------------------------------------------------------- */
17523ab0aad5SBarry Smith #undef __FUNCT__
17531096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
17541096aae1SMatthew Knepley /*@C
17551096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
17561096aae1SMatthew Knepley    it assumes a zero right hand side.
17571096aae1SMatthew Knepley 
17583f9fe445SBarry Smith    Logically Collective on SNES
17591096aae1SMatthew Knepley 
17601096aae1SMatthew Knepley    Input Parameter:
17611096aae1SMatthew Knepley .  snes - the SNES context
17621096aae1SMatthew Knepley 
17631096aae1SMatthew Knepley    Output Parameter:
1764bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
17651096aae1SMatthew Knepley 
17661096aae1SMatthew Knepley    Level: intermediate
17671096aae1SMatthew Knepley 
17681096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
17691096aae1SMatthew Knepley 
177085385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
17711096aae1SMatthew Knepley @*/
17727087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
17731096aae1SMatthew Knepley {
17741096aae1SMatthew Knepley   PetscFunctionBegin;
17750700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
17761096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
177785385478SLisandro Dalcin   *rhs = snes->vec_rhs;
17781096aae1SMatthew Knepley   PetscFunctionReturn(0);
17791096aae1SMatthew Knepley }
17801096aae1SMatthew Knepley 
17811096aae1SMatthew Knepley #undef __FUNCT__
17824a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
17839b94acceSBarry Smith /*@
178436851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
17859b94acceSBarry Smith                          SNESSetFunction().
17869b94acceSBarry Smith 
1787c7afd0dbSLois Curfman McInnes    Collective on SNES
1788c7afd0dbSLois Curfman McInnes 
17899b94acceSBarry Smith    Input Parameters:
1790c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1791c7afd0dbSLois Curfman McInnes -  x - input vector
17929b94acceSBarry Smith 
17939b94acceSBarry Smith    Output Parameter:
17943638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
17959b94acceSBarry Smith 
17961bffabb2SLois Curfman McInnes    Notes:
179736851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
179836851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
179936851e7fSLois Curfman McInnes    themselves.
180036851e7fSLois Curfman McInnes 
180136851e7fSLois Curfman McInnes    Level: developer
180236851e7fSLois Curfman McInnes 
18039b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
18049b94acceSBarry Smith 
1805a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
18069b94acceSBarry Smith @*/
18077087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
18089b94acceSBarry Smith {
1809dfbe8321SBarry Smith   PetscErrorCode ierr;
18106cab3a1bSJed Brown   DM             dm;
18116cab3a1bSJed Brown   SNESDM         sdm;
18129b94acceSBarry Smith 
18133a40ed3dSBarry Smith   PetscFunctionBegin;
18140700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
18150700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
18160700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
1817c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
1818c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
18194ec14c9cSBarry Smith   VecValidValues(x,2,PETSC_TRUE);
1820184914b5SBarry Smith 
18216cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
18226cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
1823d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
18246cab3a1bSJed Brown   if (sdm->computefunction) {
1825d64ed03dSBarry Smith     PetscStackPush("SNES user function");
18266cab3a1bSJed Brown     ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
1827d64ed03dSBarry Smith     PetscStackPop;
182873250ac0SBarry Smith   } else if (snes->dm) {
1829644e2e5bSBarry Smith     ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr);
1830c90fad12SPeter Brune   } else if (snes->vec_rhs) {
1831c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
1832644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
183385385478SLisandro Dalcin   if (snes->vec_rhs) {
183485385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
18353ab0aad5SBarry Smith   }
1836ae3c334cSLois Curfman McInnes   snes->nfuncs++;
1837d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
18384ec14c9cSBarry Smith   VecValidValues(y,3,PETSC_FALSE);
18393a40ed3dSBarry Smith   PetscFunctionReturn(0);
18409b94acceSBarry Smith }
18419b94acceSBarry Smith 
18424a2ae208SSatish Balay #undef __FUNCT__
1843646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS"
1844c79ef259SPeter Brune /*@
1845c79ef259SPeter Brune    SNESComputeGS - Calls the Gauss-Seidel function that has been set with
1846c79ef259SPeter Brune                    SNESSetGS().
1847c79ef259SPeter Brune 
1848c79ef259SPeter Brune    Collective on SNES
1849c79ef259SPeter Brune 
1850c79ef259SPeter Brune    Input Parameters:
1851c79ef259SPeter Brune +  snes - the SNES context
1852c79ef259SPeter Brune .  x - input vector
1853c79ef259SPeter Brune -  b - rhs vector
1854c79ef259SPeter Brune 
1855c79ef259SPeter Brune    Output Parameter:
1856c79ef259SPeter Brune .  x - new solution vector
1857c79ef259SPeter Brune 
1858c79ef259SPeter Brune    Notes:
1859c79ef259SPeter Brune    SNESComputeGS() is typically used within composed nonlinear solver
1860c79ef259SPeter Brune    implementations, so most users would not generally call this routine
1861c79ef259SPeter Brune    themselves.
1862c79ef259SPeter Brune 
1863c79ef259SPeter Brune    Level: developer
1864c79ef259SPeter Brune 
1865c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function
1866c79ef259SPeter Brune 
1867c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction()
1868c79ef259SPeter Brune @*/
1869646217ecSPeter Brune PetscErrorCode  SNESComputeGS(SNES snes,Vec b,Vec x)
1870646217ecSPeter Brune {
1871646217ecSPeter Brune   PetscErrorCode ierr;
187289b92e6fSPeter Brune   PetscInt i;
18736cab3a1bSJed Brown   DM dm;
18746cab3a1bSJed Brown   SNESDM sdm;
1875646217ecSPeter Brune 
1876646217ecSPeter Brune   PetscFunctionBegin;
1877646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1878646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
1879646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
1880646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
1881646217ecSPeter Brune   if(b) PetscCheckSameComm(snes,1,b,3);
18824ec14c9cSBarry Smith   if (b) VecValidValues(b,2,PETSC_TRUE);
1883701cf23dSPeter Brune   ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
18846cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
18856cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
18866cab3a1bSJed Brown   if (sdm->computegs) {
188789b92e6fSPeter Brune     for (i = 0; i < snes->gssweeps; i++) {
1888646217ecSPeter Brune       PetscStackPush("SNES user GS");
18896cab3a1bSJed Brown       ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
1890646217ecSPeter Brune       PetscStackPop;
189189b92e6fSPeter Brune     }
1892646217ecSPeter Brune   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve().");
1893701cf23dSPeter Brune   ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
18944ec14c9cSBarry Smith   VecValidValues(x,3,PETSC_FALSE);
1895646217ecSPeter Brune   PetscFunctionReturn(0);
1896646217ecSPeter Brune }
1897646217ecSPeter Brune 
1898646217ecSPeter Brune 
1899646217ecSPeter Brune #undef __FUNCT__
19004a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
190162fef451SLois Curfman McInnes /*@
190262fef451SLois Curfman McInnes    SNESComputeJacobian - Computes the Jacobian matrix that has been
190362fef451SLois Curfman McInnes    set with SNESSetJacobian().
190462fef451SLois Curfman McInnes 
1905c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
1906c7afd0dbSLois Curfman McInnes 
190762fef451SLois Curfman McInnes    Input Parameters:
1908c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1909c7afd0dbSLois Curfman McInnes -  x - input vector
191062fef451SLois Curfman McInnes 
191162fef451SLois Curfman McInnes    Output Parameters:
1912c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
191362fef451SLois Curfman McInnes .  B - optional preconditioning matrix
19142b668275SBarry Smith -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1915fee21e36SBarry Smith 
1916e35cf81dSBarry Smith   Options Database Keys:
1917e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
1918693365a8SJed Brown .    -snes_lag_jacobian <lag>
1919693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
1920693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
1921693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
19224c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
1923c01495d3SJed Brown .    -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference
1924c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
1925c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
1926c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
1927c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
19284c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
1929c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
1930c01495d3SJed Brown 
1931e35cf81dSBarry Smith 
193262fef451SLois Curfman McInnes    Notes:
193362fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
193462fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
193562fef451SLois Curfman McInnes 
193694b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the
1937dc5a77f8SLois Curfman McInnes    flag parameter.
193862fef451SLois Curfman McInnes 
193936851e7fSLois Curfman McInnes    Level: developer
194036851e7fSLois Curfman McInnes 
194162fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
194262fef451SLois Curfman McInnes 
1943e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
194462fef451SLois Curfman McInnes @*/
19457087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
19469b94acceSBarry Smith {
1947dfbe8321SBarry Smith   PetscErrorCode ierr;
1948ace3abfcSBarry Smith   PetscBool      flag;
19496cab3a1bSJed Brown   DM             dm;
19506cab3a1bSJed Brown   SNESDM         sdm;
19513a40ed3dSBarry Smith 
19523a40ed3dSBarry Smith   PetscFunctionBegin;
19530700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
19540700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
19554482741eSBarry Smith   PetscValidPointer(flg,5);
1956c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
19574ec14c9cSBarry Smith   VecValidValues(X,2,PETSC_TRUE);
19586cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
19596cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
19606cab3a1bSJed Brown   if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
1961ebd3b9afSBarry Smith 
1962ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
1963ebd3b9afSBarry Smith 
1964fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
1965fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
1966fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
1967fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
1968e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1969e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
1970251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1971ebd3b9afSBarry Smith     if (flag) {
1972ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1973ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1974ebd3b9afSBarry Smith     }
1975e35cf81dSBarry Smith     PetscFunctionReturn(0);
1976e35cf81dSBarry Smith   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
1977e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1978e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
1979251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1980ebd3b9afSBarry Smith     if (flag) {
1981ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1982ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1983ebd3b9afSBarry Smith     }
1984e35cf81dSBarry Smith     PetscFunctionReturn(0);
1985e35cf81dSBarry Smith   }
1986e35cf81dSBarry Smith 
1987c4fc05e7SBarry Smith   *flg = DIFFERENT_NONZERO_PATTERN;
1988e35cf81dSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1989d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
19906cab3a1bSJed Brown   ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr);
1991d64ed03dSBarry Smith   PetscStackPop;
1992d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1993a8054027SBarry Smith 
19943b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
19953b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
19963b4f5425SBarry Smith     snes->lagpreconditioner = -1;
19973b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
1998a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1999a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
2000a8054027SBarry Smith   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
2001a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
2002a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
2003a8054027SBarry Smith   }
2004a8054027SBarry Smith 
20056d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
20060700a824SBarry Smith   /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
20070700a824SBarry Smith     PetscValidHeaderSpecific(*B,MAT_CLASSID,4);   */
2008693365a8SJed Brown   {
2009693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
2010693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr);
2011693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
2012693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
2013693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr);
2014693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
2015693365a8SJed Brown       Mat Bexp_mine = PETSC_NULL,Bexp,FDexp;
2016693365a8SJed Brown       MatStructure mstruct;
2017693365a8SJed Brown       PetscViewer vdraw,vstdout;
20186b3a5b13SJed Brown       PetscBool flg;
2019693365a8SJed Brown       if (flag_operator) {
2020693365a8SJed Brown         ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr);
2021693365a8SJed Brown         Bexp = Bexp_mine;
2022693365a8SJed Brown       } else {
2023693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
2024251f4c67SDmitry Karpeev         ierr = PetscObjectTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
2025693365a8SJed Brown         if (flg) Bexp = *B;
2026693365a8SJed Brown         else {
2027693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
2028693365a8SJed Brown           ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr);
2029693365a8SJed Brown           Bexp = Bexp_mine;
2030693365a8SJed Brown         }
2031693365a8SJed Brown       }
2032693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
2033693365a8SJed Brown       ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr);
2034693365a8SJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
2035693365a8SJed Brown       if (flag_draw || flag_contour) {
2036693365a8SJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
2037693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
2038693365a8SJed Brown       } else vdraw = PETSC_NULL;
2039693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr);
2040693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
2041693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
2042693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
2043693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2044693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
2045693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2046693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
2047693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2048693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
2049693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
2050693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
2051693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
2052693365a8SJed Brown       }
2053693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
2054693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
2055693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
2056693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
2057693365a8SJed Brown     }
2058693365a8SJed Brown   }
20594c30e9fbSJed Brown   {
20606719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
20616719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
20624c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr);
20636719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr);
20644c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
20654c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
20666719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr);
20676719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr);
20686719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr);
20696719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
20704c30e9fbSJed Brown       Mat Bfd;
20714c30e9fbSJed Brown       MatStructure mstruct;
20724c30e9fbSJed Brown       PetscViewer vdraw,vstdout;
20734c30e9fbSJed Brown       ISColoring iscoloring;
20744c30e9fbSJed Brown       MatFDColoring matfdcoloring;
20754c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
20764c30e9fbSJed Brown       void *funcctx;
20776719d8e4SJed Brown       PetscReal norm1,norm2,normmax;
20784c30e9fbSJed Brown 
20794c30e9fbSJed Brown       ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
20804c30e9fbSJed Brown       ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
20814c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
20824c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
20834c30e9fbSJed Brown 
20844c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
20854c30e9fbSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr);
20864c30e9fbSJed Brown       ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr);
20874c30e9fbSJed Brown       ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
20884c30e9fbSJed Brown       ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
20894c30e9fbSJed Brown       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
20904c30e9fbSJed Brown       ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr);
20914c30e9fbSJed Brown       ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
20924c30e9fbSJed Brown 
20934c30e9fbSJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
20944c30e9fbSJed Brown       if (flag_draw || flag_contour) {
20954c30e9fbSJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
20964c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
20974c30e9fbSJed Brown       } else vdraw = PETSC_NULL;
20984c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
20996719d8e4SJed Brown       if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);}
21004c30e9fbSJed Brown       if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);}
21014c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
21026719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
21034c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
21044c30e9fbSJed Brown       ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
21054c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
21066719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
21074c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
21086719d8e4SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr);
21096719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
21104c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
21114c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
21124c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
21134c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
21144c30e9fbSJed Brown       }
21154c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
21166719d8e4SJed Brown 
21176719d8e4SJed Brown       if (flag_threshold) {
21186719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
21196719d8e4SJed Brown         ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr);
21206719d8e4SJed Brown         ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr);
21216719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
21226719d8e4SJed Brown           const PetscScalar *ba,*ca;
21236719d8e4SJed Brown           const PetscInt *bj,*cj;
21246719d8e4SJed Brown           PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
21256719d8e4SJed Brown           PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0;
21266719d8e4SJed Brown           ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
21276719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
21286719d8e4SJed Brown           if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
21296719d8e4SJed Brown           for (j=0; j<bn; j++) {
21306719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
21316719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
21326719d8e4SJed Brown               maxentrycol = bj[j];
21336719d8e4SJed Brown               maxentry = PetscRealPart(ba[j]);
21346719d8e4SJed Brown             }
21356719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
21366719d8e4SJed Brown               maxdiffcol = bj[j];
21376719d8e4SJed Brown               maxdiff = PetscRealPart(ca[j]);
21386719d8e4SJed Brown             }
21396719d8e4SJed Brown             if (rdiff > maxrdiff) {
21406719d8e4SJed Brown               maxrdiffcol = bj[j];
21416719d8e4SJed Brown               maxrdiff = rdiff;
21426719d8e4SJed Brown             }
21436719d8e4SJed Brown           }
21446719d8e4SJed Brown           if (maxrdiff > 1) {
21456719d8e4SJed 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);
21466719d8e4SJed Brown             for (j=0; j<bn; j++) {
21476719d8e4SJed Brown               PetscReal rdiff;
21486719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
21496719d8e4SJed Brown               if (rdiff > 1) {
21506719d8e4SJed Brown                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr);
21516719d8e4SJed Brown               }
21526719d8e4SJed Brown             }
21536719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
21546719d8e4SJed Brown           }
21556719d8e4SJed Brown           ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
21566719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
21576719d8e4SJed Brown         }
21586719d8e4SJed Brown       }
21594c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
21604c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
21614c30e9fbSJed Brown     }
21624c30e9fbSJed Brown   }
21633a40ed3dSBarry Smith   PetscFunctionReturn(0);
21649b94acceSBarry Smith }
21659b94acceSBarry Smith 
21664a2ae208SSatish Balay #undef __FUNCT__
21674a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
21689b94acceSBarry Smith /*@C
21699b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2170044dda88SLois Curfman McInnes    location to store the matrix.
21719b94acceSBarry Smith 
21723f9fe445SBarry Smith    Logically Collective on SNES and Mat
2173c7afd0dbSLois Curfman McInnes 
21749b94acceSBarry Smith    Input Parameters:
2175c7afd0dbSLois Curfman McInnes +  snes - the SNES context
21769b94acceSBarry Smith .  A - Jacobian matrix
21779b94acceSBarry Smith .  B - preconditioner matrix (usually same as the Jacobian)
2178efd51863SBarry Smith .  func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value)
2179c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
2180efd51863SBarry Smith          Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value)
21819b94acceSBarry Smith 
21829b94acceSBarry Smith    Calling sequence of func:
21838d76a1e5SLois Curfman McInnes $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
21849b94acceSBarry Smith 
2185c7afd0dbSLois Curfman McInnes +  x - input vector
21869b94acceSBarry Smith .  A - Jacobian matrix
21879b94acceSBarry Smith .  B - preconditioner matrix, usually the same as A
2188ac21db08SLois Curfman McInnes .  flag - flag indicating information about the preconditioner matrix
21892b668275SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
2190c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined Jacobian context
21919b94acceSBarry Smith 
21929b94acceSBarry Smith    Notes:
219394b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the flag
21942cd2dfdcSLois Curfman McInnes    output parameter in the routine func().  Be sure to read this information!
2195ac21db08SLois Curfman McInnes 
2196ac21db08SLois Curfman McInnes    The routine func() takes Mat * as the matrix arguments rather than Mat.
21979b94acceSBarry Smith    This allows the Jacobian evaluation routine to replace A and/or B with a
21989b94acceSBarry Smith    completely new new matrix structure (not just different matrix elements)
21999b94acceSBarry Smith    when appropriate, for instance, if the nonzero structure is changing
22009b94acceSBarry Smith    throughout the global iterations.
22019b94acceSBarry Smith 
220216913363SBarry Smith    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
220316913363SBarry Smith    each matrix.
220416913363SBarry Smith 
2205a8a26c1eSJed Brown    If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument
2206a8a26c1eSJed Brown    must be a MatFDColoring.
2207a8a26c1eSJed Brown 
2208c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2209c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2210c3cc8fd1SJed Brown 
221136851e7fSLois Curfman McInnes    Level: beginner
221236851e7fSLois Curfman McInnes 
22139b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
22149b94acceSBarry Smith 
22153ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
22169b94acceSBarry Smith @*/
22177087cfbeSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
22189b94acceSBarry Smith {
2219dfbe8321SBarry Smith   PetscErrorCode ierr;
22206cab3a1bSJed Brown   DM             dm;
22213a7fca6bSBarry Smith 
22223a40ed3dSBarry Smith   PetscFunctionBegin;
22230700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
22240700a824SBarry Smith   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
22250700a824SBarry Smith   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
2226c9780b6fSBarry Smith   if (A) PetscCheckSameComm(snes,1,A,2);
222706975374SJed Brown   if (B) PetscCheckSameComm(snes,1,B,3);
22286cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
22296cab3a1bSJed Brown   ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr);
22303a7fca6bSBarry Smith   if (A) {
22317dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
22326bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
22339b94acceSBarry Smith     snes->jacobian = A;
22343a7fca6bSBarry Smith   }
22353a7fca6bSBarry Smith   if (B) {
22367dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
22376bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
22389b94acceSBarry Smith     snes->jacobian_pre = B;
22393a7fca6bSBarry Smith   }
22403a40ed3dSBarry Smith   PetscFunctionReturn(0);
22419b94acceSBarry Smith }
224262fef451SLois Curfman McInnes 
22434a2ae208SSatish Balay #undef __FUNCT__
22444a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
2245c2aafc4cSSatish Balay /*@C
2246b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2247b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2248b4fd4287SBarry Smith 
2249c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2250c7afd0dbSLois Curfman McInnes 
2251b4fd4287SBarry Smith    Input Parameter:
2252b4fd4287SBarry Smith .  snes - the nonlinear solver context
2253b4fd4287SBarry Smith 
2254b4fd4287SBarry Smith    Output Parameters:
2255c7afd0dbSLois Curfman McInnes +  A - location to stash Jacobian matrix (or PETSC_NULL)
2256b4fd4287SBarry Smith .  B - location to stash preconditioner matrix (or PETSC_NULL)
225770e92668SMatthew Knepley .  func - location to put Jacobian function (or PETSC_NULL)
225870e92668SMatthew Knepley -  ctx - location to stash Jacobian ctx (or PETSC_NULL)
2259fee21e36SBarry Smith 
226036851e7fSLois Curfman McInnes    Level: advanced
226136851e7fSLois Curfman McInnes 
2262b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian()
2263b4fd4287SBarry Smith @*/
22647087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
2265b4fd4287SBarry Smith {
22666cab3a1bSJed Brown   PetscErrorCode ierr;
22676cab3a1bSJed Brown   DM             dm;
22686cab3a1bSJed Brown   SNESDM         sdm;
22696cab3a1bSJed Brown 
22703a40ed3dSBarry Smith   PetscFunctionBegin;
22710700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2272b4fd4287SBarry Smith   if (A)    *A    = snes->jacobian;
2273b4fd4287SBarry Smith   if (B)    *B    = snes->jacobian_pre;
22746cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
22756cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
22766cab3a1bSJed Brown   if (func) *func = sdm->computejacobian;
22776cab3a1bSJed Brown   if (ctx)  *ctx  = sdm->jacobianctx;
22783a40ed3dSBarry Smith   PetscFunctionReturn(0);
2279b4fd4287SBarry Smith }
2280b4fd4287SBarry Smith 
22819b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
22829b94acceSBarry Smith 
22834a2ae208SSatish Balay #undef __FUNCT__
22844a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
22859b94acceSBarry Smith /*@
22869b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
2287272ac6f2SLois Curfman McInnes    of a nonlinear solver.
22889b94acceSBarry Smith 
2289fee21e36SBarry Smith    Collective on SNES
2290fee21e36SBarry Smith 
2291c7afd0dbSLois Curfman McInnes    Input Parameters:
229270e92668SMatthew Knepley .  snes - the SNES context
2293c7afd0dbSLois Curfman McInnes 
2294272ac6f2SLois Curfman McInnes    Notes:
2295272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
2296272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
2297272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
2298272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
2299272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
2300272ac6f2SLois Curfman McInnes 
230136851e7fSLois Curfman McInnes    Level: advanced
230236851e7fSLois Curfman McInnes 
23039b94acceSBarry Smith .keywords: SNES, nonlinear, setup
23049b94acceSBarry Smith 
23059b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
23069b94acceSBarry Smith @*/
23077087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
23089b94acceSBarry Smith {
2309dfbe8321SBarry Smith   PetscErrorCode ierr;
23106cab3a1bSJed Brown   DM             dm;
23116cab3a1bSJed Brown   SNESDM         sdm;
2312*6e2a1849SPeter Brune   SNESLineSearch              linesearch;
2313*6e2a1849SPeter Brune   SNESLineSearch              pclinesearch;
2314*6e2a1849SPeter Brune   void                        *lsprectx,*lspostctx;
2315*6e2a1849SPeter Brune   SNESLineSearchPreCheckFunc  lsprefunc;
2316*6e2a1849SPeter Brune   SNESLineSearchPostCheckFunc lspostfunc;
2317*6e2a1849SPeter Brune   PetscErrorCode              (*func)(SNES,Vec,Vec,void*);
2318*6e2a1849SPeter Brune   Vec                         f,fpc;
2319*6e2a1849SPeter Brune   void                        *funcctx;
2320*6e2a1849SPeter Brune   PetscErrorCode              (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*);
2321*6e2a1849SPeter Brune   void                        *jacctx;
2322*6e2a1849SPeter Brune   Mat                         A,B;
23233a40ed3dSBarry Smith 
23243a40ed3dSBarry Smith   PetscFunctionBegin;
23250700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
23264dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
23279b94acceSBarry Smith 
23287adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
232985385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
233085385478SLisandro Dalcin   }
233185385478SLisandro Dalcin 
2332a63bb30eSJed Brown   ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
233317186662SBarry Smith   if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
233458c9b817SLisandro Dalcin   if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
233558c9b817SLisandro Dalcin 
233658c9b817SLisandro Dalcin   if (!snes->vec_sol_update /* && snes->vec_sol */) {
233758c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
233858c9b817SLisandro Dalcin     ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr);
233958c9b817SLisandro Dalcin   }
234058c9b817SLisandro Dalcin 
23416cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
23426cab3a1bSJed Brown   ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */
23436cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
23446cab3a1bSJed Brown   if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc");
23456cab3a1bSJed Brown   if (!snes->vec_func) {
23466cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2347214df951SJed Brown   }
2348efd51863SBarry Smith 
2349b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
2350b710008aSBarry Smith 
2351f1c6b773SPeter Brune   if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);}
23529e764e56SPeter Brune 
2353d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
2354d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
2355d25893d9SBarry Smith   }
2356d25893d9SBarry Smith 
2357*6e2a1849SPeter Brune   if (snes->pc) {
2358*6e2a1849SPeter Brune     /* copy the DM over */
2359*6e2a1849SPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2360*6e2a1849SPeter Brune     ierr = SNESSetDM(snes->pc,dm);CHKERRQ(ierr);
2361*6e2a1849SPeter Brune 
2362*6e2a1849SPeter Brune     /* copy the legacy SNES context not related to the DM over*/
2363*6e2a1849SPeter Brune     ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr);
2364*6e2a1849SPeter Brune     ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr);
2365*6e2a1849SPeter Brune     ierr = SNESSetFunction(snes->pc,fpc,func,funcctx);CHKERRQ(ierr);
2366*6e2a1849SPeter Brune     ierr = SNESGetJacobian(snes,&A,&B,&jac,&jacctx);CHKERRQ(ierr);
2367*6e2a1849SPeter Brune     ierr = SNESSetJacobian(snes->pc,A,B,jac,jacctx);CHKERRQ(ierr);
2368*6e2a1849SPeter Brune     ierr = VecDestroy(&fpc);CHKERRQ(ierr);
2369*6e2a1849SPeter Brune 
2370*6e2a1849SPeter Brune     /* copy the function pointers over */
2371*6e2a1849SPeter Brune     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr);
2372*6e2a1849SPeter Brune 
2373*6e2a1849SPeter Brune      /* default to 1 iteration */
2374*6e2a1849SPeter Brune     ierr = SNESSetTolerances(snes->pc, snes->pc->abstol, snes->pc->rtol, snes->pc->stol, 1, snes->pc->max_funcs);CHKERRQ(ierr);
2375*6e2a1849SPeter Brune     ierr = SNESSetNormType(snes->pc, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr);
2376*6e2a1849SPeter Brune     ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr);
2377*6e2a1849SPeter Brune 
2378*6e2a1849SPeter Brune     /* copy the line search context over */
2379*6e2a1849SPeter Brune     ierr = SNESGetSNESLineSearch(snes,&linesearch);CHKERRQ(ierr);
2380*6e2a1849SPeter Brune     ierr = SNESGetSNESLineSearch(snes->pc,&pclinesearch);CHKERRQ(ierr);
2381*6e2a1849SPeter Brune     ierr = SNESLineSearchGetPreCheck(linesearch,&lsprefunc,&lsprectx);CHKERRQ(ierr);
2382*6e2a1849SPeter Brune     ierr = SNESLineSearchGetPostCheck(linesearch,&lspostfunc,&lspostctx);CHKERRQ(ierr);
2383*6e2a1849SPeter Brune     ierr = SNESLineSearchSetPreCheck(pclinesearch,lsprefunc,lsprectx);CHKERRQ(ierr);
2384*6e2a1849SPeter Brune     ierr = SNESLineSearchSetPostCheck(pclinesearch,lspostfunc,lspostctx);CHKERRQ(ierr);
2385*6e2a1849SPeter Brune     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr);
2386*6e2a1849SPeter Brune   }
2387*6e2a1849SPeter Brune 
2388410397dcSLisandro Dalcin   if (snes->ops->setup) {
2389410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2390410397dcSLisandro Dalcin   }
239158c9b817SLisandro Dalcin 
23927aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
23933a40ed3dSBarry Smith   PetscFunctionReturn(0);
23949b94acceSBarry Smith }
23959b94acceSBarry Smith 
23964a2ae208SSatish Balay #undef __FUNCT__
239737596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
239837596af1SLisandro Dalcin /*@
239937596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
240037596af1SLisandro Dalcin 
240137596af1SLisandro Dalcin    Collective on SNES
240237596af1SLisandro Dalcin 
240337596af1SLisandro Dalcin    Input Parameter:
240437596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
240537596af1SLisandro Dalcin 
2406d25893d9SBarry Smith    Level: intermediate
2407d25893d9SBarry Smith 
2408d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
240937596af1SLisandro Dalcin 
241037596af1SLisandro Dalcin .keywords: SNES, destroy
241137596af1SLisandro Dalcin 
241237596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
241337596af1SLisandro Dalcin @*/
241437596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
241537596af1SLisandro Dalcin {
241637596af1SLisandro Dalcin   PetscErrorCode ierr;
241737596af1SLisandro Dalcin 
241837596af1SLisandro Dalcin   PetscFunctionBegin;
241937596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2420d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
2421d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
2422d25893d9SBarry Smith     snes->user = PETSC_NULL;
2423d25893d9SBarry Smith   }
24248a23116dSBarry Smith   if (snes->pc) {
24258a23116dSBarry Smith     ierr = SNESReset(snes->pc);CHKERRQ(ierr);
24268a23116dSBarry Smith   }
24278a23116dSBarry Smith 
242837596af1SLisandro Dalcin   if (snes->ops->reset) {
242937596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
243037596af1SLisandro Dalcin   }
24319e764e56SPeter Brune   if (snes->ksp) {
24329e764e56SPeter Brune     ierr = KSPReset(snes->ksp);CHKERRQ(ierr);
24339e764e56SPeter Brune   }
24349e764e56SPeter Brune 
24359e764e56SPeter Brune   if (snes->linesearch) {
2436f1c6b773SPeter Brune     ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr);
24379e764e56SPeter Brune   }
24389e764e56SPeter Brune 
24396bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
24406bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
24416bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
24426bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
24436bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
24446bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2445c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
2446c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
244737596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
244837596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
244937596af1SLisandro Dalcin   PetscFunctionReturn(0);
245037596af1SLisandro Dalcin }
245137596af1SLisandro Dalcin 
245237596af1SLisandro Dalcin #undef __FUNCT__
24534a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
245452baeb72SSatish Balay /*@
24559b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
24569b94acceSBarry Smith    with SNESCreate().
24579b94acceSBarry Smith 
2458c7afd0dbSLois Curfman McInnes    Collective on SNES
2459c7afd0dbSLois Curfman McInnes 
24609b94acceSBarry Smith    Input Parameter:
24619b94acceSBarry Smith .  snes - the SNES context
24629b94acceSBarry Smith 
246336851e7fSLois Curfman McInnes    Level: beginner
246436851e7fSLois Curfman McInnes 
24659b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
24669b94acceSBarry Smith 
246763a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
24689b94acceSBarry Smith @*/
24696bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
24709b94acceSBarry Smith {
24716849ba73SBarry Smith   PetscErrorCode ierr;
24723a40ed3dSBarry Smith 
24733a40ed3dSBarry Smith   PetscFunctionBegin;
24746bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
24756bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
24766bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2477d4bb536fSBarry Smith 
24786bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
24798a23116dSBarry Smith   ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr);
24806b8b9a38SLisandro Dalcin 
2481be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
24826bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
24836bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
24846d4c513bSLisandro Dalcin 
24856bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
24866bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
2487f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr);
24886b8b9a38SLisandro Dalcin 
24896bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
24906bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
24916bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
24926b8b9a38SLisandro Dalcin   }
24936bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
24946bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
24956bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
249658c9b817SLisandro Dalcin   }
24976bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2498a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
24993a40ed3dSBarry Smith  PetscFunctionReturn(0);
25009b94acceSBarry Smith }
25019b94acceSBarry Smith 
25029b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
25039b94acceSBarry Smith 
25044a2ae208SSatish Balay #undef __FUNCT__
2505a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
2506a8054027SBarry Smith /*@
2507a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2508a8054027SBarry Smith 
25093f9fe445SBarry Smith    Logically Collective on SNES
2510a8054027SBarry Smith 
2511a8054027SBarry Smith    Input Parameters:
2512a8054027SBarry Smith +  snes - the SNES context
2513a8054027SBarry 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
25143b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2515a8054027SBarry Smith 
2516a8054027SBarry Smith    Options Database Keys:
2517a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2518a8054027SBarry Smith 
2519a8054027SBarry Smith    Notes:
2520a8054027SBarry Smith    The default is 1
2521a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2522a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2523a8054027SBarry Smith 
2524a8054027SBarry Smith    Level: intermediate
2525a8054027SBarry Smith 
2526a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2527a8054027SBarry Smith 
2528e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2529a8054027SBarry Smith 
2530a8054027SBarry Smith @*/
25317087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2532a8054027SBarry Smith {
2533a8054027SBarry Smith   PetscFunctionBegin;
25340700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2535e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2536e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2537c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2538a8054027SBarry Smith   snes->lagpreconditioner = lag;
2539a8054027SBarry Smith   PetscFunctionReturn(0);
2540a8054027SBarry Smith }
2541a8054027SBarry Smith 
2542a8054027SBarry Smith #undef __FUNCT__
2543efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
2544efd51863SBarry Smith /*@
2545efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2546efd51863SBarry Smith 
2547efd51863SBarry Smith    Logically Collective on SNES
2548efd51863SBarry Smith 
2549efd51863SBarry Smith    Input Parameters:
2550efd51863SBarry Smith +  snes - the SNES context
2551efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
2552efd51863SBarry Smith 
2553efd51863SBarry Smith    Options Database Keys:
2554efd51863SBarry Smith .    -snes_grid_sequence <steps>
2555efd51863SBarry Smith 
2556efd51863SBarry Smith    Level: intermediate
2557efd51863SBarry Smith 
2558c0df2a02SJed Brown    Notes:
2559c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2560c0df2a02SJed Brown 
2561efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2562efd51863SBarry Smith 
2563efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2564efd51863SBarry Smith 
2565efd51863SBarry Smith @*/
2566efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2567efd51863SBarry Smith {
2568efd51863SBarry Smith   PetscFunctionBegin;
2569efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2570efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
2571efd51863SBarry Smith   snes->gridsequence = steps;
2572efd51863SBarry Smith   PetscFunctionReturn(0);
2573efd51863SBarry Smith }
2574efd51863SBarry Smith 
2575efd51863SBarry Smith #undef __FUNCT__
2576a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
2577a8054027SBarry Smith /*@
2578a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
2579a8054027SBarry Smith 
25803f9fe445SBarry Smith    Not Collective
2581a8054027SBarry Smith 
2582a8054027SBarry Smith    Input Parameter:
2583a8054027SBarry Smith .  snes - the SNES context
2584a8054027SBarry Smith 
2585a8054027SBarry Smith    Output Parameter:
2586a8054027SBarry 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
25873b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2588a8054027SBarry Smith 
2589a8054027SBarry Smith    Options Database Keys:
2590a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2591a8054027SBarry Smith 
2592a8054027SBarry Smith    Notes:
2593a8054027SBarry Smith    The default is 1
2594a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2595a8054027SBarry Smith 
2596a8054027SBarry Smith    Level: intermediate
2597a8054027SBarry Smith 
2598a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2599a8054027SBarry Smith 
2600a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
2601a8054027SBarry Smith 
2602a8054027SBarry Smith @*/
26037087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
2604a8054027SBarry Smith {
2605a8054027SBarry Smith   PetscFunctionBegin;
26060700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2607a8054027SBarry Smith   *lag = snes->lagpreconditioner;
2608a8054027SBarry Smith   PetscFunctionReturn(0);
2609a8054027SBarry Smith }
2610a8054027SBarry Smith 
2611a8054027SBarry Smith #undef __FUNCT__
2612e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
2613e35cf81dSBarry Smith /*@
2614e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
2615e35cf81dSBarry Smith      often the preconditioner is rebuilt.
2616e35cf81dSBarry Smith 
26173f9fe445SBarry Smith    Logically Collective on SNES
2618e35cf81dSBarry Smith 
2619e35cf81dSBarry Smith    Input Parameters:
2620e35cf81dSBarry Smith +  snes - the SNES context
2621e35cf81dSBarry 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
2622fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
2623e35cf81dSBarry Smith 
2624e35cf81dSBarry Smith    Options Database Keys:
2625e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2626e35cf81dSBarry Smith 
2627e35cf81dSBarry Smith    Notes:
2628e35cf81dSBarry Smith    The default is 1
2629e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2630fe3ffe1eSBarry 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
2631fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
2632e35cf81dSBarry Smith 
2633e35cf81dSBarry Smith    Level: intermediate
2634e35cf81dSBarry Smith 
2635e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2636e35cf81dSBarry Smith 
2637e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
2638e35cf81dSBarry Smith 
2639e35cf81dSBarry Smith @*/
26407087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
2641e35cf81dSBarry Smith {
2642e35cf81dSBarry Smith   PetscFunctionBegin;
26430700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2644e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2645e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2646c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2647e35cf81dSBarry Smith   snes->lagjacobian = lag;
2648e35cf81dSBarry Smith   PetscFunctionReturn(0);
2649e35cf81dSBarry Smith }
2650e35cf81dSBarry Smith 
2651e35cf81dSBarry Smith #undef __FUNCT__
2652e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
2653e35cf81dSBarry Smith /*@
2654e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
2655e35cf81dSBarry Smith 
26563f9fe445SBarry Smith    Not Collective
2657e35cf81dSBarry Smith 
2658e35cf81dSBarry Smith    Input Parameter:
2659e35cf81dSBarry Smith .  snes - the SNES context
2660e35cf81dSBarry Smith 
2661e35cf81dSBarry Smith    Output Parameter:
2662e35cf81dSBarry 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
2663e35cf81dSBarry Smith          the Jacobian is built etc.
2664e35cf81dSBarry Smith 
2665e35cf81dSBarry Smith    Options Database Keys:
2666e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2667e35cf81dSBarry Smith 
2668e35cf81dSBarry Smith    Notes:
2669e35cf81dSBarry Smith    The default is 1
2670e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2671e35cf81dSBarry Smith 
2672e35cf81dSBarry Smith    Level: intermediate
2673e35cf81dSBarry Smith 
2674e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2675e35cf81dSBarry Smith 
2676e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
2677e35cf81dSBarry Smith 
2678e35cf81dSBarry Smith @*/
26797087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
2680e35cf81dSBarry Smith {
2681e35cf81dSBarry Smith   PetscFunctionBegin;
26820700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2683e35cf81dSBarry Smith   *lag = snes->lagjacobian;
2684e35cf81dSBarry Smith   PetscFunctionReturn(0);
2685e35cf81dSBarry Smith }
2686e35cf81dSBarry Smith 
2687e35cf81dSBarry Smith #undef __FUNCT__
26884a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
26899b94acceSBarry Smith /*@
2690d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
26919b94acceSBarry Smith 
26923f9fe445SBarry Smith    Logically Collective on SNES
2693c7afd0dbSLois Curfman McInnes 
26949b94acceSBarry Smith    Input Parameters:
2695c7afd0dbSLois Curfman McInnes +  snes - the SNES context
269670441072SBarry Smith .  abstol - absolute convergence tolerance
269733174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
269833174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
269933174efeSLois Curfman McInnes            of the change in the solution between steps
270033174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2701c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2702fee21e36SBarry Smith 
270333174efeSLois Curfman McInnes    Options Database Keys:
270470441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
2705c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
2706c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
2707c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
2708c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
27099b94acceSBarry Smith 
2710d7a720efSLois Curfman McInnes    Notes:
27119b94acceSBarry Smith    The default maximum number of iterations is 50.
27129b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
27139b94acceSBarry Smith 
271436851e7fSLois Curfman McInnes    Level: intermediate
271536851e7fSLois Curfman McInnes 
271633174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
27179b94acceSBarry Smith 
27182492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
27199b94acceSBarry Smith @*/
27207087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
27219b94acceSBarry Smith {
27223a40ed3dSBarry Smith   PetscFunctionBegin;
27230700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2724c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
2725c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
2726c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
2727c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
2728c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
2729c5eb9154SBarry Smith 
2730ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
2731ab54825eSJed Brown     if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol);
2732ab54825eSJed Brown     snes->abstol = abstol;
2733ab54825eSJed Brown   }
2734ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
2735ab54825eSJed 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);
2736ab54825eSJed Brown     snes->rtol = rtol;
2737ab54825eSJed Brown   }
2738ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
2739ab54825eSJed Brown     if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol);
2740c60f73f4SPeter Brune     snes->stol = stol;
2741ab54825eSJed Brown   }
2742ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
2743ab54825eSJed Brown     if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
2744ab54825eSJed Brown     snes->max_its = maxit;
2745ab54825eSJed Brown   }
2746ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
2747ab54825eSJed Brown     if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
2748ab54825eSJed Brown     snes->max_funcs = maxf;
2749ab54825eSJed Brown   }
275088976e71SPeter Brune   snes->tolerancesset = PETSC_TRUE;
27513a40ed3dSBarry Smith   PetscFunctionReturn(0);
27529b94acceSBarry Smith }
27539b94acceSBarry Smith 
27544a2ae208SSatish Balay #undef __FUNCT__
27554a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
27569b94acceSBarry Smith /*@
275733174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
275833174efeSLois Curfman McInnes 
2759c7afd0dbSLois Curfman McInnes    Not Collective
2760c7afd0dbSLois Curfman McInnes 
276133174efeSLois Curfman McInnes    Input Parameters:
2762c7afd0dbSLois Curfman McInnes +  snes - the SNES context
276385385478SLisandro Dalcin .  atol - absolute convergence tolerance
276433174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
276533174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
276633174efeSLois Curfman McInnes            of the change in the solution between steps
276733174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2768c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2769fee21e36SBarry Smith 
277033174efeSLois Curfman McInnes    Notes:
277133174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
277233174efeSLois Curfman McInnes 
277336851e7fSLois Curfman McInnes    Level: intermediate
277436851e7fSLois Curfman McInnes 
277533174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
277633174efeSLois Curfman McInnes 
277733174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
277833174efeSLois Curfman McInnes @*/
27797087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
278033174efeSLois Curfman McInnes {
27813a40ed3dSBarry Smith   PetscFunctionBegin;
27820700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
278385385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
278433174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
2785c60f73f4SPeter Brune   if (stol)  *stol  = snes->stol;
278633174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
278733174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
27883a40ed3dSBarry Smith   PetscFunctionReturn(0);
278933174efeSLois Curfman McInnes }
279033174efeSLois Curfman McInnes 
27914a2ae208SSatish Balay #undef __FUNCT__
27924a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
279333174efeSLois Curfman McInnes /*@
27949b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
27959b94acceSBarry Smith 
27963f9fe445SBarry Smith    Logically Collective on SNES
2797fee21e36SBarry Smith 
2798c7afd0dbSLois Curfman McInnes    Input Parameters:
2799c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2800c7afd0dbSLois Curfman McInnes -  tol - tolerance
2801c7afd0dbSLois Curfman McInnes 
28029b94acceSBarry Smith    Options Database Key:
2803c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
28049b94acceSBarry Smith 
280536851e7fSLois Curfman McInnes    Level: intermediate
280636851e7fSLois Curfman McInnes 
28079b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
28089b94acceSBarry Smith 
28092492ecdbSBarry Smith .seealso: SNESSetTolerances()
28109b94acceSBarry Smith @*/
28117087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
28129b94acceSBarry Smith {
28133a40ed3dSBarry Smith   PetscFunctionBegin;
28140700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2815c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
28169b94acceSBarry Smith   snes->deltatol = tol;
28173a40ed3dSBarry Smith   PetscFunctionReturn(0);
28189b94acceSBarry Smith }
28199b94acceSBarry Smith 
2820df9fa365SBarry Smith /*
2821df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
2822df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
2823df9fa365SBarry Smith    macros instead of functions
2824df9fa365SBarry Smith */
28254a2ae208SSatish Balay #undef __FUNCT__
2826a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
28277087cfbeSBarry Smith PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2828ce1608b8SBarry Smith {
2829dfbe8321SBarry Smith   PetscErrorCode ierr;
2830ce1608b8SBarry Smith 
2831ce1608b8SBarry Smith   PetscFunctionBegin;
28320700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2833a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
2834ce1608b8SBarry Smith   PetscFunctionReturn(0);
2835ce1608b8SBarry Smith }
2836ce1608b8SBarry Smith 
28374a2ae208SSatish Balay #undef __FUNCT__
2838a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
28397087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2840df9fa365SBarry Smith {
2841dfbe8321SBarry Smith   PetscErrorCode ierr;
2842df9fa365SBarry Smith 
2843df9fa365SBarry Smith   PetscFunctionBegin;
2844a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2845df9fa365SBarry Smith   PetscFunctionReturn(0);
2846df9fa365SBarry Smith }
2847df9fa365SBarry Smith 
28484a2ae208SSatish Balay #undef __FUNCT__
2849a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
28506bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
2851df9fa365SBarry Smith {
2852dfbe8321SBarry Smith   PetscErrorCode ierr;
2853df9fa365SBarry Smith 
2854df9fa365SBarry Smith   PetscFunctionBegin;
2855a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2856df9fa365SBarry Smith   PetscFunctionReturn(0);
2857df9fa365SBarry Smith }
2858df9fa365SBarry Smith 
28597087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
2860b271bb04SBarry Smith #undef __FUNCT__
2861b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
28627087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2863b271bb04SBarry Smith {
2864b271bb04SBarry Smith   PetscDrawLG      lg;
2865b271bb04SBarry Smith   PetscErrorCode   ierr;
2866b271bb04SBarry Smith   PetscReal        x,y,per;
2867b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
2868b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
2869b271bb04SBarry Smith   PetscDraw        draw;
2870b271bb04SBarry Smith   PetscFunctionBegin;
2871b271bb04SBarry Smith   if (!monctx) {
2872b271bb04SBarry Smith     MPI_Comm    comm;
2873b271bb04SBarry Smith 
2874b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2875b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
2876b271bb04SBarry Smith   }
2877b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
2878b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2879b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2880b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
2881b271bb04SBarry Smith   x = (PetscReal) n;
2882b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
2883b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2884b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2885b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2886b271bb04SBarry Smith   }
2887b271bb04SBarry Smith 
2888b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
2889b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2890b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2891b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
2892b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
2893b271bb04SBarry Smith   x = (PetscReal) n;
2894b271bb04SBarry Smith   y = 100.0*per;
2895b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2896b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2897b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2898b271bb04SBarry Smith   }
2899b271bb04SBarry Smith 
2900b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
2901b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2902b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2903b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
2904b271bb04SBarry Smith   x = (PetscReal) n;
2905b271bb04SBarry Smith   y = (prev - rnorm)/prev;
2906b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2907b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2908b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2909b271bb04SBarry Smith   }
2910b271bb04SBarry Smith 
2911b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
2912b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2913b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2914b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
2915b271bb04SBarry Smith   x = (PetscReal) n;
2916b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
2917b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
2918b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2919b271bb04SBarry Smith   }
2920b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2921b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2922b271bb04SBarry Smith   }
2923b271bb04SBarry Smith   prev = rnorm;
2924b271bb04SBarry Smith   PetscFunctionReturn(0);
2925b271bb04SBarry Smith }
2926b271bb04SBarry Smith 
2927b271bb04SBarry Smith #undef __FUNCT__
2928b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
29297087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2930b271bb04SBarry Smith {
2931b271bb04SBarry Smith   PetscErrorCode ierr;
2932b271bb04SBarry Smith 
2933b271bb04SBarry Smith   PetscFunctionBegin;
2934b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2935b271bb04SBarry Smith   PetscFunctionReturn(0);
2936b271bb04SBarry Smith }
2937b271bb04SBarry Smith 
2938b271bb04SBarry Smith #undef __FUNCT__
2939b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
29406bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG *draw)
2941b271bb04SBarry Smith {
2942b271bb04SBarry Smith   PetscErrorCode ierr;
2943b271bb04SBarry Smith 
2944b271bb04SBarry Smith   PetscFunctionBegin;
2945b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2946b271bb04SBarry Smith   PetscFunctionReturn(0);
2947b271bb04SBarry Smith }
2948b271bb04SBarry Smith 
29497a03ce2fSLisandro Dalcin #undef __FUNCT__
29507a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
2951228d79bcSJed Brown /*@
2952228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
2953228d79bcSJed Brown 
2954228d79bcSJed Brown    Collective on SNES
2955228d79bcSJed Brown 
2956228d79bcSJed Brown    Input Parameters:
2957228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
2958228d79bcSJed Brown .  iter - iteration number
2959228d79bcSJed Brown -  rnorm - relative norm of the residual
2960228d79bcSJed Brown 
2961228d79bcSJed Brown    Notes:
2962228d79bcSJed Brown    This routine is called by the SNES implementations.
2963228d79bcSJed Brown    It does not typically need to be called by the user.
2964228d79bcSJed Brown 
2965228d79bcSJed Brown    Level: developer
2966228d79bcSJed Brown 
2967228d79bcSJed Brown .seealso: SNESMonitorSet()
2968228d79bcSJed Brown @*/
29697a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
29707a03ce2fSLisandro Dalcin {
29717a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
29727a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
29737a03ce2fSLisandro Dalcin 
29747a03ce2fSLisandro Dalcin   PetscFunctionBegin;
29757a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
29767a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
29777a03ce2fSLisandro Dalcin   }
29787a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
29797a03ce2fSLisandro Dalcin }
29807a03ce2fSLisandro Dalcin 
29819b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
29829b94acceSBarry Smith 
29834a2ae208SSatish Balay #undef __FUNCT__
2984a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
29859b94acceSBarry Smith /*@C
2986a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
29879b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
29889b94acceSBarry Smith    progress.
29899b94acceSBarry Smith 
29903f9fe445SBarry Smith    Logically Collective on SNES
2991fee21e36SBarry Smith 
2992c7afd0dbSLois Curfman McInnes    Input Parameters:
2993c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2994c7afd0dbSLois Curfman McInnes .  func - monitoring routine
2995b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
2996e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
2997b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
2998b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
29999b94acceSBarry Smith 
3000c7afd0dbSLois Curfman McInnes    Calling sequence of func:
3001a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
3002c7afd0dbSLois Curfman McInnes 
3003c7afd0dbSLois Curfman McInnes +    snes - the SNES context
3004c7afd0dbSLois Curfman McInnes .    its - iteration number
3005c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
300640a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
30079b94acceSBarry Smith 
30089665c990SLois Curfman McInnes    Options Database Keys:
3009a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
3010a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
3011a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
3012cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
3013c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
3014a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
3015c7afd0dbSLois Curfman McInnes                             does not cancel those set via
3016c7afd0dbSLois Curfman McInnes                             the options database.
30179665c990SLois Curfman McInnes 
3018639f9d9dSBarry Smith    Notes:
30196bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
3020a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
30216bc08f3fSLois Curfman McInnes    order in which they were set.
3022639f9d9dSBarry Smith 
3023025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
3024025f1a04SBarry Smith 
302536851e7fSLois Curfman McInnes    Level: intermediate
302636851e7fSLois Curfman McInnes 
30279b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
30289b94acceSBarry Smith 
3029a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
30309b94acceSBarry Smith @*/
3031c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
30329b94acceSBarry Smith {
3033b90d0a6eSBarry Smith   PetscInt       i;
3034649052a6SBarry Smith   PetscErrorCode ierr;
3035b90d0a6eSBarry Smith 
30363a40ed3dSBarry Smith   PetscFunctionBegin;
30370700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
303817186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
3039b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
3040649052a6SBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
3041649052a6SBarry Smith       if (monitordestroy) {
3042c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
3043649052a6SBarry Smith       }
3044b90d0a6eSBarry Smith       PetscFunctionReturn(0);
3045b90d0a6eSBarry Smith     }
3046b90d0a6eSBarry Smith   }
3047b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
3048b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
3049639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
30503a40ed3dSBarry Smith   PetscFunctionReturn(0);
30519b94acceSBarry Smith }
30529b94acceSBarry Smith 
30534a2ae208SSatish Balay #undef __FUNCT__
3054a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
30555cd90555SBarry Smith /*@C
3056a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
30575cd90555SBarry Smith 
30583f9fe445SBarry Smith    Logically Collective on SNES
3059c7afd0dbSLois Curfman McInnes 
30605cd90555SBarry Smith    Input Parameters:
30615cd90555SBarry Smith .  snes - the SNES context
30625cd90555SBarry Smith 
30631a480d89SAdministrator    Options Database Key:
3064a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
3065a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
3066c7afd0dbSLois Curfman McInnes     set via the options database
30675cd90555SBarry Smith 
30685cd90555SBarry Smith    Notes:
30695cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
30705cd90555SBarry Smith 
307136851e7fSLois Curfman McInnes    Level: intermediate
307236851e7fSLois Curfman McInnes 
30735cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
30745cd90555SBarry Smith 
3075a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
30765cd90555SBarry Smith @*/
30777087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
30785cd90555SBarry Smith {
3079d952e501SBarry Smith   PetscErrorCode ierr;
3080d952e501SBarry Smith   PetscInt       i;
3081d952e501SBarry Smith 
30825cd90555SBarry Smith   PetscFunctionBegin;
30830700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3084d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
3085d952e501SBarry Smith     if (snes->monitordestroy[i]) {
30863c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
3087d952e501SBarry Smith     }
3088d952e501SBarry Smith   }
30895cd90555SBarry Smith   snes->numbermonitors = 0;
30905cd90555SBarry Smith   PetscFunctionReturn(0);
30915cd90555SBarry Smith }
30925cd90555SBarry Smith 
30934a2ae208SSatish Balay #undef __FUNCT__
30944a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
30959b94acceSBarry Smith /*@C
30969b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
30979b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
30989b94acceSBarry Smith 
30993f9fe445SBarry Smith    Logically Collective on SNES
3100fee21e36SBarry Smith 
3101c7afd0dbSLois Curfman McInnes    Input Parameters:
3102c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3103c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
31047f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
31057f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
31069b94acceSBarry Smith 
3107c7afd0dbSLois Curfman McInnes    Calling sequence of func:
310806ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
3109c7afd0dbSLois Curfman McInnes 
3110c7afd0dbSLois Curfman McInnes +    snes - the SNES context
311106ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
3112c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
3113184914b5SBarry Smith .    reason - reason for convergence/divergence
3114c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
31154b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
31164b27c08aSLois Curfman McInnes -    f - 2-norm of function
31179b94acceSBarry Smith 
311836851e7fSLois Curfman McInnes    Level: advanced
311936851e7fSLois Curfman McInnes 
31209b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
31219b94acceSBarry Smith 
312285385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
31239b94acceSBarry Smith @*/
31247087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
31259b94acceSBarry Smith {
31267f7931b9SBarry Smith   PetscErrorCode ierr;
31277f7931b9SBarry Smith 
31283a40ed3dSBarry Smith   PetscFunctionBegin;
31290700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
313085385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
31317f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
31327f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
31337f7931b9SBarry Smith   }
313485385478SLisandro Dalcin   snes->ops->converged        = func;
31357f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
313685385478SLisandro Dalcin   snes->cnvP                  = cctx;
31373a40ed3dSBarry Smith   PetscFunctionReturn(0);
31389b94acceSBarry Smith }
31399b94acceSBarry Smith 
31404a2ae208SSatish Balay #undef __FUNCT__
31414a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
314252baeb72SSatish Balay /*@
3143184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
3144184914b5SBarry Smith 
3145184914b5SBarry Smith    Not Collective
3146184914b5SBarry Smith 
3147184914b5SBarry Smith    Input Parameter:
3148184914b5SBarry Smith .  snes - the SNES context
3149184914b5SBarry Smith 
3150184914b5SBarry Smith    Output Parameter:
31514d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
3152184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
3153184914b5SBarry Smith 
3154184914b5SBarry Smith    Level: intermediate
3155184914b5SBarry Smith 
3156184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
3157184914b5SBarry Smith 
3158184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
3159184914b5SBarry Smith 
316085385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
3161184914b5SBarry Smith @*/
31627087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
3163184914b5SBarry Smith {
3164184914b5SBarry Smith   PetscFunctionBegin;
31650700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
31664482741eSBarry Smith   PetscValidPointer(reason,2);
3167184914b5SBarry Smith   *reason = snes->reason;
3168184914b5SBarry Smith   PetscFunctionReturn(0);
3169184914b5SBarry Smith }
3170184914b5SBarry Smith 
31714a2ae208SSatish Balay #undef __FUNCT__
31724a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
3173c9005455SLois Curfman McInnes /*@
3174c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
3175c9005455SLois Curfman McInnes 
31763f9fe445SBarry Smith    Logically Collective on SNES
3177fee21e36SBarry Smith 
3178c7afd0dbSLois Curfman McInnes    Input Parameters:
3179c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
31808c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
3181cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
3182758f92a0SBarry Smith .  na  - size of a and its
318364731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
3184758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
3185c7afd0dbSLois Curfman McInnes 
3186308dcc3eSBarry Smith    Notes:
3187308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
3188308dcc3eSBarry Smith    default array of length 10000 is allocated.
3189308dcc3eSBarry Smith 
3190c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
3191c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
3192c9005455SLois Curfman McInnes    during the section of code that is being timed.
3193c9005455SLois Curfman McInnes 
319436851e7fSLois Curfman McInnes    Level: intermediate
319536851e7fSLois Curfman McInnes 
3196c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
3197758f92a0SBarry Smith 
319808405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
3199758f92a0SBarry Smith 
3200c9005455SLois Curfman McInnes @*/
32017087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
3202c9005455SLois Curfman McInnes {
3203308dcc3eSBarry Smith   PetscErrorCode ierr;
3204308dcc3eSBarry Smith 
32053a40ed3dSBarry Smith   PetscFunctionBegin;
32060700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
32074482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
3208a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
3209308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
3210308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
3211308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
3212308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
3213308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
3214308dcc3eSBarry Smith   }
3215c9005455SLois Curfman McInnes   snes->conv_hist       = a;
3216758f92a0SBarry Smith   snes->conv_hist_its   = its;
3217758f92a0SBarry Smith   snes->conv_hist_max   = na;
3218a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
3219758f92a0SBarry Smith   snes->conv_hist_reset = reset;
3220758f92a0SBarry Smith   PetscFunctionReturn(0);
3221758f92a0SBarry Smith }
3222758f92a0SBarry Smith 
3223308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3224c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
3225c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
3226308dcc3eSBarry Smith EXTERN_C_BEGIN
3227308dcc3eSBarry Smith #undef __FUNCT__
3228308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
3229308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
3230308dcc3eSBarry Smith {
3231308dcc3eSBarry Smith   mxArray        *mat;
3232308dcc3eSBarry Smith   PetscInt       i;
3233308dcc3eSBarry Smith   PetscReal      *ar;
3234308dcc3eSBarry Smith 
3235308dcc3eSBarry Smith   PetscFunctionBegin;
3236308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
3237308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
3238308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
3239308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
3240308dcc3eSBarry Smith   }
3241308dcc3eSBarry Smith   PetscFunctionReturn(mat);
3242308dcc3eSBarry Smith }
3243308dcc3eSBarry Smith EXTERN_C_END
3244308dcc3eSBarry Smith #endif
3245308dcc3eSBarry Smith 
3246308dcc3eSBarry Smith 
32474a2ae208SSatish Balay #undef __FUNCT__
32484a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
32490c4c9dddSBarry Smith /*@C
3250758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
3251758f92a0SBarry Smith 
32523f9fe445SBarry Smith    Not Collective
3253758f92a0SBarry Smith 
3254758f92a0SBarry Smith    Input Parameter:
3255758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
3256758f92a0SBarry Smith 
3257758f92a0SBarry Smith    Output Parameters:
3258758f92a0SBarry Smith .  a   - array to hold history
3259758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
3260758f92a0SBarry Smith          negative if not converged) for each solve.
3261758f92a0SBarry Smith -  na  - size of a and its
3262758f92a0SBarry Smith 
3263758f92a0SBarry Smith    Notes:
3264758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
3265758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
3266758f92a0SBarry Smith 
3267758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
3268758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
3269758f92a0SBarry Smith    during the section of code that is being timed.
3270758f92a0SBarry Smith 
3271758f92a0SBarry Smith    Level: intermediate
3272758f92a0SBarry Smith 
3273758f92a0SBarry Smith .keywords: SNES, get, convergence, history
3274758f92a0SBarry Smith 
3275758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
3276758f92a0SBarry Smith 
3277758f92a0SBarry Smith @*/
32787087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3279758f92a0SBarry Smith {
3280758f92a0SBarry Smith   PetscFunctionBegin;
32810700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3282758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
3283758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
3284758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
32853a40ed3dSBarry Smith   PetscFunctionReturn(0);
3286c9005455SLois Curfman McInnes }
3287c9005455SLois Curfman McInnes 
3288e74ef692SMatthew Knepley #undef __FUNCT__
3289e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
3290ac226902SBarry Smith /*@C
329176b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
3292eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
32937e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
329476b2cf59SMatthew Knepley 
32953f9fe445SBarry Smith   Logically Collective on SNES
329676b2cf59SMatthew Knepley 
329776b2cf59SMatthew Knepley   Input Parameters:
329876b2cf59SMatthew Knepley . snes - The nonlinear solver context
329976b2cf59SMatthew Knepley . func - The function
330076b2cf59SMatthew Knepley 
330176b2cf59SMatthew Knepley   Calling sequence of func:
3302b5d30489SBarry Smith . func (SNES snes, PetscInt step);
330376b2cf59SMatthew Knepley 
330476b2cf59SMatthew Knepley . step - The current step of the iteration
330576b2cf59SMatthew Knepley 
3306fe97e370SBarry Smith   Level: advanced
3307fe97e370SBarry Smith 
3308fe97e370SBarry 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()
3309fe97e370SBarry Smith         This is not used by most users.
331076b2cf59SMatthew Knepley 
331176b2cf59SMatthew Knepley .keywords: SNES, update
3312b5d30489SBarry Smith 
331385385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
331476b2cf59SMatthew Knepley @*/
33157087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
331676b2cf59SMatthew Knepley {
331776b2cf59SMatthew Knepley   PetscFunctionBegin;
33180700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
3319e7788613SBarry Smith   snes->ops->update = func;
332076b2cf59SMatthew Knepley   PetscFunctionReturn(0);
332176b2cf59SMatthew Knepley }
332276b2cf59SMatthew Knepley 
3323e74ef692SMatthew Knepley #undef __FUNCT__
3324e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
332576b2cf59SMatthew Knepley /*@
332676b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
332776b2cf59SMatthew Knepley 
332876b2cf59SMatthew Knepley   Not collective
332976b2cf59SMatthew Knepley 
333076b2cf59SMatthew Knepley   Input Parameters:
333176b2cf59SMatthew Knepley . snes - The nonlinear solver context
333276b2cf59SMatthew Knepley . step - The current step of the iteration
333376b2cf59SMatthew Knepley 
3334205452f4SMatthew Knepley   Level: intermediate
3335205452f4SMatthew Knepley 
333676b2cf59SMatthew Knepley .keywords: SNES, update
3337a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
333876b2cf59SMatthew Knepley @*/
33397087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
334076b2cf59SMatthew Knepley {
334176b2cf59SMatthew Knepley   PetscFunctionBegin;
334276b2cf59SMatthew Knepley   PetscFunctionReturn(0);
334376b2cf59SMatthew Knepley }
334476b2cf59SMatthew Knepley 
33454a2ae208SSatish Balay #undef __FUNCT__
33464a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
33479b94acceSBarry Smith /*
33489b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
33499b94acceSBarry Smith    positive parameter delta.
33509b94acceSBarry Smith 
33519b94acceSBarry Smith     Input Parameters:
3352c7afd0dbSLois Curfman McInnes +   snes - the SNES context
33539b94acceSBarry Smith .   y - approximate solution of linear system
33549b94acceSBarry Smith .   fnorm - 2-norm of current function
3355c7afd0dbSLois Curfman McInnes -   delta - trust region size
33569b94acceSBarry Smith 
33579b94acceSBarry Smith     Output Parameters:
3358c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
33599b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
33609b94acceSBarry Smith     region, and exceeds zero otherwise.
3361c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
33629b94acceSBarry Smith 
33639b94acceSBarry Smith     Note:
33644b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
33659b94acceSBarry Smith     is set to be the maximum allowable step size.
33669b94acceSBarry Smith 
33679b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
33689b94acceSBarry Smith */
3369dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
33709b94acceSBarry Smith {
3371064f8208SBarry Smith   PetscReal      nrm;
3372ea709b57SSatish Balay   PetscScalar    cnorm;
3373dfbe8321SBarry Smith   PetscErrorCode ierr;
33743a40ed3dSBarry Smith 
33753a40ed3dSBarry Smith   PetscFunctionBegin;
33760700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
33770700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3378c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
3379184914b5SBarry Smith 
3380064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
3381064f8208SBarry Smith   if (nrm > *delta) {
3382064f8208SBarry Smith      nrm = *delta/nrm;
3383064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
3384064f8208SBarry Smith      cnorm = nrm;
33852dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
33869b94acceSBarry Smith      *ynorm = *delta;
33879b94acceSBarry Smith   } else {
33889b94acceSBarry Smith      *gpnorm = 0.0;
3389064f8208SBarry Smith      *ynorm = nrm;
33909b94acceSBarry Smith   }
33913a40ed3dSBarry Smith   PetscFunctionReturn(0);
33929b94acceSBarry Smith }
33939b94acceSBarry Smith 
33944a2ae208SSatish Balay #undef __FUNCT__
33954a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
33966ce558aeSBarry Smith /*@C
3397f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
3398f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
33999b94acceSBarry Smith 
3400c7afd0dbSLois Curfman McInnes    Collective on SNES
3401c7afd0dbSLois Curfman McInnes 
3402b2002411SLois Curfman McInnes    Input Parameters:
3403c7afd0dbSLois Curfman McInnes +  snes - the SNES context
34043cebf274SJed Brown .  b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero.
340585385478SLisandro Dalcin -  x - the solution vector.
34069b94acceSBarry Smith 
3407b2002411SLois Curfman McInnes    Notes:
34088ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
34098ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
34108ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
34118ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
34128ddd3da0SLois Curfman McInnes 
341336851e7fSLois Curfman McInnes    Level: beginner
341436851e7fSLois Curfman McInnes 
34159b94acceSBarry Smith .keywords: SNES, nonlinear, solve
34169b94acceSBarry Smith 
3417c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
34189b94acceSBarry Smith @*/
34197087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
34209b94acceSBarry Smith {
3421dfbe8321SBarry Smith   PetscErrorCode ierr;
3422ace3abfcSBarry Smith   PetscBool      flg;
3423eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
3424eabae89aSBarry Smith   PetscViewer    viewer;
3425efd51863SBarry Smith   PetscInt       grid;
3426a69afd8bSBarry Smith   Vec            xcreated = PETSC_NULL;
3427caa4e7f2SJed Brown   DM             dm;
3428052efed2SBarry Smith 
34293a40ed3dSBarry Smith   PetscFunctionBegin;
34300700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3431a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3432a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
34330700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
343485385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
343585385478SLisandro Dalcin 
3436caa4e7f2SJed Brown   if (!x) {
3437caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3438caa4e7f2SJed Brown     ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr);
3439a69afd8bSBarry Smith     x    = xcreated;
3440a69afd8bSBarry Smith   }
3441a69afd8bSBarry Smith 
3442a8248277SBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);}
3443efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
3444efd51863SBarry Smith 
344585385478SLisandro Dalcin     /* set solution vector */
3446efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
34476bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
344885385478SLisandro Dalcin     snes->vec_sol = x;
3449caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3450caa4e7f2SJed Brown 
3451caa4e7f2SJed Brown     /* set affine vector if provided */
345285385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
34536bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
345485385478SLisandro Dalcin     snes->vec_rhs = b;
345585385478SLisandro Dalcin 
345670e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
34573f149594SLisandro Dalcin 
34587eee914bSBarry Smith     if (!grid) {
34597eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
3460d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
3461dd568438SSatish Balay       } else if (snes->dm) {
3462dd568438SSatish Balay         PetscBool ig;
3463dd568438SSatish Balay         ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr);
3464dd568438SSatish Balay         if (ig) {
34657eee914bSBarry Smith           ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr);
34667eee914bSBarry Smith         }
3467d25893d9SBarry Smith       }
3468dd568438SSatish Balay     }
3469d25893d9SBarry Smith 
3470abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
347150ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
3472d5e45103SBarry Smith 
34733f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
34744936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
347585385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
34764936397dSBarry Smith     if (snes->domainerror){
34774936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
34784936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
34794936397dSBarry Smith     }
348017186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
34813f149594SLisandro Dalcin 
34827adad957SLisandro Dalcin     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
3483eabae89aSBarry Smith     if (flg && !PetscPreLoadingOn) {
34847adad957SLisandro Dalcin       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
3485eabae89aSBarry Smith       ierr = SNESView(snes,viewer);CHKERRQ(ierr);
34866bf464f9SBarry Smith       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3487eabae89aSBarry Smith     }
3488eabae89aSBarry Smith 
348990d69ab7SBarry Smith     flg  = PETSC_FALSE;
3490acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
3491da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
34925968eb51SBarry Smith     if (snes->printreason) {
3493a8248277SBarry Smith       ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
34945968eb51SBarry Smith       if (snes->reason > 0) {
3495c7e7b494SJed 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);
34965968eb51SBarry Smith       } else {
3497c7e7b494SJed 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);
34985968eb51SBarry Smith       }
3499a8248277SBarry Smith       ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
35005968eb51SBarry Smith     }
35015968eb51SBarry Smith 
35028501fc72SJed Brown     flg = PETSC_FALSE;
35038501fc72SJed Brown     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
35048501fc72SJed Brown     if (flg) {
35058501fc72SJed Brown       PetscViewer viewer;
35068501fc72SJed Brown       ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
35078501fc72SJed Brown       ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr);
35088501fc72SJed Brown       ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr);
35098501fc72SJed Brown       ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr);
35108501fc72SJed Brown       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
35118501fc72SJed Brown     }
35128501fc72SJed Brown 
3513e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
3514efd51863SBarry Smith     if (grid <  snes->gridsequence) {
3515efd51863SBarry Smith       DM  fine;
3516efd51863SBarry Smith       Vec xnew;
3517efd51863SBarry Smith       Mat interp;
3518efd51863SBarry Smith 
3519efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
3520c5c77316SJed Brown       if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
3521e727c939SJed Brown       ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
3522efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
3523efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
3524c833c3b5SJed Brown       ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr);
3525efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
3526efd51863SBarry Smith       x    = xnew;
3527efd51863SBarry Smith 
3528efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
3529efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
3530efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
3531a8248277SBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);
3532efd51863SBarry Smith     }
3533efd51863SBarry Smith   }
3534a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
35353a40ed3dSBarry Smith   PetscFunctionReturn(0);
35369b94acceSBarry Smith }
35379b94acceSBarry Smith 
35389b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
35399b94acceSBarry Smith 
35404a2ae208SSatish Balay #undef __FUNCT__
35414a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
354282bf6240SBarry Smith /*@C
35434b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
35449b94acceSBarry Smith 
3545fee21e36SBarry Smith    Collective on SNES
3546fee21e36SBarry Smith 
3547c7afd0dbSLois Curfman McInnes    Input Parameters:
3548c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3549454a90a3SBarry Smith -  type - a known method
3550c7afd0dbSLois Curfman McInnes 
3551c7afd0dbSLois Curfman McInnes    Options Database Key:
3552454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
3553c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
3554ae12b187SLois Curfman McInnes 
35559b94acceSBarry Smith    Notes:
3556e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
35574b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
3558c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
35594b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
3560c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
35619b94acceSBarry Smith 
3562ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
3563ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
3564ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
3565ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
3566ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
3567ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
3568ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
3569ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
3570ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
3571b0a32e0cSBarry Smith   appropriate method.
357236851e7fSLois Curfman McInnes 
357336851e7fSLois Curfman McInnes   Level: intermediate
3574a703fe33SLois Curfman McInnes 
3575454a90a3SBarry Smith .keywords: SNES, set, type
3576435da068SBarry Smith 
3577435da068SBarry Smith .seealso: SNESType, SNESCreate()
3578435da068SBarry Smith 
35799b94acceSBarry Smith @*/
35807087cfbeSBarry Smith PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
35819b94acceSBarry Smith {
3582dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
3583ace3abfcSBarry Smith   PetscBool      match;
35843a40ed3dSBarry Smith 
35853a40ed3dSBarry Smith   PetscFunctionBegin;
35860700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35874482741eSBarry Smith   PetscValidCharPointer(type,2);
358882bf6240SBarry Smith 
3589251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
35900f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
359192ff6ae8SBarry Smith 
35924b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
3593e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
359475396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
3595b5c23020SJed Brown   if (snes->ops->destroy) {
3596b5c23020SJed Brown     ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
3597b5c23020SJed Brown     snes->ops->destroy = PETSC_NULL;
3598b5c23020SJed Brown   }
359975396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
360075396ef9SLisandro Dalcin   snes->ops->setup          = 0;
360175396ef9SLisandro Dalcin   snes->ops->solve          = 0;
360275396ef9SLisandro Dalcin   snes->ops->view           = 0;
360375396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
360475396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
360575396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
360675396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
3607454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
360803bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
36099fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
36109fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
36119fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
36129fb22e1aSBarry Smith   }
36139fb22e1aSBarry Smith #endif
36143a40ed3dSBarry Smith   PetscFunctionReturn(0);
36159b94acceSBarry Smith }
36169b94acceSBarry Smith 
3617a847f771SSatish Balay 
36189b94acceSBarry Smith /* --------------------------------------------------------------------- */
36194a2ae208SSatish Balay #undef __FUNCT__
36204a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
362152baeb72SSatish Balay /*@
36229b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
3623f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
36249b94acceSBarry Smith 
3625fee21e36SBarry Smith    Not Collective
3626fee21e36SBarry Smith 
362736851e7fSLois Curfman McInnes    Level: advanced
362836851e7fSLois Curfman McInnes 
36299b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
36309b94acceSBarry Smith 
36319b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
36329b94acceSBarry Smith @*/
36337087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
36349b94acceSBarry Smith {
3635dfbe8321SBarry Smith   PetscErrorCode ierr;
363682bf6240SBarry Smith 
36373a40ed3dSBarry Smith   PetscFunctionBegin;
36381441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
36394c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
36403a40ed3dSBarry Smith   PetscFunctionReturn(0);
36419b94acceSBarry Smith }
36429b94acceSBarry Smith 
36434a2ae208SSatish Balay #undef __FUNCT__
36444a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
36459b94acceSBarry Smith /*@C
36469a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
36479b94acceSBarry Smith 
3648c7afd0dbSLois Curfman McInnes    Not Collective
3649c7afd0dbSLois Curfman McInnes 
36509b94acceSBarry Smith    Input Parameter:
36514b0e389bSBarry Smith .  snes - nonlinear solver context
36529b94acceSBarry Smith 
36539b94acceSBarry Smith    Output Parameter:
36543a7fca6bSBarry Smith .  type - SNES method (a character string)
36559b94acceSBarry Smith 
365636851e7fSLois Curfman McInnes    Level: intermediate
365736851e7fSLois Curfman McInnes 
3658454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
36599b94acceSBarry Smith @*/
36607087cfbeSBarry Smith PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
36619b94acceSBarry Smith {
36623a40ed3dSBarry Smith   PetscFunctionBegin;
36630700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36644482741eSBarry Smith   PetscValidPointer(type,2);
36657adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
36663a40ed3dSBarry Smith   PetscFunctionReturn(0);
36679b94acceSBarry Smith }
36689b94acceSBarry Smith 
36694a2ae208SSatish Balay #undef __FUNCT__
36704a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
367152baeb72SSatish Balay /*@
36729b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
3673c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
36749b94acceSBarry Smith 
3675c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3676c7afd0dbSLois Curfman McInnes 
36779b94acceSBarry Smith    Input Parameter:
36789b94acceSBarry Smith .  snes - the SNES context
36799b94acceSBarry Smith 
36809b94acceSBarry Smith    Output Parameter:
36819b94acceSBarry Smith .  x - the solution
36829b94acceSBarry Smith 
368370e92668SMatthew Knepley    Level: intermediate
368436851e7fSLois Curfman McInnes 
36859b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
36869b94acceSBarry Smith 
368785385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
36889b94acceSBarry Smith @*/
36897087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
36909b94acceSBarry Smith {
36913a40ed3dSBarry Smith   PetscFunctionBegin;
36920700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36934482741eSBarry Smith   PetscValidPointer(x,2);
369485385478SLisandro Dalcin   *x = snes->vec_sol;
369570e92668SMatthew Knepley   PetscFunctionReturn(0);
369670e92668SMatthew Knepley }
369770e92668SMatthew Knepley 
369870e92668SMatthew Knepley #undef __FUNCT__
36994a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
370052baeb72SSatish Balay /*@
37019b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
37029b94acceSBarry Smith    stored.
37039b94acceSBarry Smith 
3704c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3705c7afd0dbSLois Curfman McInnes 
37069b94acceSBarry Smith    Input Parameter:
37079b94acceSBarry Smith .  snes - the SNES context
37089b94acceSBarry Smith 
37099b94acceSBarry Smith    Output Parameter:
37109b94acceSBarry Smith .  x - the solution update
37119b94acceSBarry Smith 
371236851e7fSLois Curfman McInnes    Level: advanced
371336851e7fSLois Curfman McInnes 
37149b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
37159b94acceSBarry Smith 
371685385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
37179b94acceSBarry Smith @*/
37187087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
37199b94acceSBarry Smith {
37203a40ed3dSBarry Smith   PetscFunctionBegin;
37210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37224482741eSBarry Smith   PetscValidPointer(x,2);
372385385478SLisandro Dalcin   *x = snes->vec_sol_update;
37243a40ed3dSBarry Smith   PetscFunctionReturn(0);
37259b94acceSBarry Smith }
37269b94acceSBarry Smith 
37274a2ae208SSatish Balay #undef __FUNCT__
37284a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
37299b94acceSBarry Smith /*@C
37303638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
37319b94acceSBarry Smith 
3732a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
3733c7afd0dbSLois Curfman McInnes 
37349b94acceSBarry Smith    Input Parameter:
37359b94acceSBarry Smith .  snes - the SNES context
37369b94acceSBarry Smith 
37379b94acceSBarry Smith    Output Parameter:
37387bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
373970e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
374070e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
37419b94acceSBarry Smith 
374236851e7fSLois Curfman McInnes    Level: advanced
374336851e7fSLois Curfman McInnes 
3744a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
37459b94acceSBarry Smith 
37464b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
37479b94acceSBarry Smith @*/
37487087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
37499b94acceSBarry Smith {
3750a63bb30eSJed Brown   PetscErrorCode ierr;
37516cab3a1bSJed Brown   DM             dm;
3752a63bb30eSJed Brown 
37533a40ed3dSBarry Smith   PetscFunctionBegin;
37540700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3755a63bb30eSJed Brown   if (r) {
3756a63bb30eSJed Brown     if (!snes->vec_func) {
3757a63bb30eSJed Brown       if (snes->vec_rhs) {
3758a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
3759a63bb30eSJed Brown       } else if (snes->vec_sol) {
3760a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
3761a63bb30eSJed Brown       } else if (snes->dm) {
3762a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
3763a63bb30eSJed Brown       }
3764a63bb30eSJed Brown     }
3765a63bb30eSJed Brown     *r = snes->vec_func;
3766a63bb30eSJed Brown   }
37676cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
37686cab3a1bSJed Brown   ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr);
37693a40ed3dSBarry Smith   PetscFunctionReturn(0);
37709b94acceSBarry Smith }
37719b94acceSBarry Smith 
3772c79ef259SPeter Brune /*@C
3773c79ef259SPeter Brune    SNESGetGS - Returns the GS function and context.
3774c79ef259SPeter Brune 
3775c79ef259SPeter Brune    Input Parameter:
3776c79ef259SPeter Brune .  snes - the SNES context
3777c79ef259SPeter Brune 
3778c79ef259SPeter Brune    Output Parameter:
3779c79ef259SPeter Brune +  gsfunc - the function (or PETSC_NULL)
3780c79ef259SPeter Brune -  ctx    - the function context (or PETSC_NULL)
3781c79ef259SPeter Brune 
3782c79ef259SPeter Brune    Level: advanced
3783c79ef259SPeter Brune 
3784c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
3785c79ef259SPeter Brune 
3786c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction()
3787c79ef259SPeter Brune @*/
3788c79ef259SPeter Brune 
37894a2ae208SSatish Balay #undef __FUNCT__
3790646217ecSPeter Brune #define __FUNCT__ "SNESGetGS"
3791646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx)
3792646217ecSPeter Brune {
37936cab3a1bSJed Brown   PetscErrorCode ierr;
37946cab3a1bSJed Brown   DM             dm;
37956cab3a1bSJed Brown 
3796646217ecSPeter Brune   PetscFunctionBegin;
3797646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37986cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
37996cab3a1bSJed Brown   ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr);
3800646217ecSPeter Brune   PetscFunctionReturn(0);
3801646217ecSPeter Brune }
3802646217ecSPeter Brune 
38034a2ae208SSatish Balay #undef __FUNCT__
38044a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
38053c7409f5SSatish Balay /*@C
38063c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
3807d850072dSLois Curfman McInnes    SNES options in the database.
38083c7409f5SSatish Balay 
38093f9fe445SBarry Smith    Logically Collective on SNES
3810fee21e36SBarry Smith 
3811c7afd0dbSLois Curfman McInnes    Input Parameter:
3812c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3813c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3814c7afd0dbSLois Curfman McInnes 
3815d850072dSLois Curfman McInnes    Notes:
3816a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3817c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3818d850072dSLois Curfman McInnes 
381936851e7fSLois Curfman McInnes    Level: advanced
382036851e7fSLois Curfman McInnes 
38213c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
3822a86d99e1SLois Curfman McInnes 
3823a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
38243c7409f5SSatish Balay @*/
38257087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
38263c7409f5SSatish Balay {
3827dfbe8321SBarry Smith   PetscErrorCode ierr;
38283c7409f5SSatish Balay 
38293a40ed3dSBarry Smith   PetscFunctionBegin;
38300700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3831639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
38321cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
383394b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
38343a40ed3dSBarry Smith   PetscFunctionReturn(0);
38353c7409f5SSatish Balay }
38363c7409f5SSatish Balay 
38374a2ae208SSatish Balay #undef __FUNCT__
38384a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
38393c7409f5SSatish Balay /*@C
3840f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
3841d850072dSLois Curfman McInnes    SNES options in the database.
38423c7409f5SSatish Balay 
38433f9fe445SBarry Smith    Logically Collective on SNES
3844fee21e36SBarry Smith 
3845c7afd0dbSLois Curfman McInnes    Input Parameters:
3846c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3847c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3848c7afd0dbSLois Curfman McInnes 
3849d850072dSLois Curfman McInnes    Notes:
3850a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3851c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3852d850072dSLois Curfman McInnes 
385336851e7fSLois Curfman McInnes    Level: advanced
385436851e7fSLois Curfman McInnes 
38553c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
3856a86d99e1SLois Curfman McInnes 
3857a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
38583c7409f5SSatish Balay @*/
38597087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
38603c7409f5SSatish Balay {
3861dfbe8321SBarry Smith   PetscErrorCode ierr;
38623c7409f5SSatish Balay 
38633a40ed3dSBarry Smith   PetscFunctionBegin;
38640700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3865639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
38661cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
386794b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
38683a40ed3dSBarry Smith   PetscFunctionReturn(0);
38693c7409f5SSatish Balay }
38703c7409f5SSatish Balay 
38714a2ae208SSatish Balay #undef __FUNCT__
38724a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
38739ab63eb5SSatish Balay /*@C
38743c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
38753c7409f5SSatish Balay    SNES options in the database.
38763c7409f5SSatish Balay 
3877c7afd0dbSLois Curfman McInnes    Not Collective
3878c7afd0dbSLois Curfman McInnes 
38793c7409f5SSatish Balay    Input Parameter:
38803c7409f5SSatish Balay .  snes - the SNES context
38813c7409f5SSatish Balay 
38823c7409f5SSatish Balay    Output Parameter:
38833c7409f5SSatish Balay .  prefix - pointer to the prefix string used
38843c7409f5SSatish Balay 
38854ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
38869ab63eb5SSatish Balay    sufficient length to hold the prefix.
38879ab63eb5SSatish Balay 
388836851e7fSLois Curfman McInnes    Level: advanced
388936851e7fSLois Curfman McInnes 
38903c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
3891a86d99e1SLois Curfman McInnes 
3892a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
38933c7409f5SSatish Balay @*/
38947087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
38953c7409f5SSatish Balay {
3896dfbe8321SBarry Smith   PetscErrorCode ierr;
38973c7409f5SSatish Balay 
38983a40ed3dSBarry Smith   PetscFunctionBegin;
38990700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3900639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
39013a40ed3dSBarry Smith   PetscFunctionReturn(0);
39023c7409f5SSatish Balay }
39033c7409f5SSatish Balay 
3904b2002411SLois Curfman McInnes 
39054a2ae208SSatish Balay #undef __FUNCT__
39064a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
39073cea93caSBarry Smith /*@C
39083cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
39093cea93caSBarry Smith 
39107f6c08e0SMatthew Knepley   Level: advanced
39113cea93caSBarry Smith @*/
39127087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
3913b2002411SLois Curfman McInnes {
3914e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
3915dfbe8321SBarry Smith   PetscErrorCode ierr;
3916b2002411SLois Curfman McInnes 
3917b2002411SLois Curfman McInnes   PetscFunctionBegin;
3918b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3919c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3920b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
3921b2002411SLois Curfman McInnes }
3922da9b6338SBarry Smith 
3923da9b6338SBarry Smith #undef __FUNCT__
3924da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
39257087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
3926da9b6338SBarry Smith {
3927dfbe8321SBarry Smith   PetscErrorCode ierr;
392877431f27SBarry Smith   PetscInt       N,i,j;
3929da9b6338SBarry Smith   Vec            u,uh,fh;
3930da9b6338SBarry Smith   PetscScalar    value;
3931da9b6338SBarry Smith   PetscReal      norm;
3932da9b6338SBarry Smith 
3933da9b6338SBarry Smith   PetscFunctionBegin;
3934da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
3935da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
3936da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
3937da9b6338SBarry Smith 
3938da9b6338SBarry Smith   /* currently only works for sequential */
3939da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
3940da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
3941da9b6338SBarry Smith   for (i=0; i<N; i++) {
3942da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
394377431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
3944da9b6338SBarry Smith     for (j=-10; j<11; j++) {
3945ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
3946da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
39473ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
3948da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
394977431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
3950da9b6338SBarry Smith       value = -value;
3951da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
3952da9b6338SBarry Smith     }
3953da9b6338SBarry Smith   }
39546bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
39556bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
3956da9b6338SBarry Smith   PetscFunctionReturn(0);
3957da9b6338SBarry Smith }
395871f87433Sdalcinl 
395971f87433Sdalcinl #undef __FUNCT__
3960fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
396171f87433Sdalcinl /*@
3962fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
396371f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
396471f87433Sdalcinl    Newton method.
396571f87433Sdalcinl 
39663f9fe445SBarry Smith    Logically Collective on SNES
396771f87433Sdalcinl 
396871f87433Sdalcinl    Input Parameters:
396971f87433Sdalcinl +  snes - SNES context
397071f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
397171f87433Sdalcinl 
397264ba62caSBarry Smith     Options Database:
397364ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
397464ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
397564ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
397664ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
397764ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
397864ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
397964ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
398064ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
398164ba62caSBarry Smith 
398271f87433Sdalcinl    Notes:
398371f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
398471f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
398571f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
398671f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
398771f87433Sdalcinl    solver.
398871f87433Sdalcinl 
398971f87433Sdalcinl    Level: advanced
399071f87433Sdalcinl 
399171f87433Sdalcinl    Reference:
399271f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
399371f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
399471f87433Sdalcinl 
399571f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
399671f87433Sdalcinl 
3997fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
399871f87433Sdalcinl @*/
39997087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
400071f87433Sdalcinl {
400171f87433Sdalcinl   PetscFunctionBegin;
40020700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4003acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
400471f87433Sdalcinl   snes->ksp_ewconv = flag;
400571f87433Sdalcinl   PetscFunctionReturn(0);
400671f87433Sdalcinl }
400771f87433Sdalcinl 
400871f87433Sdalcinl #undef __FUNCT__
4009fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
401071f87433Sdalcinl /*@
4011fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
401271f87433Sdalcinl    for computing relative tolerance for linear solvers within an
401371f87433Sdalcinl    inexact Newton method.
401471f87433Sdalcinl 
401571f87433Sdalcinl    Not Collective
401671f87433Sdalcinl 
401771f87433Sdalcinl    Input Parameter:
401871f87433Sdalcinl .  snes - SNES context
401971f87433Sdalcinl 
402071f87433Sdalcinl    Output Parameter:
402171f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
402271f87433Sdalcinl 
402371f87433Sdalcinl    Notes:
402471f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
402571f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
402671f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
402771f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
402871f87433Sdalcinl    solver.
402971f87433Sdalcinl 
403071f87433Sdalcinl    Level: advanced
403171f87433Sdalcinl 
403271f87433Sdalcinl    Reference:
403371f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
403471f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
403571f87433Sdalcinl 
403671f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
403771f87433Sdalcinl 
4038fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
403971f87433Sdalcinl @*/
40407087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
404171f87433Sdalcinl {
404271f87433Sdalcinl   PetscFunctionBegin;
40430700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
404471f87433Sdalcinl   PetscValidPointer(flag,2);
404571f87433Sdalcinl   *flag = snes->ksp_ewconv;
404671f87433Sdalcinl   PetscFunctionReturn(0);
404771f87433Sdalcinl }
404871f87433Sdalcinl 
404971f87433Sdalcinl #undef __FUNCT__
4050fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
405171f87433Sdalcinl /*@
4052fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
405371f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
405471f87433Sdalcinl    Newton method.
405571f87433Sdalcinl 
40563f9fe445SBarry Smith    Logically Collective on SNES
405771f87433Sdalcinl 
405871f87433Sdalcinl    Input Parameters:
405971f87433Sdalcinl +    snes - SNES context
406071f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
406171f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
406271f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
406371f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
406471f87433Sdalcinl              (0 <= gamma2 <= 1)
406571f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
406671f87433Sdalcinl .    alpha2 - power for safeguard
406771f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
406871f87433Sdalcinl 
406971f87433Sdalcinl    Note:
407071f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
407171f87433Sdalcinl 
407271f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
407371f87433Sdalcinl 
407471f87433Sdalcinl    Level: advanced
407571f87433Sdalcinl 
407671f87433Sdalcinl    Reference:
407771f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
407871f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
407971f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
408071f87433Sdalcinl 
408171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
408271f87433Sdalcinl 
4083fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
408471f87433Sdalcinl @*/
40857087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
408671f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
408771f87433Sdalcinl {
4088fa9f3622SBarry Smith   SNESKSPEW *kctx;
408971f87433Sdalcinl   PetscFunctionBegin;
40900700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4091fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4092e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
4093c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
4094c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
4095c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
4096c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
4097c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
4098c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
4099c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
410071f87433Sdalcinl 
410171f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
410271f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
410371f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
410471f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
410571f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
410671f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
410771f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
410871f87433Sdalcinl 
410971f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
4110e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
411171f87433Sdalcinl   }
411271f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
4113e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
411471f87433Sdalcinl   }
411571f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
4116e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
411771f87433Sdalcinl   }
411871f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
4119e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
412071f87433Sdalcinl   }
412171f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
4122e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
412371f87433Sdalcinl   }
412471f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
4125e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
412671f87433Sdalcinl   }
412771f87433Sdalcinl   PetscFunctionReturn(0);
412871f87433Sdalcinl }
412971f87433Sdalcinl 
413071f87433Sdalcinl #undef __FUNCT__
4131fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
413271f87433Sdalcinl /*@
4133fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
413471f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
413571f87433Sdalcinl    Newton method.
413671f87433Sdalcinl 
413771f87433Sdalcinl    Not Collective
413871f87433Sdalcinl 
413971f87433Sdalcinl    Input Parameters:
414071f87433Sdalcinl      snes - SNES context
414171f87433Sdalcinl 
414271f87433Sdalcinl    Output Parameters:
414371f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
414471f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
414571f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
414671f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
414771f87433Sdalcinl              (0 <= gamma2 <= 1)
414871f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
414971f87433Sdalcinl .    alpha2 - power for safeguard
415071f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
415171f87433Sdalcinl 
415271f87433Sdalcinl    Level: advanced
415371f87433Sdalcinl 
415471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
415571f87433Sdalcinl 
4156fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
415771f87433Sdalcinl @*/
41587087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
415971f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
416071f87433Sdalcinl {
4161fa9f3622SBarry Smith   SNESKSPEW *kctx;
416271f87433Sdalcinl   PetscFunctionBegin;
41630700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4164fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4165e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
416671f87433Sdalcinl   if(version)   *version   = kctx->version;
416771f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
416871f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
416971f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
417071f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
417171f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
417271f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
417371f87433Sdalcinl   PetscFunctionReturn(0);
417471f87433Sdalcinl }
417571f87433Sdalcinl 
417671f87433Sdalcinl #undef __FUNCT__
4177fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
4178fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
417971f87433Sdalcinl {
418071f87433Sdalcinl   PetscErrorCode ierr;
4181fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
418271f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
418371f87433Sdalcinl 
418471f87433Sdalcinl   PetscFunctionBegin;
4185e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
418671f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
418771f87433Sdalcinl     rtol = kctx->rtol_0;
418871f87433Sdalcinl   } else {
418971f87433Sdalcinl     if (kctx->version == 1) {
419071f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
419171f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
419271f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
419371f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
419471f87433Sdalcinl     } else if (kctx->version == 2) {
419571f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
419671f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
419771f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
419871f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
419971f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
420071f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
420171f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
420271f87433Sdalcinl       stol = PetscMax(rtol,stol);
420371f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
420471f87433Sdalcinl       /* safeguard: avoid oversolving */
420571f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
420671f87433Sdalcinl       stol = PetscMax(rtol,stol);
420771f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
4208e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
420971f87433Sdalcinl   }
421071f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
421171f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
421271f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
421371f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
421471f87433Sdalcinl   PetscFunctionReturn(0);
421571f87433Sdalcinl }
421671f87433Sdalcinl 
421771f87433Sdalcinl #undef __FUNCT__
4218fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
4219fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
422071f87433Sdalcinl {
422171f87433Sdalcinl   PetscErrorCode ierr;
4222fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
422371f87433Sdalcinl   PCSide         pcside;
422471f87433Sdalcinl   Vec            lres;
422571f87433Sdalcinl 
422671f87433Sdalcinl   PetscFunctionBegin;
4227e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
422871f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
422971f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
423071f87433Sdalcinl   if (kctx->version == 1) {
4231b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
423271f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
423371f87433Sdalcinl       /* KSP residual is true linear residual */
423471f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
423571f87433Sdalcinl     } else {
423671f87433Sdalcinl       /* KSP residual is preconditioned residual */
423771f87433Sdalcinl       /* compute true linear residual norm */
423871f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
423971f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
424071f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
424171f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
42426bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
424371f87433Sdalcinl     }
424471f87433Sdalcinl   }
424571f87433Sdalcinl   PetscFunctionReturn(0);
424671f87433Sdalcinl }
424771f87433Sdalcinl 
424871f87433Sdalcinl #undef __FUNCT__
424971f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
425071f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
425171f87433Sdalcinl {
425271f87433Sdalcinl   PetscErrorCode ierr;
425371f87433Sdalcinl 
425471f87433Sdalcinl   PetscFunctionBegin;
4255fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
425671f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
4257fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
425871f87433Sdalcinl   PetscFunctionReturn(0);
425971f87433Sdalcinl }
42606c699258SBarry Smith 
42616c699258SBarry Smith #undef __FUNCT__
42626c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
42636c699258SBarry Smith /*@
42646c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
42656c699258SBarry Smith 
42663f9fe445SBarry Smith    Logically Collective on SNES
42676c699258SBarry Smith 
42686c699258SBarry Smith    Input Parameters:
42696c699258SBarry Smith +  snes - the preconditioner context
42706c699258SBarry Smith -  dm - the dm
42716c699258SBarry Smith 
42726c699258SBarry Smith    Level: intermediate
42736c699258SBarry Smith 
42746c699258SBarry Smith 
42756c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
42766c699258SBarry Smith @*/
42777087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
42786c699258SBarry Smith {
42796c699258SBarry Smith   PetscErrorCode ierr;
4280345fed2cSBarry Smith   KSP            ksp;
42816cab3a1bSJed Brown   SNESDM         sdm;
42826c699258SBarry Smith 
42836c699258SBarry Smith   PetscFunctionBegin;
42840700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4285d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
42866cab3a1bSJed Brown   if (snes->dm) {               /* Move the SNESDM context over to the new DM unless the new DM already has one */
42876cab3a1bSJed Brown     PetscContainer oldcontainer,container;
42886cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr);
42896cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr);
42906cab3a1bSJed Brown     if (oldcontainer && !container) {
42916cab3a1bSJed Brown       ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr);
42926cab3a1bSJed Brown       ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr);
42936cab3a1bSJed Brown       if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */
42946cab3a1bSJed Brown         sdm->originaldm = dm;
42956cab3a1bSJed Brown       }
42966cab3a1bSJed Brown     }
42976bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
42986cab3a1bSJed Brown   }
42996c699258SBarry Smith   snes->dm = dm;
4300345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4301345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4302f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
43032c155ee1SBarry Smith   if (snes->pc) {
43042c155ee1SBarry Smith     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
43052c155ee1SBarry Smith   }
43066c699258SBarry Smith   PetscFunctionReturn(0);
43076c699258SBarry Smith }
43086c699258SBarry Smith 
43096c699258SBarry Smith #undef __FUNCT__
43106c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
43116c699258SBarry Smith /*@
43126c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
43136c699258SBarry Smith 
43143f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
43156c699258SBarry Smith 
43166c699258SBarry Smith    Input Parameter:
43176c699258SBarry Smith . snes - the preconditioner context
43186c699258SBarry Smith 
43196c699258SBarry Smith    Output Parameter:
43206c699258SBarry Smith .  dm - the dm
43216c699258SBarry Smith 
43226c699258SBarry Smith    Level: intermediate
43236c699258SBarry Smith 
43246c699258SBarry Smith 
43256c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
43266c699258SBarry Smith @*/
43277087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
43286c699258SBarry Smith {
43296cab3a1bSJed Brown   PetscErrorCode ierr;
43306cab3a1bSJed Brown 
43316c699258SBarry Smith   PetscFunctionBegin;
43320700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
43336cab3a1bSJed Brown   if (!snes->dm) {
43346cab3a1bSJed Brown     ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr);
43356cab3a1bSJed Brown   }
43366c699258SBarry Smith   *dm = snes->dm;
43376c699258SBarry Smith   PetscFunctionReturn(0);
43386c699258SBarry Smith }
43390807856dSBarry Smith 
434031823bd8SMatthew G Knepley #undef __FUNCT__
434131823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
434231823bd8SMatthew G Knepley /*@
4343fd4b34e9SJed Brown   SNESSetPC - Sets the nonlinear preconditioner to be used.
434431823bd8SMatthew G Knepley 
434531823bd8SMatthew G Knepley   Collective on SNES
434631823bd8SMatthew G Knepley 
434731823bd8SMatthew G Knepley   Input Parameters:
434831823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
434931823bd8SMatthew G Knepley - pc   - the preconditioner object
435031823bd8SMatthew G Knepley 
435131823bd8SMatthew G Knepley   Notes:
435231823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
435331823bd8SMatthew G Knepley   to configure it using the API).
435431823bd8SMatthew G Knepley 
435531823bd8SMatthew G Knepley   Level: developer
435631823bd8SMatthew G Knepley 
435731823bd8SMatthew G Knepley .keywords: SNES, set, precondition
435831823bd8SMatthew G Knepley .seealso: SNESGetPC()
435931823bd8SMatthew G Knepley @*/
436031823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
436131823bd8SMatthew G Knepley {
436231823bd8SMatthew G Knepley   PetscErrorCode ierr;
436331823bd8SMatthew G Knepley 
436431823bd8SMatthew G Knepley   PetscFunctionBegin;
436531823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
436631823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
436731823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
436831823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4369bf11d3b6SBarry Smith   ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr);
437031823bd8SMatthew G Knepley   snes->pc = pc;
437131823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
437231823bd8SMatthew G Knepley   PetscFunctionReturn(0);
437331823bd8SMatthew G Knepley }
437431823bd8SMatthew G Knepley 
437531823bd8SMatthew G Knepley #undef __FUNCT__
437631823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
437731823bd8SMatthew G Knepley /*@
4378fd4b34e9SJed Brown   SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().
437931823bd8SMatthew G Knepley 
438031823bd8SMatthew G Knepley   Not Collective
438131823bd8SMatthew G Knepley 
438231823bd8SMatthew G Knepley   Input Parameter:
438331823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
438431823bd8SMatthew G Knepley 
438531823bd8SMatthew G Knepley   Output Parameter:
438631823bd8SMatthew G Knepley . pc - preconditioner context
438731823bd8SMatthew G Knepley 
438831823bd8SMatthew G Knepley   Level: developer
438931823bd8SMatthew G Knepley 
439031823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
439131823bd8SMatthew G Knepley .seealso: SNESSetPC()
439231823bd8SMatthew G Knepley @*/
439331823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
439431823bd8SMatthew G Knepley {
439531823bd8SMatthew G Knepley   PetscErrorCode              ierr;
4396a64e098fSPeter Brune   const char                  *optionsprefix;
439731823bd8SMatthew G Knepley 
439831823bd8SMatthew G Knepley   PetscFunctionBegin;
439931823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
440031823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
440131823bd8SMatthew G Knepley   if (!snes->pc) {
440231823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm,&snes->pc);CHKERRQ(ierr);
44034a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);CHKERRQ(ierr);
440431823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes,snes->pc);CHKERRQ(ierr);
4405a64e098fSPeter Brune     ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr);
4406a64e098fSPeter Brune     ierr = SNESSetOptionsPrefix(snes->pc,optionsprefix);CHKERRQ(ierr);
4407a64e098fSPeter Brune     ierr = SNESAppendOptionsPrefix(snes->pc,"npc_");CHKERRQ(ierr);
440831823bd8SMatthew G Knepley   }
440931823bd8SMatthew G Knepley   *pc = snes->pc;
441031823bd8SMatthew G Knepley   PetscFunctionReturn(0);
441131823bd8SMatthew G Knepley }
441231823bd8SMatthew G Knepley 
44139e764e56SPeter Brune #undef __FUNCT__
4414f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch"
44159e764e56SPeter Brune /*@
44168141a3b9SPeter Brune   SNESSetSNESLineSearch - Sets the linesearch on the SNES instance.
44179e764e56SPeter Brune 
44189e764e56SPeter Brune   Collective on SNES
44199e764e56SPeter Brune 
44209e764e56SPeter Brune   Input Parameters:
44219e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
44229e764e56SPeter Brune - linesearch   - the linesearch object
44239e764e56SPeter Brune 
44249e764e56SPeter Brune   Notes:
4425f1c6b773SPeter Brune   Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example,
44269e764e56SPeter Brune   to configure it using the API).
44279e764e56SPeter Brune 
44289e764e56SPeter Brune   Level: developer
44299e764e56SPeter Brune 
44309e764e56SPeter Brune .keywords: SNES, set, linesearch
4431f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch()
44329e764e56SPeter Brune @*/
4433f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch)
44349e764e56SPeter Brune {
44359e764e56SPeter Brune   PetscErrorCode ierr;
44369e764e56SPeter Brune 
44379e764e56SPeter Brune   PetscFunctionBegin;
44389e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4439f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
44409e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
44419e764e56SPeter Brune   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
4442f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
44439e764e56SPeter Brune   snes->linesearch = linesearch;
44449e764e56SPeter Brune   ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
44459e764e56SPeter Brune   PetscFunctionReturn(0);
44469e764e56SPeter Brune }
44479e764e56SPeter Brune 
44489e764e56SPeter Brune #undef __FUNCT__
4449f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch"
4450ea5d4fccSPeter Brune /*@C
44518141a3b9SPeter Brune   SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch()
44528141a3b9SPeter Brune   or creates a default line search instance associated with the SNES and returns it.
44539e764e56SPeter Brune 
44549e764e56SPeter Brune   Not Collective
44559e764e56SPeter Brune 
44569e764e56SPeter Brune   Input Parameter:
44579e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
44589e764e56SPeter Brune 
44599e764e56SPeter Brune   Output Parameter:
44609e764e56SPeter Brune . linesearch - linesearch context
44619e764e56SPeter Brune 
44629e764e56SPeter Brune   Level: developer
44639e764e56SPeter Brune 
44649e764e56SPeter Brune .keywords: SNES, get, linesearch
4465f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch()
44669e764e56SPeter Brune @*/
4467f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch)
44689e764e56SPeter Brune {
44699e764e56SPeter Brune   PetscErrorCode ierr;
44709e764e56SPeter Brune   const char     *optionsprefix;
44719e764e56SPeter Brune 
44729e764e56SPeter Brune   PetscFunctionBegin;
44739e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
44749e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
44759e764e56SPeter Brune   if (!snes->linesearch) {
44769e764e56SPeter Brune     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
4477f1c6b773SPeter Brune     ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr);
4478f1c6b773SPeter Brune     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
4479b1dca40bSPeter Brune     ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr);
44809e764e56SPeter Brune     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
44819e764e56SPeter Brune     ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
44829e764e56SPeter Brune   }
44839e764e56SPeter Brune   *linesearch = snes->linesearch;
44849e764e56SPeter Brune   PetscFunctionReturn(0);
44859e764e56SPeter Brune }
44869e764e56SPeter Brune 
448769b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4488c6db04a5SJed Brown #include <mex.h>
448969b4f73cSBarry Smith 
44908f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
44918f6e6473SBarry Smith 
44920807856dSBarry Smith #undef __FUNCT__
44930807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
44940807856dSBarry Smith /*
44950807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
44960807856dSBarry Smith                          SNESSetFunctionMatlab().
44970807856dSBarry Smith 
44980807856dSBarry Smith    Collective on SNES
44990807856dSBarry Smith 
45000807856dSBarry Smith    Input Parameters:
45010807856dSBarry Smith +  snes - the SNES context
45020807856dSBarry Smith -  x - input vector
45030807856dSBarry Smith 
45040807856dSBarry Smith    Output Parameter:
45050807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
45060807856dSBarry Smith 
45070807856dSBarry Smith    Notes:
45080807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
45090807856dSBarry Smith    implementations, so most users would not generally call this routine
45100807856dSBarry Smith    themselves.
45110807856dSBarry Smith 
45120807856dSBarry Smith    Level: developer
45130807856dSBarry Smith 
45140807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
45150807856dSBarry Smith 
45160807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
451761b2408cSBarry Smith */
45187087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
45190807856dSBarry Smith {
4520e650e774SBarry Smith   PetscErrorCode    ierr;
45218f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
45228f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
45238f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
452491621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
4525e650e774SBarry Smith 
45260807856dSBarry Smith   PetscFunctionBegin;
45270807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
45280807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
45290807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
45300807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
45310807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
45320807856dSBarry Smith 
45330807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
4534e650e774SBarry Smith 
453591621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4536e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4537e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
453891621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
453991621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
454091621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
45418f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
45428f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
4543b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
4544e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4545e650e774SBarry Smith   mxDestroyArray(prhs[0]);
4546e650e774SBarry Smith   mxDestroyArray(prhs[1]);
4547e650e774SBarry Smith   mxDestroyArray(prhs[2]);
45488f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
4549e650e774SBarry Smith   mxDestroyArray(plhs[0]);
45500807856dSBarry Smith   PetscFunctionReturn(0);
45510807856dSBarry Smith }
45520807856dSBarry Smith 
45530807856dSBarry Smith 
45540807856dSBarry Smith #undef __FUNCT__
45550807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
455661b2408cSBarry Smith /*
45570807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
45580807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4559e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
45600807856dSBarry Smith 
45610807856dSBarry Smith    Logically Collective on SNES
45620807856dSBarry Smith 
45630807856dSBarry Smith    Input Parameters:
45640807856dSBarry Smith +  snes - the SNES context
45650807856dSBarry Smith .  r - vector to store function value
45660807856dSBarry Smith -  func - function evaluation routine
45670807856dSBarry Smith 
45680807856dSBarry Smith    Calling sequence of func:
456961b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
45700807856dSBarry Smith 
45710807856dSBarry Smith 
45720807856dSBarry Smith    Notes:
45730807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
45740807856dSBarry Smith $      f'(x) x = -f(x),
45750807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
45760807856dSBarry Smith 
45770807856dSBarry Smith    Level: beginner
45780807856dSBarry Smith 
45790807856dSBarry Smith .keywords: SNES, nonlinear, set, function
45800807856dSBarry Smith 
45810807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
458261b2408cSBarry Smith */
45837087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
45840807856dSBarry Smith {
45850807856dSBarry Smith   PetscErrorCode    ierr;
45868f6e6473SBarry Smith   SNESMatlabContext *sctx;
45870807856dSBarry Smith 
45880807856dSBarry Smith   PetscFunctionBegin;
45898f6e6473SBarry Smith   /* currently sctx is memory bleed */
45908f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
45918f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
45928f6e6473SBarry Smith   /*
45938f6e6473SBarry Smith      This should work, but it doesn't
45948f6e6473SBarry Smith   sctx->ctx = ctx;
45958f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
45968f6e6473SBarry Smith   */
45978f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
45988f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
45990807856dSBarry Smith   PetscFunctionReturn(0);
46000807856dSBarry Smith }
460169b4f73cSBarry Smith 
460261b2408cSBarry Smith #undef __FUNCT__
460361b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
460461b2408cSBarry Smith /*
460561b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
460661b2408cSBarry Smith                          SNESSetJacobianMatlab().
460761b2408cSBarry Smith 
460861b2408cSBarry Smith    Collective on SNES
460961b2408cSBarry Smith 
461061b2408cSBarry Smith    Input Parameters:
461161b2408cSBarry Smith +  snes - the SNES context
461261b2408cSBarry Smith .  x - input vector
461361b2408cSBarry Smith .  A, B - the matrices
461461b2408cSBarry Smith -  ctx - user context
461561b2408cSBarry Smith 
461661b2408cSBarry Smith    Output Parameter:
461761b2408cSBarry Smith .  flag - structure of the matrix
461861b2408cSBarry Smith 
461961b2408cSBarry Smith    Level: developer
462061b2408cSBarry Smith 
462161b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
462261b2408cSBarry Smith 
462361b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
462461b2408cSBarry Smith @*/
46257087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
462661b2408cSBarry Smith {
462761b2408cSBarry Smith   PetscErrorCode    ierr;
462861b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
462961b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
463061b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
463161b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
463261b2408cSBarry Smith 
463361b2408cSBarry Smith   PetscFunctionBegin;
463461b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
463561b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
463661b2408cSBarry Smith 
463761b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
463861b2408cSBarry Smith 
463961b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
464061b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
464161b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
464261b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
464361b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
464461b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
464561b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
464661b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
464761b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
464861b2408cSBarry Smith   prhs[5] =  sctx->ctx;
4649b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
465061b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
465161b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
465261b2408cSBarry Smith   mxDestroyArray(prhs[0]);
465361b2408cSBarry Smith   mxDestroyArray(prhs[1]);
465461b2408cSBarry Smith   mxDestroyArray(prhs[2]);
465561b2408cSBarry Smith   mxDestroyArray(prhs[3]);
465661b2408cSBarry Smith   mxDestroyArray(prhs[4]);
465761b2408cSBarry Smith   mxDestroyArray(plhs[0]);
465861b2408cSBarry Smith   mxDestroyArray(plhs[1]);
465961b2408cSBarry Smith   PetscFunctionReturn(0);
466061b2408cSBarry Smith }
466161b2408cSBarry Smith 
466261b2408cSBarry Smith 
466361b2408cSBarry Smith #undef __FUNCT__
466461b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
466561b2408cSBarry Smith /*
466661b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
466761b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4668e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
466961b2408cSBarry Smith 
467061b2408cSBarry Smith    Logically Collective on SNES
467161b2408cSBarry Smith 
467261b2408cSBarry Smith    Input Parameters:
467361b2408cSBarry Smith +  snes - the SNES context
467461b2408cSBarry Smith .  A,B - Jacobian matrices
467561b2408cSBarry Smith .  func - function evaluation routine
467661b2408cSBarry Smith -  ctx - user context
467761b2408cSBarry Smith 
467861b2408cSBarry Smith    Calling sequence of func:
467961b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
468061b2408cSBarry Smith 
468161b2408cSBarry Smith 
468261b2408cSBarry Smith    Level: developer
468361b2408cSBarry Smith 
468461b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
468561b2408cSBarry Smith 
468661b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
468761b2408cSBarry Smith */
46887087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
468961b2408cSBarry Smith {
469061b2408cSBarry Smith   PetscErrorCode    ierr;
469161b2408cSBarry Smith   SNESMatlabContext *sctx;
469261b2408cSBarry Smith 
469361b2408cSBarry Smith   PetscFunctionBegin;
469461b2408cSBarry Smith   /* currently sctx is memory bleed */
469561b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
469661b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
469761b2408cSBarry Smith   /*
469861b2408cSBarry Smith      This should work, but it doesn't
469961b2408cSBarry Smith   sctx->ctx = ctx;
470061b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
470161b2408cSBarry Smith   */
470261b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
470361b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
470461b2408cSBarry Smith   PetscFunctionReturn(0);
470561b2408cSBarry Smith }
470669b4f73cSBarry Smith 
4707f9eb7ae2SShri Abhyankar #undef __FUNCT__
4708f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
4709f9eb7ae2SShri Abhyankar /*
4710f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
4711f9eb7ae2SShri Abhyankar 
4712f9eb7ae2SShri Abhyankar    Collective on SNES
4713f9eb7ae2SShri Abhyankar 
4714f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
4715f9eb7ae2SShri Abhyankar @*/
47167087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
4717f9eb7ae2SShri Abhyankar {
4718f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
471948f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
4720f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
4721f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
4722f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
4723f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
4724f9eb7ae2SShri Abhyankar 
4725f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4726f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4727f9eb7ae2SShri Abhyankar 
4728f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4729f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4730f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
4731f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
4732f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
4733f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
4734f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
4735f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
4736f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
4737f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4738f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
4739f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
4740f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
4741f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
4742f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
4743f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
4744f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4745f9eb7ae2SShri Abhyankar }
4746f9eb7ae2SShri Abhyankar 
4747f9eb7ae2SShri Abhyankar 
4748f9eb7ae2SShri Abhyankar #undef __FUNCT__
4749f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
4750f9eb7ae2SShri Abhyankar /*
4751e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
4752f9eb7ae2SShri Abhyankar 
4753f9eb7ae2SShri Abhyankar    Level: developer
4754f9eb7ae2SShri Abhyankar 
4755f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
4756f9eb7ae2SShri Abhyankar 
4757f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
4758f9eb7ae2SShri Abhyankar */
47597087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
4760f9eb7ae2SShri Abhyankar {
4761f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
4762f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
4763f9eb7ae2SShri Abhyankar 
4764f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4765f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
4766f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
4767f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4768f9eb7ae2SShri Abhyankar   /*
4769f9eb7ae2SShri Abhyankar      This should work, but it doesn't
4770f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
4771f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
4772f9eb7ae2SShri Abhyankar   */
4773f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
4774f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4775f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4776f9eb7ae2SShri Abhyankar }
4777f9eb7ae2SShri Abhyankar 
477869b4f73cSBarry Smith #endif
4779