xref: /petsc/src/snes/interface/snes.c (revision a64e098fc20714e9cef7e27e1bf2de9a50c27852)
19b94acceSBarry Smith 
2b45d2f2cSJed Brown #include <petsc-private/snesimpl.h>      /*I "petscsnes.h"  I*/
36cab3a1bSJed Brown #include <petscdmshell.h>                /*I "petscdmshell.h" I*/
4*a64e098fSPeter 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;
519*a64e098fSPeter 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;
23123a40ed3dSBarry Smith 
23133a40ed3dSBarry Smith   PetscFunctionBegin;
23140700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
23154dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
23169b94acceSBarry Smith 
23177adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
231885385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
231985385478SLisandro Dalcin   }
232085385478SLisandro Dalcin 
2321a63bb30eSJed Brown   ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
232217186662SBarry Smith   if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
232358c9b817SLisandro Dalcin   if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
232458c9b817SLisandro Dalcin 
232558c9b817SLisandro Dalcin   if (!snes->vec_sol_update /* && snes->vec_sol */) {
232658c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
232758c9b817SLisandro Dalcin     ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr);
232858c9b817SLisandro Dalcin   }
232958c9b817SLisandro Dalcin 
23306cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
23316cab3a1bSJed Brown   ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */
23326cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
23336cab3a1bSJed Brown   if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc");
23346cab3a1bSJed Brown   if (!snes->vec_func) {
23356cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2336214df951SJed Brown   }
2337efd51863SBarry Smith 
2338b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
2339b710008aSBarry Smith 
2340f1c6b773SPeter Brune   if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);}
23419e764e56SPeter Brune 
2342d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
2343d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
2344d25893d9SBarry Smith   }
2345d25893d9SBarry Smith 
2346410397dcSLisandro Dalcin   if (snes->ops->setup) {
2347410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2348410397dcSLisandro Dalcin   }
234958c9b817SLisandro Dalcin 
23507aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
23513a40ed3dSBarry Smith   PetscFunctionReturn(0);
23529b94acceSBarry Smith }
23539b94acceSBarry Smith 
23544a2ae208SSatish Balay #undef __FUNCT__
235537596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
235637596af1SLisandro Dalcin /*@
235737596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
235837596af1SLisandro Dalcin 
235937596af1SLisandro Dalcin    Collective on SNES
236037596af1SLisandro Dalcin 
236137596af1SLisandro Dalcin    Input Parameter:
236237596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
236337596af1SLisandro Dalcin 
2364d25893d9SBarry Smith    Level: intermediate
2365d25893d9SBarry Smith 
2366d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
236737596af1SLisandro Dalcin 
236837596af1SLisandro Dalcin .keywords: SNES, destroy
236937596af1SLisandro Dalcin 
237037596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
237137596af1SLisandro Dalcin @*/
237237596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
237337596af1SLisandro Dalcin {
237437596af1SLisandro Dalcin   PetscErrorCode ierr;
237537596af1SLisandro Dalcin 
237637596af1SLisandro Dalcin   PetscFunctionBegin;
237737596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2378d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
2379d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
2380d25893d9SBarry Smith     snes->user = PETSC_NULL;
2381d25893d9SBarry Smith   }
23828a23116dSBarry Smith   if (snes->pc) {
23838a23116dSBarry Smith     ierr = SNESReset(snes->pc);CHKERRQ(ierr);
23848a23116dSBarry Smith   }
23858a23116dSBarry Smith 
238637596af1SLisandro Dalcin   if (snes->ops->reset) {
238737596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
238837596af1SLisandro Dalcin   }
23899e764e56SPeter Brune   if (snes->ksp) {
23909e764e56SPeter Brune     ierr = KSPReset(snes->ksp);CHKERRQ(ierr);
23919e764e56SPeter Brune   }
23929e764e56SPeter Brune 
23939e764e56SPeter Brune   if (snes->linesearch) {
2394f1c6b773SPeter Brune     ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr);
23959e764e56SPeter Brune   }
23969e764e56SPeter Brune 
23976bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
23986bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
23996bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
24006bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
24016bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
24026bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2403c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
2404c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
240537596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
240637596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
240737596af1SLisandro Dalcin   PetscFunctionReturn(0);
240837596af1SLisandro Dalcin }
240937596af1SLisandro Dalcin 
241037596af1SLisandro Dalcin #undef __FUNCT__
24114a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
241252baeb72SSatish Balay /*@
24139b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
24149b94acceSBarry Smith    with SNESCreate().
24159b94acceSBarry Smith 
2416c7afd0dbSLois Curfman McInnes    Collective on SNES
2417c7afd0dbSLois Curfman McInnes 
24189b94acceSBarry Smith    Input Parameter:
24199b94acceSBarry Smith .  snes - the SNES context
24209b94acceSBarry Smith 
242136851e7fSLois Curfman McInnes    Level: beginner
242236851e7fSLois Curfman McInnes 
24239b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
24249b94acceSBarry Smith 
242563a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
24269b94acceSBarry Smith @*/
24276bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
24289b94acceSBarry Smith {
24296849ba73SBarry Smith   PetscErrorCode ierr;
24303a40ed3dSBarry Smith 
24313a40ed3dSBarry Smith   PetscFunctionBegin;
24326bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
24336bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
24346bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2435d4bb536fSBarry Smith 
24366bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
24378a23116dSBarry Smith   ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr);
24386b8b9a38SLisandro Dalcin 
2439be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
24406bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
24416bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
24426d4c513bSLisandro Dalcin 
24436bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
24446bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
2445f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr);
24466b8b9a38SLisandro Dalcin 
24476bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
24486bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
24496bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
24506b8b9a38SLisandro Dalcin   }
24516bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
24526bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
24536bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
245458c9b817SLisandro Dalcin   }
24556bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2456a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
24573a40ed3dSBarry Smith  PetscFunctionReturn(0);
24589b94acceSBarry Smith }
24599b94acceSBarry Smith 
24609b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
24619b94acceSBarry Smith 
24624a2ae208SSatish Balay #undef __FUNCT__
2463a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
2464a8054027SBarry Smith /*@
2465a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2466a8054027SBarry Smith 
24673f9fe445SBarry Smith    Logically Collective on SNES
2468a8054027SBarry Smith 
2469a8054027SBarry Smith    Input Parameters:
2470a8054027SBarry Smith +  snes - the SNES context
2471a8054027SBarry 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
24723b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2473a8054027SBarry Smith 
2474a8054027SBarry Smith    Options Database Keys:
2475a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2476a8054027SBarry Smith 
2477a8054027SBarry Smith    Notes:
2478a8054027SBarry Smith    The default is 1
2479a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2480a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2481a8054027SBarry Smith 
2482a8054027SBarry Smith    Level: intermediate
2483a8054027SBarry Smith 
2484a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2485a8054027SBarry Smith 
2486e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2487a8054027SBarry Smith 
2488a8054027SBarry Smith @*/
24897087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2490a8054027SBarry Smith {
2491a8054027SBarry Smith   PetscFunctionBegin;
24920700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2493e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2494e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2495c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2496a8054027SBarry Smith   snes->lagpreconditioner = lag;
2497a8054027SBarry Smith   PetscFunctionReturn(0);
2498a8054027SBarry Smith }
2499a8054027SBarry Smith 
2500a8054027SBarry Smith #undef __FUNCT__
2501efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
2502efd51863SBarry Smith /*@
2503efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2504efd51863SBarry Smith 
2505efd51863SBarry Smith    Logically Collective on SNES
2506efd51863SBarry Smith 
2507efd51863SBarry Smith    Input Parameters:
2508efd51863SBarry Smith +  snes - the SNES context
2509efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
2510efd51863SBarry Smith 
2511efd51863SBarry Smith    Options Database Keys:
2512efd51863SBarry Smith .    -snes_grid_sequence <steps>
2513efd51863SBarry Smith 
2514efd51863SBarry Smith    Level: intermediate
2515efd51863SBarry Smith 
2516c0df2a02SJed Brown    Notes:
2517c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2518c0df2a02SJed Brown 
2519efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2520efd51863SBarry Smith 
2521efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2522efd51863SBarry Smith 
2523efd51863SBarry Smith @*/
2524efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2525efd51863SBarry Smith {
2526efd51863SBarry Smith   PetscFunctionBegin;
2527efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2528efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
2529efd51863SBarry Smith   snes->gridsequence = steps;
2530efd51863SBarry Smith   PetscFunctionReturn(0);
2531efd51863SBarry Smith }
2532efd51863SBarry Smith 
2533efd51863SBarry Smith #undef __FUNCT__
2534a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
2535a8054027SBarry Smith /*@
2536a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
2537a8054027SBarry Smith 
25383f9fe445SBarry Smith    Not Collective
2539a8054027SBarry Smith 
2540a8054027SBarry Smith    Input Parameter:
2541a8054027SBarry Smith .  snes - the SNES context
2542a8054027SBarry Smith 
2543a8054027SBarry Smith    Output Parameter:
2544a8054027SBarry 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
25453b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2546a8054027SBarry Smith 
2547a8054027SBarry Smith    Options Database Keys:
2548a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2549a8054027SBarry Smith 
2550a8054027SBarry Smith    Notes:
2551a8054027SBarry Smith    The default is 1
2552a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2553a8054027SBarry Smith 
2554a8054027SBarry Smith    Level: intermediate
2555a8054027SBarry Smith 
2556a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2557a8054027SBarry Smith 
2558a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
2559a8054027SBarry Smith 
2560a8054027SBarry Smith @*/
25617087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
2562a8054027SBarry Smith {
2563a8054027SBarry Smith   PetscFunctionBegin;
25640700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2565a8054027SBarry Smith   *lag = snes->lagpreconditioner;
2566a8054027SBarry Smith   PetscFunctionReturn(0);
2567a8054027SBarry Smith }
2568a8054027SBarry Smith 
2569a8054027SBarry Smith #undef __FUNCT__
2570e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
2571e35cf81dSBarry Smith /*@
2572e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
2573e35cf81dSBarry Smith      often the preconditioner is rebuilt.
2574e35cf81dSBarry Smith 
25753f9fe445SBarry Smith    Logically Collective on SNES
2576e35cf81dSBarry Smith 
2577e35cf81dSBarry Smith    Input Parameters:
2578e35cf81dSBarry Smith +  snes - the SNES context
2579e35cf81dSBarry 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
2580fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
2581e35cf81dSBarry Smith 
2582e35cf81dSBarry Smith    Options Database Keys:
2583e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2584e35cf81dSBarry Smith 
2585e35cf81dSBarry Smith    Notes:
2586e35cf81dSBarry Smith    The default is 1
2587e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2588fe3ffe1eSBarry 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
2589fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
2590e35cf81dSBarry Smith 
2591e35cf81dSBarry Smith    Level: intermediate
2592e35cf81dSBarry Smith 
2593e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2594e35cf81dSBarry Smith 
2595e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
2596e35cf81dSBarry Smith 
2597e35cf81dSBarry Smith @*/
25987087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
2599e35cf81dSBarry Smith {
2600e35cf81dSBarry Smith   PetscFunctionBegin;
26010700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2602e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2603e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2604c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2605e35cf81dSBarry Smith   snes->lagjacobian = lag;
2606e35cf81dSBarry Smith   PetscFunctionReturn(0);
2607e35cf81dSBarry Smith }
2608e35cf81dSBarry Smith 
2609e35cf81dSBarry Smith #undef __FUNCT__
2610e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
2611e35cf81dSBarry Smith /*@
2612e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
2613e35cf81dSBarry Smith 
26143f9fe445SBarry Smith    Not Collective
2615e35cf81dSBarry Smith 
2616e35cf81dSBarry Smith    Input Parameter:
2617e35cf81dSBarry Smith .  snes - the SNES context
2618e35cf81dSBarry Smith 
2619e35cf81dSBarry Smith    Output Parameter:
2620e35cf81dSBarry 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
2621e35cf81dSBarry Smith          the Jacobian is built etc.
2622e35cf81dSBarry Smith 
2623e35cf81dSBarry Smith    Options Database Keys:
2624e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2625e35cf81dSBarry Smith 
2626e35cf81dSBarry Smith    Notes:
2627e35cf81dSBarry Smith    The default is 1
2628e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2629e35cf81dSBarry Smith 
2630e35cf81dSBarry Smith    Level: intermediate
2631e35cf81dSBarry Smith 
2632e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2633e35cf81dSBarry Smith 
2634e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
2635e35cf81dSBarry Smith 
2636e35cf81dSBarry Smith @*/
26377087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
2638e35cf81dSBarry Smith {
2639e35cf81dSBarry Smith   PetscFunctionBegin;
26400700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2641e35cf81dSBarry Smith   *lag = snes->lagjacobian;
2642e35cf81dSBarry Smith   PetscFunctionReturn(0);
2643e35cf81dSBarry Smith }
2644e35cf81dSBarry Smith 
2645e35cf81dSBarry Smith #undef __FUNCT__
26464a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
26479b94acceSBarry Smith /*@
2648d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
26499b94acceSBarry Smith 
26503f9fe445SBarry Smith    Logically Collective on SNES
2651c7afd0dbSLois Curfman McInnes 
26529b94acceSBarry Smith    Input Parameters:
2653c7afd0dbSLois Curfman McInnes +  snes - the SNES context
265470441072SBarry Smith .  abstol - absolute convergence tolerance
265533174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
265633174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
265733174efeSLois Curfman McInnes            of the change in the solution between steps
265833174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2659c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2660fee21e36SBarry Smith 
266133174efeSLois Curfman McInnes    Options Database Keys:
266270441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
2663c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
2664c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
2665c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
2666c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
26679b94acceSBarry Smith 
2668d7a720efSLois Curfman McInnes    Notes:
26699b94acceSBarry Smith    The default maximum number of iterations is 50.
26709b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
26719b94acceSBarry Smith 
267236851e7fSLois Curfman McInnes    Level: intermediate
267336851e7fSLois Curfman McInnes 
267433174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
26759b94acceSBarry Smith 
26762492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
26779b94acceSBarry Smith @*/
26787087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
26799b94acceSBarry Smith {
26803a40ed3dSBarry Smith   PetscFunctionBegin;
26810700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2682c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
2683c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
2684c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
2685c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
2686c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
2687c5eb9154SBarry Smith 
2688ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
2689ab54825eSJed Brown     if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol);
2690ab54825eSJed Brown     snes->abstol = abstol;
2691ab54825eSJed Brown   }
2692ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
2693ab54825eSJed 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);
2694ab54825eSJed Brown     snes->rtol = rtol;
2695ab54825eSJed Brown   }
2696ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
2697ab54825eSJed Brown     if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol);
2698c60f73f4SPeter Brune     snes->stol = stol;
2699ab54825eSJed Brown   }
2700ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
2701ab54825eSJed Brown     if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
2702ab54825eSJed Brown     snes->max_its = maxit;
2703ab54825eSJed Brown   }
2704ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
2705ab54825eSJed Brown     if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
2706ab54825eSJed Brown     snes->max_funcs = maxf;
2707ab54825eSJed Brown   }
270888976e71SPeter Brune   snes->tolerancesset = PETSC_TRUE;
27093a40ed3dSBarry Smith   PetscFunctionReturn(0);
27109b94acceSBarry Smith }
27119b94acceSBarry Smith 
27124a2ae208SSatish Balay #undef __FUNCT__
27134a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
27149b94acceSBarry Smith /*@
271533174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
271633174efeSLois Curfman McInnes 
2717c7afd0dbSLois Curfman McInnes    Not Collective
2718c7afd0dbSLois Curfman McInnes 
271933174efeSLois Curfman McInnes    Input Parameters:
2720c7afd0dbSLois Curfman McInnes +  snes - the SNES context
272185385478SLisandro Dalcin .  atol - absolute convergence tolerance
272233174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
272333174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
272433174efeSLois Curfman McInnes            of the change in the solution between steps
272533174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2726c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2727fee21e36SBarry Smith 
272833174efeSLois Curfman McInnes    Notes:
272933174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
273033174efeSLois Curfman McInnes 
273136851e7fSLois Curfman McInnes    Level: intermediate
273236851e7fSLois Curfman McInnes 
273333174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
273433174efeSLois Curfman McInnes 
273533174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
273633174efeSLois Curfman McInnes @*/
27377087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
273833174efeSLois Curfman McInnes {
27393a40ed3dSBarry Smith   PetscFunctionBegin;
27400700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
274185385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
274233174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
2743c60f73f4SPeter Brune   if (stol)  *stol  = snes->stol;
274433174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
274533174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
27463a40ed3dSBarry Smith   PetscFunctionReturn(0);
274733174efeSLois Curfman McInnes }
274833174efeSLois Curfman McInnes 
27494a2ae208SSatish Balay #undef __FUNCT__
27504a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
275133174efeSLois Curfman McInnes /*@
27529b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
27539b94acceSBarry Smith 
27543f9fe445SBarry Smith    Logically Collective on SNES
2755fee21e36SBarry Smith 
2756c7afd0dbSLois Curfman McInnes    Input Parameters:
2757c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2758c7afd0dbSLois Curfman McInnes -  tol - tolerance
2759c7afd0dbSLois Curfman McInnes 
27609b94acceSBarry Smith    Options Database Key:
2761c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
27629b94acceSBarry Smith 
276336851e7fSLois Curfman McInnes    Level: intermediate
276436851e7fSLois Curfman McInnes 
27659b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
27669b94acceSBarry Smith 
27672492ecdbSBarry Smith .seealso: SNESSetTolerances()
27689b94acceSBarry Smith @*/
27697087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
27709b94acceSBarry Smith {
27713a40ed3dSBarry Smith   PetscFunctionBegin;
27720700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2773c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
27749b94acceSBarry Smith   snes->deltatol = tol;
27753a40ed3dSBarry Smith   PetscFunctionReturn(0);
27769b94acceSBarry Smith }
27779b94acceSBarry Smith 
2778df9fa365SBarry Smith /*
2779df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
2780df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
2781df9fa365SBarry Smith    macros instead of functions
2782df9fa365SBarry Smith */
27834a2ae208SSatish Balay #undef __FUNCT__
2784a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
27857087cfbeSBarry Smith PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2786ce1608b8SBarry Smith {
2787dfbe8321SBarry Smith   PetscErrorCode ierr;
2788ce1608b8SBarry Smith 
2789ce1608b8SBarry Smith   PetscFunctionBegin;
27900700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2791a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
2792ce1608b8SBarry Smith   PetscFunctionReturn(0);
2793ce1608b8SBarry Smith }
2794ce1608b8SBarry Smith 
27954a2ae208SSatish Balay #undef __FUNCT__
2796a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
27977087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2798df9fa365SBarry Smith {
2799dfbe8321SBarry Smith   PetscErrorCode ierr;
2800df9fa365SBarry Smith 
2801df9fa365SBarry Smith   PetscFunctionBegin;
2802a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2803df9fa365SBarry Smith   PetscFunctionReturn(0);
2804df9fa365SBarry Smith }
2805df9fa365SBarry Smith 
28064a2ae208SSatish Balay #undef __FUNCT__
2807a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
28086bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
2809df9fa365SBarry Smith {
2810dfbe8321SBarry Smith   PetscErrorCode ierr;
2811df9fa365SBarry Smith 
2812df9fa365SBarry Smith   PetscFunctionBegin;
2813a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2814df9fa365SBarry Smith   PetscFunctionReturn(0);
2815df9fa365SBarry Smith }
2816df9fa365SBarry Smith 
28177087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
2818b271bb04SBarry Smith #undef __FUNCT__
2819b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
28207087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2821b271bb04SBarry Smith {
2822b271bb04SBarry Smith   PetscDrawLG      lg;
2823b271bb04SBarry Smith   PetscErrorCode   ierr;
2824b271bb04SBarry Smith   PetscReal        x,y,per;
2825b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
2826b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
2827b271bb04SBarry Smith   PetscDraw        draw;
2828b271bb04SBarry Smith   PetscFunctionBegin;
2829b271bb04SBarry Smith   if (!monctx) {
2830b271bb04SBarry Smith     MPI_Comm    comm;
2831b271bb04SBarry Smith 
2832b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2833b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
2834b271bb04SBarry Smith   }
2835b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
2836b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2837b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2838b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
2839b271bb04SBarry Smith   x = (PetscReal) n;
2840b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
2841b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2842b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2843b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2844b271bb04SBarry Smith   }
2845b271bb04SBarry Smith 
2846b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
2847b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2848b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2849b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
2850b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
2851b271bb04SBarry Smith   x = (PetscReal) n;
2852b271bb04SBarry Smith   y = 100.0*per;
2853b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2854b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2855b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2856b271bb04SBarry Smith   }
2857b271bb04SBarry Smith 
2858b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
2859b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2860b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2861b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
2862b271bb04SBarry Smith   x = (PetscReal) n;
2863b271bb04SBarry Smith   y = (prev - rnorm)/prev;
2864b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2865b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2866b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2867b271bb04SBarry Smith   }
2868b271bb04SBarry Smith 
2869b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
2870b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2871b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2872b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
2873b271bb04SBarry Smith   x = (PetscReal) n;
2874b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
2875b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
2876b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2877b271bb04SBarry Smith   }
2878b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2879b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2880b271bb04SBarry Smith   }
2881b271bb04SBarry Smith   prev = rnorm;
2882b271bb04SBarry Smith   PetscFunctionReturn(0);
2883b271bb04SBarry Smith }
2884b271bb04SBarry Smith 
2885b271bb04SBarry Smith #undef __FUNCT__
2886b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
28877087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2888b271bb04SBarry Smith {
2889b271bb04SBarry Smith   PetscErrorCode ierr;
2890b271bb04SBarry Smith 
2891b271bb04SBarry Smith   PetscFunctionBegin;
2892b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2893b271bb04SBarry Smith   PetscFunctionReturn(0);
2894b271bb04SBarry Smith }
2895b271bb04SBarry Smith 
2896b271bb04SBarry Smith #undef __FUNCT__
2897b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
28986bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG *draw)
2899b271bb04SBarry Smith {
2900b271bb04SBarry Smith   PetscErrorCode ierr;
2901b271bb04SBarry Smith 
2902b271bb04SBarry Smith   PetscFunctionBegin;
2903b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2904b271bb04SBarry Smith   PetscFunctionReturn(0);
2905b271bb04SBarry Smith }
2906b271bb04SBarry Smith 
29077a03ce2fSLisandro Dalcin #undef __FUNCT__
29087a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
2909228d79bcSJed Brown /*@
2910228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
2911228d79bcSJed Brown 
2912228d79bcSJed Brown    Collective on SNES
2913228d79bcSJed Brown 
2914228d79bcSJed Brown    Input Parameters:
2915228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
2916228d79bcSJed Brown .  iter - iteration number
2917228d79bcSJed Brown -  rnorm - relative norm of the residual
2918228d79bcSJed Brown 
2919228d79bcSJed Brown    Notes:
2920228d79bcSJed Brown    This routine is called by the SNES implementations.
2921228d79bcSJed Brown    It does not typically need to be called by the user.
2922228d79bcSJed Brown 
2923228d79bcSJed Brown    Level: developer
2924228d79bcSJed Brown 
2925228d79bcSJed Brown .seealso: SNESMonitorSet()
2926228d79bcSJed Brown @*/
29277a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
29287a03ce2fSLisandro Dalcin {
29297a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
29307a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
29317a03ce2fSLisandro Dalcin 
29327a03ce2fSLisandro Dalcin   PetscFunctionBegin;
29337a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
29347a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
29357a03ce2fSLisandro Dalcin   }
29367a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
29377a03ce2fSLisandro Dalcin }
29387a03ce2fSLisandro Dalcin 
29399b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
29409b94acceSBarry Smith 
29414a2ae208SSatish Balay #undef __FUNCT__
2942a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
29439b94acceSBarry Smith /*@C
2944a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
29459b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
29469b94acceSBarry Smith    progress.
29479b94acceSBarry Smith 
29483f9fe445SBarry Smith    Logically Collective on SNES
2949fee21e36SBarry Smith 
2950c7afd0dbSLois Curfman McInnes    Input Parameters:
2951c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2952c7afd0dbSLois Curfman McInnes .  func - monitoring routine
2953b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
2954e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
2955b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
2956b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
29579b94acceSBarry Smith 
2958c7afd0dbSLois Curfman McInnes    Calling sequence of func:
2959a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
2960c7afd0dbSLois Curfman McInnes 
2961c7afd0dbSLois Curfman McInnes +    snes - the SNES context
2962c7afd0dbSLois Curfman McInnes .    its - iteration number
2963c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
296440a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
29659b94acceSBarry Smith 
29669665c990SLois Curfman McInnes    Options Database Keys:
2967a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
2968a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
2969a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
2970cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
2971c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
2972a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
2973c7afd0dbSLois Curfman McInnes                             does not cancel those set via
2974c7afd0dbSLois Curfman McInnes                             the options database.
29759665c990SLois Curfman McInnes 
2976639f9d9dSBarry Smith    Notes:
29776bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
2978a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
29796bc08f3fSLois Curfman McInnes    order in which they were set.
2980639f9d9dSBarry Smith 
2981025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
2982025f1a04SBarry Smith 
298336851e7fSLois Curfman McInnes    Level: intermediate
298436851e7fSLois Curfman McInnes 
29859b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
29869b94acceSBarry Smith 
2987a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
29889b94acceSBarry Smith @*/
2989c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
29909b94acceSBarry Smith {
2991b90d0a6eSBarry Smith   PetscInt       i;
2992649052a6SBarry Smith   PetscErrorCode ierr;
2993b90d0a6eSBarry Smith 
29943a40ed3dSBarry Smith   PetscFunctionBegin;
29950700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
299617186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
2997b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
2998649052a6SBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
2999649052a6SBarry Smith       if (monitordestroy) {
3000c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
3001649052a6SBarry Smith       }
3002b90d0a6eSBarry Smith       PetscFunctionReturn(0);
3003b90d0a6eSBarry Smith     }
3004b90d0a6eSBarry Smith   }
3005b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
3006b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
3007639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
30083a40ed3dSBarry Smith   PetscFunctionReturn(0);
30099b94acceSBarry Smith }
30109b94acceSBarry Smith 
30114a2ae208SSatish Balay #undef __FUNCT__
3012a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
30135cd90555SBarry Smith /*@C
3014a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
30155cd90555SBarry Smith 
30163f9fe445SBarry Smith    Logically Collective on SNES
3017c7afd0dbSLois Curfman McInnes 
30185cd90555SBarry Smith    Input Parameters:
30195cd90555SBarry Smith .  snes - the SNES context
30205cd90555SBarry Smith 
30211a480d89SAdministrator    Options Database Key:
3022a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
3023a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
3024c7afd0dbSLois Curfman McInnes     set via the options database
30255cd90555SBarry Smith 
30265cd90555SBarry Smith    Notes:
30275cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
30285cd90555SBarry Smith 
302936851e7fSLois Curfman McInnes    Level: intermediate
303036851e7fSLois Curfman McInnes 
30315cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
30325cd90555SBarry Smith 
3033a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
30345cd90555SBarry Smith @*/
30357087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
30365cd90555SBarry Smith {
3037d952e501SBarry Smith   PetscErrorCode ierr;
3038d952e501SBarry Smith   PetscInt       i;
3039d952e501SBarry Smith 
30405cd90555SBarry Smith   PetscFunctionBegin;
30410700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3042d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
3043d952e501SBarry Smith     if (snes->monitordestroy[i]) {
30443c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
3045d952e501SBarry Smith     }
3046d952e501SBarry Smith   }
30475cd90555SBarry Smith   snes->numbermonitors = 0;
30485cd90555SBarry Smith   PetscFunctionReturn(0);
30495cd90555SBarry Smith }
30505cd90555SBarry Smith 
30514a2ae208SSatish Balay #undef __FUNCT__
30524a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
30539b94acceSBarry Smith /*@C
30549b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
30559b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
30569b94acceSBarry Smith 
30573f9fe445SBarry Smith    Logically Collective on SNES
3058fee21e36SBarry Smith 
3059c7afd0dbSLois Curfman McInnes    Input Parameters:
3060c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3061c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
30627f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
30637f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
30649b94acceSBarry Smith 
3065c7afd0dbSLois Curfman McInnes    Calling sequence of func:
306606ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
3067c7afd0dbSLois Curfman McInnes 
3068c7afd0dbSLois Curfman McInnes +    snes - the SNES context
306906ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
3070c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
3071184914b5SBarry Smith .    reason - reason for convergence/divergence
3072c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
30734b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
30744b27c08aSLois Curfman McInnes -    f - 2-norm of function
30759b94acceSBarry Smith 
307636851e7fSLois Curfman McInnes    Level: advanced
307736851e7fSLois Curfman McInnes 
30789b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
30799b94acceSBarry Smith 
308085385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
30819b94acceSBarry Smith @*/
30827087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
30839b94acceSBarry Smith {
30847f7931b9SBarry Smith   PetscErrorCode ierr;
30857f7931b9SBarry Smith 
30863a40ed3dSBarry Smith   PetscFunctionBegin;
30870700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
308885385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
30897f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
30907f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
30917f7931b9SBarry Smith   }
309285385478SLisandro Dalcin   snes->ops->converged        = func;
30937f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
309485385478SLisandro Dalcin   snes->cnvP                  = cctx;
30953a40ed3dSBarry Smith   PetscFunctionReturn(0);
30969b94acceSBarry Smith }
30979b94acceSBarry Smith 
30984a2ae208SSatish Balay #undef __FUNCT__
30994a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
310052baeb72SSatish Balay /*@
3101184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
3102184914b5SBarry Smith 
3103184914b5SBarry Smith    Not Collective
3104184914b5SBarry Smith 
3105184914b5SBarry Smith    Input Parameter:
3106184914b5SBarry Smith .  snes - the SNES context
3107184914b5SBarry Smith 
3108184914b5SBarry Smith    Output Parameter:
31094d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
3110184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
3111184914b5SBarry Smith 
3112184914b5SBarry Smith    Level: intermediate
3113184914b5SBarry Smith 
3114184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
3115184914b5SBarry Smith 
3116184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
3117184914b5SBarry Smith 
311885385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
3119184914b5SBarry Smith @*/
31207087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
3121184914b5SBarry Smith {
3122184914b5SBarry Smith   PetscFunctionBegin;
31230700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
31244482741eSBarry Smith   PetscValidPointer(reason,2);
3125184914b5SBarry Smith   *reason = snes->reason;
3126184914b5SBarry Smith   PetscFunctionReturn(0);
3127184914b5SBarry Smith }
3128184914b5SBarry Smith 
31294a2ae208SSatish Balay #undef __FUNCT__
31304a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
3131c9005455SLois Curfman McInnes /*@
3132c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
3133c9005455SLois Curfman McInnes 
31343f9fe445SBarry Smith    Logically Collective on SNES
3135fee21e36SBarry Smith 
3136c7afd0dbSLois Curfman McInnes    Input Parameters:
3137c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
31388c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
3139cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
3140758f92a0SBarry Smith .  na  - size of a and its
314164731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
3142758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
3143c7afd0dbSLois Curfman McInnes 
3144308dcc3eSBarry Smith    Notes:
3145308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
3146308dcc3eSBarry Smith    default array of length 10000 is allocated.
3147308dcc3eSBarry Smith 
3148c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
3149c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
3150c9005455SLois Curfman McInnes    during the section of code that is being timed.
3151c9005455SLois Curfman McInnes 
315236851e7fSLois Curfman McInnes    Level: intermediate
315336851e7fSLois Curfman McInnes 
3154c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
3155758f92a0SBarry Smith 
315608405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
3157758f92a0SBarry Smith 
3158c9005455SLois Curfman McInnes @*/
31597087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
3160c9005455SLois Curfman McInnes {
3161308dcc3eSBarry Smith   PetscErrorCode ierr;
3162308dcc3eSBarry Smith 
31633a40ed3dSBarry Smith   PetscFunctionBegin;
31640700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
31654482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
3166a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
3167308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
3168308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
3169308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
3170308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
3171308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
3172308dcc3eSBarry Smith   }
3173c9005455SLois Curfman McInnes   snes->conv_hist       = a;
3174758f92a0SBarry Smith   snes->conv_hist_its   = its;
3175758f92a0SBarry Smith   snes->conv_hist_max   = na;
3176a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
3177758f92a0SBarry Smith   snes->conv_hist_reset = reset;
3178758f92a0SBarry Smith   PetscFunctionReturn(0);
3179758f92a0SBarry Smith }
3180758f92a0SBarry Smith 
3181308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3182c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
3183c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
3184308dcc3eSBarry Smith EXTERN_C_BEGIN
3185308dcc3eSBarry Smith #undef __FUNCT__
3186308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
3187308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
3188308dcc3eSBarry Smith {
3189308dcc3eSBarry Smith   mxArray        *mat;
3190308dcc3eSBarry Smith   PetscInt       i;
3191308dcc3eSBarry Smith   PetscReal      *ar;
3192308dcc3eSBarry Smith 
3193308dcc3eSBarry Smith   PetscFunctionBegin;
3194308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
3195308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
3196308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
3197308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
3198308dcc3eSBarry Smith   }
3199308dcc3eSBarry Smith   PetscFunctionReturn(mat);
3200308dcc3eSBarry Smith }
3201308dcc3eSBarry Smith EXTERN_C_END
3202308dcc3eSBarry Smith #endif
3203308dcc3eSBarry Smith 
3204308dcc3eSBarry Smith 
32054a2ae208SSatish Balay #undef __FUNCT__
32064a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
32070c4c9dddSBarry Smith /*@C
3208758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
3209758f92a0SBarry Smith 
32103f9fe445SBarry Smith    Not Collective
3211758f92a0SBarry Smith 
3212758f92a0SBarry Smith    Input Parameter:
3213758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
3214758f92a0SBarry Smith 
3215758f92a0SBarry Smith    Output Parameters:
3216758f92a0SBarry Smith .  a   - array to hold history
3217758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
3218758f92a0SBarry Smith          negative if not converged) for each solve.
3219758f92a0SBarry Smith -  na  - size of a and its
3220758f92a0SBarry Smith 
3221758f92a0SBarry Smith    Notes:
3222758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
3223758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
3224758f92a0SBarry Smith 
3225758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
3226758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
3227758f92a0SBarry Smith    during the section of code that is being timed.
3228758f92a0SBarry Smith 
3229758f92a0SBarry Smith    Level: intermediate
3230758f92a0SBarry Smith 
3231758f92a0SBarry Smith .keywords: SNES, get, convergence, history
3232758f92a0SBarry Smith 
3233758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
3234758f92a0SBarry Smith 
3235758f92a0SBarry Smith @*/
32367087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3237758f92a0SBarry Smith {
3238758f92a0SBarry Smith   PetscFunctionBegin;
32390700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3240758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
3241758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
3242758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
32433a40ed3dSBarry Smith   PetscFunctionReturn(0);
3244c9005455SLois Curfman McInnes }
3245c9005455SLois Curfman McInnes 
3246e74ef692SMatthew Knepley #undef __FUNCT__
3247e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
3248ac226902SBarry Smith /*@C
324976b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
3250eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
32517e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
325276b2cf59SMatthew Knepley 
32533f9fe445SBarry Smith   Logically Collective on SNES
325476b2cf59SMatthew Knepley 
325576b2cf59SMatthew Knepley   Input Parameters:
325676b2cf59SMatthew Knepley . snes - The nonlinear solver context
325776b2cf59SMatthew Knepley . func - The function
325876b2cf59SMatthew Knepley 
325976b2cf59SMatthew Knepley   Calling sequence of func:
3260b5d30489SBarry Smith . func (SNES snes, PetscInt step);
326176b2cf59SMatthew Knepley 
326276b2cf59SMatthew Knepley . step - The current step of the iteration
326376b2cf59SMatthew Knepley 
3264fe97e370SBarry Smith   Level: advanced
3265fe97e370SBarry Smith 
3266fe97e370SBarry 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()
3267fe97e370SBarry Smith         This is not used by most users.
326876b2cf59SMatthew Knepley 
326976b2cf59SMatthew Knepley .keywords: SNES, update
3270b5d30489SBarry Smith 
327185385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
327276b2cf59SMatthew Knepley @*/
32737087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
327476b2cf59SMatthew Knepley {
327576b2cf59SMatthew Knepley   PetscFunctionBegin;
32760700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
3277e7788613SBarry Smith   snes->ops->update = func;
327876b2cf59SMatthew Knepley   PetscFunctionReturn(0);
327976b2cf59SMatthew Knepley }
328076b2cf59SMatthew Knepley 
3281e74ef692SMatthew Knepley #undef __FUNCT__
3282e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
328376b2cf59SMatthew Knepley /*@
328476b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
328576b2cf59SMatthew Knepley 
328676b2cf59SMatthew Knepley   Not collective
328776b2cf59SMatthew Knepley 
328876b2cf59SMatthew Knepley   Input Parameters:
328976b2cf59SMatthew Knepley . snes - The nonlinear solver context
329076b2cf59SMatthew Knepley . step - The current step of the iteration
329176b2cf59SMatthew Knepley 
3292205452f4SMatthew Knepley   Level: intermediate
3293205452f4SMatthew Knepley 
329476b2cf59SMatthew Knepley .keywords: SNES, update
3295a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
329676b2cf59SMatthew Knepley @*/
32977087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
329876b2cf59SMatthew Knepley {
329976b2cf59SMatthew Knepley   PetscFunctionBegin;
330076b2cf59SMatthew Knepley   PetscFunctionReturn(0);
330176b2cf59SMatthew Knepley }
330276b2cf59SMatthew Knepley 
33034a2ae208SSatish Balay #undef __FUNCT__
33044a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
33059b94acceSBarry Smith /*
33069b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
33079b94acceSBarry Smith    positive parameter delta.
33089b94acceSBarry Smith 
33099b94acceSBarry Smith     Input Parameters:
3310c7afd0dbSLois Curfman McInnes +   snes - the SNES context
33119b94acceSBarry Smith .   y - approximate solution of linear system
33129b94acceSBarry Smith .   fnorm - 2-norm of current function
3313c7afd0dbSLois Curfman McInnes -   delta - trust region size
33149b94acceSBarry Smith 
33159b94acceSBarry Smith     Output Parameters:
3316c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
33179b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
33189b94acceSBarry Smith     region, and exceeds zero otherwise.
3319c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
33209b94acceSBarry Smith 
33219b94acceSBarry Smith     Note:
33224b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
33239b94acceSBarry Smith     is set to be the maximum allowable step size.
33249b94acceSBarry Smith 
33259b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
33269b94acceSBarry Smith */
3327dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
33289b94acceSBarry Smith {
3329064f8208SBarry Smith   PetscReal      nrm;
3330ea709b57SSatish Balay   PetscScalar    cnorm;
3331dfbe8321SBarry Smith   PetscErrorCode ierr;
33323a40ed3dSBarry Smith 
33333a40ed3dSBarry Smith   PetscFunctionBegin;
33340700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
33350700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3336c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
3337184914b5SBarry Smith 
3338064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
3339064f8208SBarry Smith   if (nrm > *delta) {
3340064f8208SBarry Smith      nrm = *delta/nrm;
3341064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
3342064f8208SBarry Smith      cnorm = nrm;
33432dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
33449b94acceSBarry Smith      *ynorm = *delta;
33459b94acceSBarry Smith   } else {
33469b94acceSBarry Smith      *gpnorm = 0.0;
3347064f8208SBarry Smith      *ynorm = nrm;
33489b94acceSBarry Smith   }
33493a40ed3dSBarry Smith   PetscFunctionReturn(0);
33509b94acceSBarry Smith }
33519b94acceSBarry Smith 
33524a2ae208SSatish Balay #undef __FUNCT__
33534a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
33546ce558aeSBarry Smith /*@C
3355f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
3356f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
33579b94acceSBarry Smith 
3358c7afd0dbSLois Curfman McInnes    Collective on SNES
3359c7afd0dbSLois Curfman McInnes 
3360b2002411SLois Curfman McInnes    Input Parameters:
3361c7afd0dbSLois Curfman McInnes +  snes - the SNES context
33623cebf274SJed Brown .  b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero.
336385385478SLisandro Dalcin -  x - the solution vector.
33649b94acceSBarry Smith 
3365b2002411SLois Curfman McInnes    Notes:
33668ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
33678ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
33688ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
33698ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
33708ddd3da0SLois Curfman McInnes 
337136851e7fSLois Curfman McInnes    Level: beginner
337236851e7fSLois Curfman McInnes 
33739b94acceSBarry Smith .keywords: SNES, nonlinear, solve
33749b94acceSBarry Smith 
3375c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
33769b94acceSBarry Smith @*/
33777087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
33789b94acceSBarry Smith {
3379dfbe8321SBarry Smith   PetscErrorCode ierr;
3380ace3abfcSBarry Smith   PetscBool      flg;
3381eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
3382eabae89aSBarry Smith   PetscViewer    viewer;
3383efd51863SBarry Smith   PetscInt       grid;
3384a69afd8bSBarry Smith   Vec            xcreated = PETSC_NULL;
3385caa4e7f2SJed Brown   DM             dm;
3386052efed2SBarry Smith 
33873a40ed3dSBarry Smith   PetscFunctionBegin;
33880700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3389a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3390a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
33910700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
339285385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
339385385478SLisandro Dalcin 
3394caa4e7f2SJed Brown   if (!x) {
3395caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3396caa4e7f2SJed Brown     ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr);
3397a69afd8bSBarry Smith     x    = xcreated;
3398a69afd8bSBarry Smith   }
3399a69afd8bSBarry Smith 
3400a8248277SBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);}
3401efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
3402efd51863SBarry Smith 
340385385478SLisandro Dalcin     /* set solution vector */
3404efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
34056bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
340685385478SLisandro Dalcin     snes->vec_sol = x;
3407caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3408caa4e7f2SJed Brown 
3409caa4e7f2SJed Brown     /* set affine vector if provided */
341085385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
34116bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
341285385478SLisandro Dalcin     snes->vec_rhs = b;
341385385478SLisandro Dalcin 
341470e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
34153f149594SLisandro Dalcin 
34167eee914bSBarry Smith     if (!grid) {
34177eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
3418d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
3419dd568438SSatish Balay       } else if (snes->dm) {
3420dd568438SSatish Balay         PetscBool ig;
3421dd568438SSatish Balay         ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr);
3422dd568438SSatish Balay         if (ig) {
34237eee914bSBarry Smith           ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr);
34247eee914bSBarry Smith         }
3425d25893d9SBarry Smith       }
3426dd568438SSatish Balay     }
3427d25893d9SBarry Smith 
3428abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
342950ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
3430d5e45103SBarry Smith 
34313f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
34324936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
343385385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
34344936397dSBarry Smith     if (snes->domainerror){
34354936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
34364936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
34374936397dSBarry Smith     }
343817186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
34393f149594SLisandro Dalcin 
34407adad957SLisandro Dalcin     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
3441eabae89aSBarry Smith     if (flg && !PetscPreLoadingOn) {
34427adad957SLisandro Dalcin       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
3443eabae89aSBarry Smith       ierr = SNESView(snes,viewer);CHKERRQ(ierr);
34446bf464f9SBarry Smith       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3445eabae89aSBarry Smith     }
3446eabae89aSBarry Smith 
344790d69ab7SBarry Smith     flg  = PETSC_FALSE;
3448acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
3449da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
34505968eb51SBarry Smith     if (snes->printreason) {
3451a8248277SBarry Smith       ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
34525968eb51SBarry Smith       if (snes->reason > 0) {
3453c7e7b494SJed 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);
34545968eb51SBarry Smith       } else {
3455c7e7b494SJed 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);
34565968eb51SBarry Smith       }
3457a8248277SBarry Smith       ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
34585968eb51SBarry Smith     }
34595968eb51SBarry Smith 
34608501fc72SJed Brown     flg = PETSC_FALSE;
34618501fc72SJed Brown     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
34628501fc72SJed Brown     if (flg) {
34638501fc72SJed Brown       PetscViewer viewer;
34648501fc72SJed Brown       ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
34658501fc72SJed Brown       ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr);
34668501fc72SJed Brown       ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr);
34678501fc72SJed Brown       ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr);
34688501fc72SJed Brown       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
34698501fc72SJed Brown     }
34708501fc72SJed Brown 
3471e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
3472efd51863SBarry Smith     if (grid <  snes->gridsequence) {
3473efd51863SBarry Smith       DM  fine;
3474efd51863SBarry Smith       Vec xnew;
3475efd51863SBarry Smith       Mat interp;
3476efd51863SBarry Smith 
3477efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
3478c5c77316SJed Brown       if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
3479e727c939SJed Brown       ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
3480efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
3481efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
3482c833c3b5SJed Brown       ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr);
3483efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
3484efd51863SBarry Smith       x    = xnew;
3485efd51863SBarry Smith 
3486efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
3487efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
3488efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
3489a8248277SBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);
3490efd51863SBarry Smith     }
3491efd51863SBarry Smith   }
3492a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
34933a40ed3dSBarry Smith   PetscFunctionReturn(0);
34949b94acceSBarry Smith }
34959b94acceSBarry Smith 
34969b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
34979b94acceSBarry Smith 
34984a2ae208SSatish Balay #undef __FUNCT__
34994a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
350082bf6240SBarry Smith /*@C
35014b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
35029b94acceSBarry Smith 
3503fee21e36SBarry Smith    Collective on SNES
3504fee21e36SBarry Smith 
3505c7afd0dbSLois Curfman McInnes    Input Parameters:
3506c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3507454a90a3SBarry Smith -  type - a known method
3508c7afd0dbSLois Curfman McInnes 
3509c7afd0dbSLois Curfman McInnes    Options Database Key:
3510454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
3511c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
3512ae12b187SLois Curfman McInnes 
35139b94acceSBarry Smith    Notes:
3514e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
35154b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
3516c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
35174b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
3518c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
35199b94acceSBarry Smith 
3520ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
3521ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
3522ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
3523ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
3524ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
3525ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
3526ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
3527ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
3528ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
3529b0a32e0cSBarry Smith   appropriate method.
353036851e7fSLois Curfman McInnes 
353136851e7fSLois Curfman McInnes   Level: intermediate
3532a703fe33SLois Curfman McInnes 
3533454a90a3SBarry Smith .keywords: SNES, set, type
3534435da068SBarry Smith 
3535435da068SBarry Smith .seealso: SNESType, SNESCreate()
3536435da068SBarry Smith 
35379b94acceSBarry Smith @*/
35387087cfbeSBarry Smith PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
35399b94acceSBarry Smith {
3540dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
3541ace3abfcSBarry Smith   PetscBool      match;
35423a40ed3dSBarry Smith 
35433a40ed3dSBarry Smith   PetscFunctionBegin;
35440700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35454482741eSBarry Smith   PetscValidCharPointer(type,2);
354682bf6240SBarry Smith 
3547251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
35480f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
354992ff6ae8SBarry Smith 
35504b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
3551e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
355275396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
3553b5c23020SJed Brown   if (snes->ops->destroy) {
3554b5c23020SJed Brown     ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
3555b5c23020SJed Brown     snes->ops->destroy = PETSC_NULL;
3556b5c23020SJed Brown   }
355775396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
355875396ef9SLisandro Dalcin   snes->ops->setup          = 0;
355975396ef9SLisandro Dalcin   snes->ops->solve          = 0;
356075396ef9SLisandro Dalcin   snes->ops->view           = 0;
356175396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
356275396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
356375396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
356475396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
3565454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
356603bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
35679fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
35689fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
35699fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
35709fb22e1aSBarry Smith   }
35719fb22e1aSBarry Smith #endif
35723a40ed3dSBarry Smith   PetscFunctionReturn(0);
35739b94acceSBarry Smith }
35749b94acceSBarry Smith 
3575a847f771SSatish Balay 
35769b94acceSBarry Smith /* --------------------------------------------------------------------- */
35774a2ae208SSatish Balay #undef __FUNCT__
35784a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
357952baeb72SSatish Balay /*@
35809b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
3581f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
35829b94acceSBarry Smith 
3583fee21e36SBarry Smith    Not Collective
3584fee21e36SBarry Smith 
358536851e7fSLois Curfman McInnes    Level: advanced
358636851e7fSLois Curfman McInnes 
35879b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
35889b94acceSBarry Smith 
35899b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
35909b94acceSBarry Smith @*/
35917087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
35929b94acceSBarry Smith {
3593dfbe8321SBarry Smith   PetscErrorCode ierr;
359482bf6240SBarry Smith 
35953a40ed3dSBarry Smith   PetscFunctionBegin;
35961441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
35974c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
35983a40ed3dSBarry Smith   PetscFunctionReturn(0);
35999b94acceSBarry Smith }
36009b94acceSBarry Smith 
36014a2ae208SSatish Balay #undef __FUNCT__
36024a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
36039b94acceSBarry Smith /*@C
36049a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
36059b94acceSBarry Smith 
3606c7afd0dbSLois Curfman McInnes    Not Collective
3607c7afd0dbSLois Curfman McInnes 
36089b94acceSBarry Smith    Input Parameter:
36094b0e389bSBarry Smith .  snes - nonlinear solver context
36109b94acceSBarry Smith 
36119b94acceSBarry Smith    Output Parameter:
36123a7fca6bSBarry Smith .  type - SNES method (a character string)
36139b94acceSBarry Smith 
361436851e7fSLois Curfman McInnes    Level: intermediate
361536851e7fSLois Curfman McInnes 
3616454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
36179b94acceSBarry Smith @*/
36187087cfbeSBarry Smith PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
36199b94acceSBarry Smith {
36203a40ed3dSBarry Smith   PetscFunctionBegin;
36210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36224482741eSBarry Smith   PetscValidPointer(type,2);
36237adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
36243a40ed3dSBarry Smith   PetscFunctionReturn(0);
36259b94acceSBarry Smith }
36269b94acceSBarry Smith 
36274a2ae208SSatish Balay #undef __FUNCT__
36284a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
362952baeb72SSatish Balay /*@
36309b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
3631c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
36329b94acceSBarry Smith 
3633c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3634c7afd0dbSLois Curfman McInnes 
36359b94acceSBarry Smith    Input Parameter:
36369b94acceSBarry Smith .  snes - the SNES context
36379b94acceSBarry Smith 
36389b94acceSBarry Smith    Output Parameter:
36399b94acceSBarry Smith .  x - the solution
36409b94acceSBarry Smith 
364170e92668SMatthew Knepley    Level: intermediate
364236851e7fSLois Curfman McInnes 
36439b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
36449b94acceSBarry Smith 
364585385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
36469b94acceSBarry Smith @*/
36477087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
36489b94acceSBarry Smith {
36493a40ed3dSBarry Smith   PetscFunctionBegin;
36500700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36514482741eSBarry Smith   PetscValidPointer(x,2);
365285385478SLisandro Dalcin   *x = snes->vec_sol;
365370e92668SMatthew Knepley   PetscFunctionReturn(0);
365470e92668SMatthew Knepley }
365570e92668SMatthew Knepley 
365670e92668SMatthew Knepley #undef __FUNCT__
36574a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
365852baeb72SSatish Balay /*@
36599b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
36609b94acceSBarry Smith    stored.
36619b94acceSBarry Smith 
3662c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3663c7afd0dbSLois Curfman McInnes 
36649b94acceSBarry Smith    Input Parameter:
36659b94acceSBarry Smith .  snes - the SNES context
36669b94acceSBarry Smith 
36679b94acceSBarry Smith    Output Parameter:
36689b94acceSBarry Smith .  x - the solution update
36699b94acceSBarry Smith 
367036851e7fSLois Curfman McInnes    Level: advanced
367136851e7fSLois Curfman McInnes 
36729b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
36739b94acceSBarry Smith 
367485385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
36759b94acceSBarry Smith @*/
36767087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
36779b94acceSBarry Smith {
36783a40ed3dSBarry Smith   PetscFunctionBegin;
36790700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36804482741eSBarry Smith   PetscValidPointer(x,2);
368185385478SLisandro Dalcin   *x = snes->vec_sol_update;
36823a40ed3dSBarry Smith   PetscFunctionReturn(0);
36839b94acceSBarry Smith }
36849b94acceSBarry Smith 
36854a2ae208SSatish Balay #undef __FUNCT__
36864a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
36879b94acceSBarry Smith /*@C
36883638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
36899b94acceSBarry Smith 
3690a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
3691c7afd0dbSLois Curfman McInnes 
36929b94acceSBarry Smith    Input Parameter:
36939b94acceSBarry Smith .  snes - the SNES context
36949b94acceSBarry Smith 
36959b94acceSBarry Smith    Output Parameter:
36967bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
369770e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
369870e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
36999b94acceSBarry Smith 
370036851e7fSLois Curfman McInnes    Level: advanced
370136851e7fSLois Curfman McInnes 
3702a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
37039b94acceSBarry Smith 
37044b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
37059b94acceSBarry Smith @*/
37067087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
37079b94acceSBarry Smith {
3708a63bb30eSJed Brown   PetscErrorCode ierr;
37096cab3a1bSJed Brown   DM             dm;
3710a63bb30eSJed Brown 
37113a40ed3dSBarry Smith   PetscFunctionBegin;
37120700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3713a63bb30eSJed Brown   if (r) {
3714a63bb30eSJed Brown     if (!snes->vec_func) {
3715a63bb30eSJed Brown       if (snes->vec_rhs) {
3716a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
3717a63bb30eSJed Brown       } else if (snes->vec_sol) {
3718a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
3719a63bb30eSJed Brown       } else if (snes->dm) {
3720a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
3721a63bb30eSJed Brown       }
3722a63bb30eSJed Brown     }
3723a63bb30eSJed Brown     *r = snes->vec_func;
3724a63bb30eSJed Brown   }
37256cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
37266cab3a1bSJed Brown   ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr);
37273a40ed3dSBarry Smith   PetscFunctionReturn(0);
37289b94acceSBarry Smith }
37299b94acceSBarry Smith 
3730c79ef259SPeter Brune /*@C
3731c79ef259SPeter Brune    SNESGetGS - Returns the GS function and context.
3732c79ef259SPeter Brune 
3733c79ef259SPeter Brune    Input Parameter:
3734c79ef259SPeter Brune .  snes - the SNES context
3735c79ef259SPeter Brune 
3736c79ef259SPeter Brune    Output Parameter:
3737c79ef259SPeter Brune +  gsfunc - the function (or PETSC_NULL)
3738c79ef259SPeter Brune -  ctx    - the function context (or PETSC_NULL)
3739c79ef259SPeter Brune 
3740c79ef259SPeter Brune    Level: advanced
3741c79ef259SPeter Brune 
3742c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
3743c79ef259SPeter Brune 
3744c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction()
3745c79ef259SPeter Brune @*/
3746c79ef259SPeter Brune 
37474a2ae208SSatish Balay #undef __FUNCT__
3748646217ecSPeter Brune #define __FUNCT__ "SNESGetGS"
3749646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx)
3750646217ecSPeter Brune {
37516cab3a1bSJed Brown   PetscErrorCode ierr;
37526cab3a1bSJed Brown   DM             dm;
37536cab3a1bSJed Brown 
3754646217ecSPeter Brune   PetscFunctionBegin;
3755646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37566cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
37576cab3a1bSJed Brown   ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr);
3758646217ecSPeter Brune   PetscFunctionReturn(0);
3759646217ecSPeter Brune }
3760646217ecSPeter Brune 
37614a2ae208SSatish Balay #undef __FUNCT__
37624a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
37633c7409f5SSatish Balay /*@C
37643c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
3765d850072dSLois Curfman McInnes    SNES options in the database.
37663c7409f5SSatish Balay 
37673f9fe445SBarry Smith    Logically Collective on SNES
3768fee21e36SBarry Smith 
3769c7afd0dbSLois Curfman McInnes    Input Parameter:
3770c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3771c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3772c7afd0dbSLois Curfman McInnes 
3773d850072dSLois Curfman McInnes    Notes:
3774a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3775c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3776d850072dSLois Curfman McInnes 
377736851e7fSLois Curfman McInnes    Level: advanced
377836851e7fSLois Curfman McInnes 
37793c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
3780a86d99e1SLois Curfman McInnes 
3781a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
37823c7409f5SSatish Balay @*/
37837087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
37843c7409f5SSatish Balay {
3785dfbe8321SBarry Smith   PetscErrorCode ierr;
37863c7409f5SSatish Balay 
37873a40ed3dSBarry Smith   PetscFunctionBegin;
37880700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3789639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
37901cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
379194b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
37923a40ed3dSBarry Smith   PetscFunctionReturn(0);
37933c7409f5SSatish Balay }
37943c7409f5SSatish Balay 
37954a2ae208SSatish Balay #undef __FUNCT__
37964a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
37973c7409f5SSatish Balay /*@C
3798f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
3799d850072dSLois Curfman McInnes    SNES options in the database.
38003c7409f5SSatish Balay 
38013f9fe445SBarry Smith    Logically Collective on SNES
3802fee21e36SBarry Smith 
3803c7afd0dbSLois Curfman McInnes    Input Parameters:
3804c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3805c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3806c7afd0dbSLois Curfman McInnes 
3807d850072dSLois Curfman McInnes    Notes:
3808a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3809c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3810d850072dSLois Curfman McInnes 
381136851e7fSLois Curfman McInnes    Level: advanced
381236851e7fSLois Curfman McInnes 
38133c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
3814a86d99e1SLois Curfman McInnes 
3815a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
38163c7409f5SSatish Balay @*/
38177087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
38183c7409f5SSatish Balay {
3819dfbe8321SBarry Smith   PetscErrorCode ierr;
38203c7409f5SSatish Balay 
38213a40ed3dSBarry Smith   PetscFunctionBegin;
38220700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3823639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
38241cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
382594b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
38263a40ed3dSBarry Smith   PetscFunctionReturn(0);
38273c7409f5SSatish Balay }
38283c7409f5SSatish Balay 
38294a2ae208SSatish Balay #undef __FUNCT__
38304a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
38319ab63eb5SSatish Balay /*@C
38323c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
38333c7409f5SSatish Balay    SNES options in the database.
38343c7409f5SSatish Balay 
3835c7afd0dbSLois Curfman McInnes    Not Collective
3836c7afd0dbSLois Curfman McInnes 
38373c7409f5SSatish Balay    Input Parameter:
38383c7409f5SSatish Balay .  snes - the SNES context
38393c7409f5SSatish Balay 
38403c7409f5SSatish Balay    Output Parameter:
38413c7409f5SSatish Balay .  prefix - pointer to the prefix string used
38423c7409f5SSatish Balay 
38434ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
38449ab63eb5SSatish Balay    sufficient length to hold the prefix.
38459ab63eb5SSatish Balay 
384636851e7fSLois Curfman McInnes    Level: advanced
384736851e7fSLois Curfman McInnes 
38483c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
3849a86d99e1SLois Curfman McInnes 
3850a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
38513c7409f5SSatish Balay @*/
38527087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
38533c7409f5SSatish Balay {
3854dfbe8321SBarry Smith   PetscErrorCode ierr;
38553c7409f5SSatish Balay 
38563a40ed3dSBarry Smith   PetscFunctionBegin;
38570700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3858639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
38593a40ed3dSBarry Smith   PetscFunctionReturn(0);
38603c7409f5SSatish Balay }
38613c7409f5SSatish Balay 
3862b2002411SLois Curfman McInnes 
38634a2ae208SSatish Balay #undef __FUNCT__
38644a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
38653cea93caSBarry Smith /*@C
38663cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
38673cea93caSBarry Smith 
38687f6c08e0SMatthew Knepley   Level: advanced
38693cea93caSBarry Smith @*/
38707087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
3871b2002411SLois Curfman McInnes {
3872e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
3873dfbe8321SBarry Smith   PetscErrorCode ierr;
3874b2002411SLois Curfman McInnes 
3875b2002411SLois Curfman McInnes   PetscFunctionBegin;
3876b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3877c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3878b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
3879b2002411SLois Curfman McInnes }
3880da9b6338SBarry Smith 
3881da9b6338SBarry Smith #undef __FUNCT__
3882da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
38837087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
3884da9b6338SBarry Smith {
3885dfbe8321SBarry Smith   PetscErrorCode ierr;
388677431f27SBarry Smith   PetscInt       N,i,j;
3887da9b6338SBarry Smith   Vec            u,uh,fh;
3888da9b6338SBarry Smith   PetscScalar    value;
3889da9b6338SBarry Smith   PetscReal      norm;
3890da9b6338SBarry Smith 
3891da9b6338SBarry Smith   PetscFunctionBegin;
3892da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
3893da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
3894da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
3895da9b6338SBarry Smith 
3896da9b6338SBarry Smith   /* currently only works for sequential */
3897da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
3898da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
3899da9b6338SBarry Smith   for (i=0; i<N; i++) {
3900da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
390177431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
3902da9b6338SBarry Smith     for (j=-10; j<11; j++) {
3903ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
3904da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
39053ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
3906da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
390777431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
3908da9b6338SBarry Smith       value = -value;
3909da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
3910da9b6338SBarry Smith     }
3911da9b6338SBarry Smith   }
39126bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
39136bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
3914da9b6338SBarry Smith   PetscFunctionReturn(0);
3915da9b6338SBarry Smith }
391671f87433Sdalcinl 
391771f87433Sdalcinl #undef __FUNCT__
3918fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
391971f87433Sdalcinl /*@
3920fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
392171f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
392271f87433Sdalcinl    Newton method.
392371f87433Sdalcinl 
39243f9fe445SBarry Smith    Logically Collective on SNES
392571f87433Sdalcinl 
392671f87433Sdalcinl    Input Parameters:
392771f87433Sdalcinl +  snes - SNES context
392871f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
392971f87433Sdalcinl 
393064ba62caSBarry Smith     Options Database:
393164ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
393264ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
393364ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
393464ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
393564ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
393664ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
393764ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
393864ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
393964ba62caSBarry Smith 
394071f87433Sdalcinl    Notes:
394171f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
394271f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
394371f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
394471f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
394571f87433Sdalcinl    solver.
394671f87433Sdalcinl 
394771f87433Sdalcinl    Level: advanced
394871f87433Sdalcinl 
394971f87433Sdalcinl    Reference:
395071f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
395171f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
395271f87433Sdalcinl 
395371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
395471f87433Sdalcinl 
3955fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
395671f87433Sdalcinl @*/
39577087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
395871f87433Sdalcinl {
395971f87433Sdalcinl   PetscFunctionBegin;
39600700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3961acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
396271f87433Sdalcinl   snes->ksp_ewconv = flag;
396371f87433Sdalcinl   PetscFunctionReturn(0);
396471f87433Sdalcinl }
396571f87433Sdalcinl 
396671f87433Sdalcinl #undef __FUNCT__
3967fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
396871f87433Sdalcinl /*@
3969fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
397071f87433Sdalcinl    for computing relative tolerance for linear solvers within an
397171f87433Sdalcinl    inexact Newton method.
397271f87433Sdalcinl 
397371f87433Sdalcinl    Not Collective
397471f87433Sdalcinl 
397571f87433Sdalcinl    Input Parameter:
397671f87433Sdalcinl .  snes - SNES context
397771f87433Sdalcinl 
397871f87433Sdalcinl    Output Parameter:
397971f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
398071f87433Sdalcinl 
398171f87433Sdalcinl    Notes:
398271f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
398371f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
398471f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
398571f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
398671f87433Sdalcinl    solver.
398771f87433Sdalcinl 
398871f87433Sdalcinl    Level: advanced
398971f87433Sdalcinl 
399071f87433Sdalcinl    Reference:
399171f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
399271f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
399371f87433Sdalcinl 
399471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
399571f87433Sdalcinl 
3996fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
399771f87433Sdalcinl @*/
39987087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
399971f87433Sdalcinl {
400071f87433Sdalcinl   PetscFunctionBegin;
40010700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
400271f87433Sdalcinl   PetscValidPointer(flag,2);
400371f87433Sdalcinl   *flag = snes->ksp_ewconv;
400471f87433Sdalcinl   PetscFunctionReturn(0);
400571f87433Sdalcinl }
400671f87433Sdalcinl 
400771f87433Sdalcinl #undef __FUNCT__
4008fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
400971f87433Sdalcinl /*@
4010fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
401171f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
401271f87433Sdalcinl    Newton method.
401371f87433Sdalcinl 
40143f9fe445SBarry Smith    Logically Collective on SNES
401571f87433Sdalcinl 
401671f87433Sdalcinl    Input Parameters:
401771f87433Sdalcinl +    snes - SNES context
401871f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
401971f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
402071f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
402171f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
402271f87433Sdalcinl              (0 <= gamma2 <= 1)
402371f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
402471f87433Sdalcinl .    alpha2 - power for safeguard
402571f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
402671f87433Sdalcinl 
402771f87433Sdalcinl    Note:
402871f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
402971f87433Sdalcinl 
403071f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
403171f87433Sdalcinl 
403271f87433Sdalcinl    Level: advanced
403371f87433Sdalcinl 
403471f87433Sdalcinl    Reference:
403571f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
403671f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
403771f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
403871f87433Sdalcinl 
403971f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
404071f87433Sdalcinl 
4041fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
404271f87433Sdalcinl @*/
40437087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
404471f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
404571f87433Sdalcinl {
4046fa9f3622SBarry Smith   SNESKSPEW *kctx;
404771f87433Sdalcinl   PetscFunctionBegin;
40480700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4049fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4050e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
4051c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
4052c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
4053c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
4054c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
4055c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
4056c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
4057c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
405871f87433Sdalcinl 
405971f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
406071f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
406171f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
406271f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
406371f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
406471f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
406571f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
406671f87433Sdalcinl 
406771f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
4068e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
406971f87433Sdalcinl   }
407071f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
4071e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
407271f87433Sdalcinl   }
407371f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
4074e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
407571f87433Sdalcinl   }
407671f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
4077e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
407871f87433Sdalcinl   }
407971f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
4080e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
408171f87433Sdalcinl   }
408271f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
4083e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
408471f87433Sdalcinl   }
408571f87433Sdalcinl   PetscFunctionReturn(0);
408671f87433Sdalcinl }
408771f87433Sdalcinl 
408871f87433Sdalcinl #undef __FUNCT__
4089fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
409071f87433Sdalcinl /*@
4091fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
409271f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
409371f87433Sdalcinl    Newton method.
409471f87433Sdalcinl 
409571f87433Sdalcinl    Not Collective
409671f87433Sdalcinl 
409771f87433Sdalcinl    Input Parameters:
409871f87433Sdalcinl      snes - SNES context
409971f87433Sdalcinl 
410071f87433Sdalcinl    Output Parameters:
410171f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
410271f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
410371f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
410471f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
410571f87433Sdalcinl              (0 <= gamma2 <= 1)
410671f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
410771f87433Sdalcinl .    alpha2 - power for safeguard
410871f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
410971f87433Sdalcinl 
411071f87433Sdalcinl    Level: advanced
411171f87433Sdalcinl 
411271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
411371f87433Sdalcinl 
4114fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
411571f87433Sdalcinl @*/
41167087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
411771f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
411871f87433Sdalcinl {
4119fa9f3622SBarry Smith   SNESKSPEW *kctx;
412071f87433Sdalcinl   PetscFunctionBegin;
41210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4122fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4123e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
412471f87433Sdalcinl   if(version)   *version   = kctx->version;
412571f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
412671f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
412771f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
412871f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
412971f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
413071f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
413171f87433Sdalcinl   PetscFunctionReturn(0);
413271f87433Sdalcinl }
413371f87433Sdalcinl 
413471f87433Sdalcinl #undef __FUNCT__
4135fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
4136fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
413771f87433Sdalcinl {
413871f87433Sdalcinl   PetscErrorCode ierr;
4139fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
414071f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
414171f87433Sdalcinl 
414271f87433Sdalcinl   PetscFunctionBegin;
4143e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
414471f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
414571f87433Sdalcinl     rtol = kctx->rtol_0;
414671f87433Sdalcinl   } else {
414771f87433Sdalcinl     if (kctx->version == 1) {
414871f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
414971f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
415071f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
415171f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
415271f87433Sdalcinl     } else if (kctx->version == 2) {
415371f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
415471f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
415571f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
415671f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
415771f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
415871f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
415971f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
416071f87433Sdalcinl       stol = PetscMax(rtol,stol);
416171f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
416271f87433Sdalcinl       /* safeguard: avoid oversolving */
416371f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
416471f87433Sdalcinl       stol = PetscMax(rtol,stol);
416571f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
4166e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
416771f87433Sdalcinl   }
416871f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
416971f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
417071f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
417171f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
417271f87433Sdalcinl   PetscFunctionReturn(0);
417371f87433Sdalcinl }
417471f87433Sdalcinl 
417571f87433Sdalcinl #undef __FUNCT__
4176fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
4177fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
417871f87433Sdalcinl {
417971f87433Sdalcinl   PetscErrorCode ierr;
4180fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
418171f87433Sdalcinl   PCSide         pcside;
418271f87433Sdalcinl   Vec            lres;
418371f87433Sdalcinl 
418471f87433Sdalcinl   PetscFunctionBegin;
4185e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
418671f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
418771f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
418871f87433Sdalcinl   if (kctx->version == 1) {
4189b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
419071f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
419171f87433Sdalcinl       /* KSP residual is true linear residual */
419271f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
419371f87433Sdalcinl     } else {
419471f87433Sdalcinl       /* KSP residual is preconditioned residual */
419571f87433Sdalcinl       /* compute true linear residual norm */
419671f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
419771f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
419871f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
419971f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
42006bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
420171f87433Sdalcinl     }
420271f87433Sdalcinl   }
420371f87433Sdalcinl   PetscFunctionReturn(0);
420471f87433Sdalcinl }
420571f87433Sdalcinl 
420671f87433Sdalcinl #undef __FUNCT__
420771f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
420871f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
420971f87433Sdalcinl {
421071f87433Sdalcinl   PetscErrorCode ierr;
421171f87433Sdalcinl 
421271f87433Sdalcinl   PetscFunctionBegin;
4213fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
421471f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
4215fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
421671f87433Sdalcinl   PetscFunctionReturn(0);
421771f87433Sdalcinl }
42186c699258SBarry Smith 
42196c699258SBarry Smith #undef __FUNCT__
42206c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
42216c699258SBarry Smith /*@
42226c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
42236c699258SBarry Smith 
42243f9fe445SBarry Smith    Logically Collective on SNES
42256c699258SBarry Smith 
42266c699258SBarry Smith    Input Parameters:
42276c699258SBarry Smith +  snes - the preconditioner context
42286c699258SBarry Smith -  dm - the dm
42296c699258SBarry Smith 
42306c699258SBarry Smith    Level: intermediate
42316c699258SBarry Smith 
42326c699258SBarry Smith 
42336c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
42346c699258SBarry Smith @*/
42357087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
42366c699258SBarry Smith {
42376c699258SBarry Smith   PetscErrorCode ierr;
4238345fed2cSBarry Smith   KSP            ksp;
42396cab3a1bSJed Brown   SNESDM         sdm;
42406c699258SBarry Smith 
42416c699258SBarry Smith   PetscFunctionBegin;
42420700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4243d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
42446cab3a1bSJed Brown   if (snes->dm) {               /* Move the SNESDM context over to the new DM unless the new DM already has one */
42456cab3a1bSJed Brown     PetscContainer oldcontainer,container;
42466cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr);
42476cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr);
42486cab3a1bSJed Brown     if (oldcontainer && !container) {
42496cab3a1bSJed Brown       ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr);
42506cab3a1bSJed Brown       ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr);
42516cab3a1bSJed Brown       if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */
42526cab3a1bSJed Brown         sdm->originaldm = dm;
42536cab3a1bSJed Brown       }
42546cab3a1bSJed Brown     }
42556bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
42566cab3a1bSJed Brown   }
42576c699258SBarry Smith   snes->dm = dm;
4258345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4259345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4260f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
42612c155ee1SBarry Smith   if (snes->pc) {
42622c155ee1SBarry Smith     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
42632c155ee1SBarry Smith   }
42646c699258SBarry Smith   PetscFunctionReturn(0);
42656c699258SBarry Smith }
42666c699258SBarry Smith 
42676c699258SBarry Smith #undef __FUNCT__
42686c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
42696c699258SBarry Smith /*@
42706c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
42716c699258SBarry Smith 
42723f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
42736c699258SBarry Smith 
42746c699258SBarry Smith    Input Parameter:
42756c699258SBarry Smith . snes - the preconditioner context
42766c699258SBarry Smith 
42776c699258SBarry Smith    Output Parameter:
42786c699258SBarry Smith .  dm - the dm
42796c699258SBarry Smith 
42806c699258SBarry Smith    Level: intermediate
42816c699258SBarry Smith 
42826c699258SBarry Smith 
42836c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
42846c699258SBarry Smith @*/
42857087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
42866c699258SBarry Smith {
42876cab3a1bSJed Brown   PetscErrorCode ierr;
42886cab3a1bSJed Brown 
42896c699258SBarry Smith   PetscFunctionBegin;
42900700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
42916cab3a1bSJed Brown   if (!snes->dm) {
42926cab3a1bSJed Brown     ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr);
42936cab3a1bSJed Brown   }
42946c699258SBarry Smith   *dm = snes->dm;
42956c699258SBarry Smith   PetscFunctionReturn(0);
42966c699258SBarry Smith }
42970807856dSBarry Smith 
429831823bd8SMatthew G Knepley #undef __FUNCT__
429931823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
430031823bd8SMatthew G Knepley /*@
4301fd4b34e9SJed Brown   SNESSetPC - Sets the nonlinear preconditioner to be used.
430231823bd8SMatthew G Knepley 
430331823bd8SMatthew G Knepley   Collective on SNES
430431823bd8SMatthew G Knepley 
430531823bd8SMatthew G Knepley   Input Parameters:
430631823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
430731823bd8SMatthew G Knepley - pc   - the preconditioner object
430831823bd8SMatthew G Knepley 
430931823bd8SMatthew G Knepley   Notes:
431031823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
431131823bd8SMatthew G Knepley   to configure it using the API).
431231823bd8SMatthew G Knepley 
431331823bd8SMatthew G Knepley   Level: developer
431431823bd8SMatthew G Knepley 
431531823bd8SMatthew G Knepley .keywords: SNES, set, precondition
431631823bd8SMatthew G Knepley .seealso: SNESGetPC()
431731823bd8SMatthew G Knepley @*/
431831823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
431931823bd8SMatthew G Knepley {
432031823bd8SMatthew G Knepley   PetscErrorCode ierr;
432131823bd8SMatthew G Knepley 
432231823bd8SMatthew G Knepley   PetscFunctionBegin;
432331823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
432431823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
432531823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
432631823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4327bf11d3b6SBarry Smith   ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr);
432831823bd8SMatthew G Knepley   snes->pc = pc;
432931823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
433031823bd8SMatthew G Knepley   PetscFunctionReturn(0);
433131823bd8SMatthew G Knepley }
433231823bd8SMatthew G Knepley 
433331823bd8SMatthew G Knepley #undef __FUNCT__
433431823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
433531823bd8SMatthew G Knepley /*@
4336fd4b34e9SJed Brown   SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().
433731823bd8SMatthew G Knepley 
433831823bd8SMatthew G Knepley   Not Collective
433931823bd8SMatthew G Knepley 
434031823bd8SMatthew G Knepley   Input Parameter:
434131823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
434231823bd8SMatthew G Knepley 
434331823bd8SMatthew G Knepley   Output Parameter:
434431823bd8SMatthew G Knepley . pc - preconditioner context
434531823bd8SMatthew G Knepley 
434631823bd8SMatthew G Knepley   Level: developer
434731823bd8SMatthew G Knepley 
434831823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
434931823bd8SMatthew G Knepley .seealso: SNESSetPC()
435031823bd8SMatthew G Knepley @*/
435131823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
435231823bd8SMatthew G Knepley {
435331823bd8SMatthew G Knepley   PetscErrorCode              ierr;
4354*a64e098fSPeter Brune   SNESLineSearch              linesearch;
4355*a64e098fSPeter Brune   SNESLineSearch              pclinesearch;
4356*a64e098fSPeter Brune   void                        *lsprectx,*lspostctx;
4357*a64e098fSPeter Brune   SNESLineSearchPreCheckFunc  lsprefunc;
4358*a64e098fSPeter Brune   SNESLineSearchPostCheckFunc lspostfunc;
4359*a64e098fSPeter Brune   DM                          dm;
4360*a64e098fSPeter Brune   const char                  *optionsprefix;
436131823bd8SMatthew G Knepley 
436231823bd8SMatthew G Knepley   PetscFunctionBegin;
436331823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
436431823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
436531823bd8SMatthew G Knepley   if (!snes->pc) {
436631823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm,&snes->pc);CHKERRQ(ierr);
43674a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);CHKERRQ(ierr);
436831823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes,snes->pc);CHKERRQ(ierr);
4369*a64e098fSPeter Brune     ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr);
4370*a64e098fSPeter Brune     ierr = SNESSetOptionsPrefix(snes->pc,optionsprefix);CHKERRQ(ierr);
4371*a64e098fSPeter Brune     ierr = SNESAppendOptionsPrefix(snes->pc,"npc_");CHKERRQ(ierr);
4372*a64e098fSPeter Brune 
4373*a64e098fSPeter Brune     /* copy the DM over */
4374*a64e098fSPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4375*a64e098fSPeter Brune     ierr = SNESSetDM(snes->pc,dm);CHKERRQ(ierr);
4376*a64e098fSPeter Brune 
4377*a64e098fSPeter Brune    /* copy the function pointers over */
4378*a64e098fSPeter Brune     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr);
4379*a64e098fSPeter Brune 
4380*a64e098fSPeter Brune      /* default to 1 iteration */
4381*a64e098fSPeter Brune     ierr = SNESSetTolerances(snes->pc, snes->pc->abstol, snes->pc->rtol, snes->pc->stol, 1, snes->pc->max_funcs);CHKERRQ(ierr);
4382*a64e098fSPeter Brune     ierr = SNESSetNormType(snes->pc, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr);
4383*a64e098fSPeter Brune     ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr);
4384*a64e098fSPeter Brune 
4385*a64e098fSPeter Brune 
4386*a64e098fSPeter Brune     /* copy the line search context over */
4387*a64e098fSPeter Brune     ierr = SNESGetSNESLineSearch(snes,&linesearch);CHKERRQ(ierr);
4388*a64e098fSPeter Brune     ierr = SNESGetSNESLineSearch(snes->pc,&pclinesearch);CHKERRQ(ierr);
4389*a64e098fSPeter Brune     ierr = SNESLineSearchGetPreCheck(linesearch,&lsprefunc,&lsprectx);CHKERRQ(ierr);
4390*a64e098fSPeter Brune     ierr = SNESLineSearchGetPostCheck(linesearch,&lspostfunc,&lspostctx);CHKERRQ(ierr);
4391*a64e098fSPeter Brune     ierr = SNESLineSearchSetPreCheck(pclinesearch,lsprefunc,lsprectx);CHKERRQ(ierr);
4392*a64e098fSPeter Brune     ierr = SNESLineSearchSetPostCheck(pclinesearch,lspostfunc,lspostctx);CHKERRQ(ierr);
4393*a64e098fSPeter Brune     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr);
439431823bd8SMatthew G Knepley   }
439531823bd8SMatthew G Knepley   *pc = snes->pc;
439631823bd8SMatthew G Knepley   PetscFunctionReturn(0);
439731823bd8SMatthew G Knepley }
439831823bd8SMatthew G Knepley 
43999e764e56SPeter Brune #undef __FUNCT__
4400f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch"
44019e764e56SPeter Brune /*@
44028141a3b9SPeter Brune   SNESSetSNESLineSearch - Sets the linesearch on the SNES instance.
44039e764e56SPeter Brune 
44049e764e56SPeter Brune   Collective on SNES
44059e764e56SPeter Brune 
44069e764e56SPeter Brune   Input Parameters:
44079e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
44089e764e56SPeter Brune - linesearch   - the linesearch object
44099e764e56SPeter Brune 
44109e764e56SPeter Brune   Notes:
4411f1c6b773SPeter Brune   Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example,
44129e764e56SPeter Brune   to configure it using the API).
44139e764e56SPeter Brune 
44149e764e56SPeter Brune   Level: developer
44159e764e56SPeter Brune 
44169e764e56SPeter Brune .keywords: SNES, set, linesearch
4417f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch()
44189e764e56SPeter Brune @*/
4419f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch)
44209e764e56SPeter Brune {
44219e764e56SPeter Brune   PetscErrorCode ierr;
44229e764e56SPeter Brune 
44239e764e56SPeter Brune   PetscFunctionBegin;
44249e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4425f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
44269e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
44279e764e56SPeter Brune   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
4428f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
44299e764e56SPeter Brune   snes->linesearch = linesearch;
44309e764e56SPeter Brune   ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
44319e764e56SPeter Brune   PetscFunctionReturn(0);
44329e764e56SPeter Brune }
44339e764e56SPeter Brune 
44349e764e56SPeter Brune #undef __FUNCT__
4435f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch"
4436ea5d4fccSPeter Brune /*@C
44378141a3b9SPeter Brune   SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch()
44388141a3b9SPeter Brune   or creates a default line search instance associated with the SNES and returns it.
44399e764e56SPeter Brune 
44409e764e56SPeter Brune   Not Collective
44419e764e56SPeter Brune 
44429e764e56SPeter Brune   Input Parameter:
44439e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
44449e764e56SPeter Brune 
44459e764e56SPeter Brune   Output Parameter:
44469e764e56SPeter Brune . linesearch - linesearch context
44479e764e56SPeter Brune 
44489e764e56SPeter Brune   Level: developer
44499e764e56SPeter Brune 
44509e764e56SPeter Brune .keywords: SNES, get, linesearch
4451f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch()
44529e764e56SPeter Brune @*/
4453f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch)
44549e764e56SPeter Brune {
44559e764e56SPeter Brune   PetscErrorCode ierr;
44569e764e56SPeter Brune   const char     *optionsprefix;
44579e764e56SPeter Brune 
44589e764e56SPeter Brune   PetscFunctionBegin;
44599e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
44609e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
44619e764e56SPeter Brune   if (!snes->linesearch) {
44629e764e56SPeter Brune     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
4463f1c6b773SPeter Brune     ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr);
4464f1c6b773SPeter Brune     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
4465b1dca40bSPeter Brune     ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr);
44669e764e56SPeter Brune     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
44679e764e56SPeter Brune     ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
44689e764e56SPeter Brune   }
44699e764e56SPeter Brune   *linesearch = snes->linesearch;
44709e764e56SPeter Brune   PetscFunctionReturn(0);
44719e764e56SPeter Brune }
44729e764e56SPeter Brune 
447369b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4474c6db04a5SJed Brown #include <mex.h>
447569b4f73cSBarry Smith 
44768f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
44778f6e6473SBarry Smith 
44780807856dSBarry Smith #undef __FUNCT__
44790807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
44800807856dSBarry Smith /*
44810807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
44820807856dSBarry Smith                          SNESSetFunctionMatlab().
44830807856dSBarry Smith 
44840807856dSBarry Smith    Collective on SNES
44850807856dSBarry Smith 
44860807856dSBarry Smith    Input Parameters:
44870807856dSBarry Smith +  snes - the SNES context
44880807856dSBarry Smith -  x - input vector
44890807856dSBarry Smith 
44900807856dSBarry Smith    Output Parameter:
44910807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
44920807856dSBarry Smith 
44930807856dSBarry Smith    Notes:
44940807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
44950807856dSBarry Smith    implementations, so most users would not generally call this routine
44960807856dSBarry Smith    themselves.
44970807856dSBarry Smith 
44980807856dSBarry Smith    Level: developer
44990807856dSBarry Smith 
45000807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
45010807856dSBarry Smith 
45020807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
450361b2408cSBarry Smith */
45047087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
45050807856dSBarry Smith {
4506e650e774SBarry Smith   PetscErrorCode    ierr;
45078f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
45088f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
45098f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
451091621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
4511e650e774SBarry Smith 
45120807856dSBarry Smith   PetscFunctionBegin;
45130807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
45140807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
45150807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
45160807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
45170807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
45180807856dSBarry Smith 
45190807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
4520e650e774SBarry Smith 
452191621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4522e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4523e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
452491621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
452591621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
452691621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
45278f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
45288f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
4529b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
4530e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4531e650e774SBarry Smith   mxDestroyArray(prhs[0]);
4532e650e774SBarry Smith   mxDestroyArray(prhs[1]);
4533e650e774SBarry Smith   mxDestroyArray(prhs[2]);
45348f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
4535e650e774SBarry Smith   mxDestroyArray(plhs[0]);
45360807856dSBarry Smith   PetscFunctionReturn(0);
45370807856dSBarry Smith }
45380807856dSBarry Smith 
45390807856dSBarry Smith 
45400807856dSBarry Smith #undef __FUNCT__
45410807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
454261b2408cSBarry Smith /*
45430807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
45440807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4545e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
45460807856dSBarry Smith 
45470807856dSBarry Smith    Logically Collective on SNES
45480807856dSBarry Smith 
45490807856dSBarry Smith    Input Parameters:
45500807856dSBarry Smith +  snes - the SNES context
45510807856dSBarry Smith .  r - vector to store function value
45520807856dSBarry Smith -  func - function evaluation routine
45530807856dSBarry Smith 
45540807856dSBarry Smith    Calling sequence of func:
455561b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
45560807856dSBarry Smith 
45570807856dSBarry Smith 
45580807856dSBarry Smith    Notes:
45590807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
45600807856dSBarry Smith $      f'(x) x = -f(x),
45610807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
45620807856dSBarry Smith 
45630807856dSBarry Smith    Level: beginner
45640807856dSBarry Smith 
45650807856dSBarry Smith .keywords: SNES, nonlinear, set, function
45660807856dSBarry Smith 
45670807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
456861b2408cSBarry Smith */
45697087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
45700807856dSBarry Smith {
45710807856dSBarry Smith   PetscErrorCode    ierr;
45728f6e6473SBarry Smith   SNESMatlabContext *sctx;
45730807856dSBarry Smith 
45740807856dSBarry Smith   PetscFunctionBegin;
45758f6e6473SBarry Smith   /* currently sctx is memory bleed */
45768f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
45778f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
45788f6e6473SBarry Smith   /*
45798f6e6473SBarry Smith      This should work, but it doesn't
45808f6e6473SBarry Smith   sctx->ctx = ctx;
45818f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
45828f6e6473SBarry Smith   */
45838f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
45848f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
45850807856dSBarry Smith   PetscFunctionReturn(0);
45860807856dSBarry Smith }
458769b4f73cSBarry Smith 
458861b2408cSBarry Smith #undef __FUNCT__
458961b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
459061b2408cSBarry Smith /*
459161b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
459261b2408cSBarry Smith                          SNESSetJacobianMatlab().
459361b2408cSBarry Smith 
459461b2408cSBarry Smith    Collective on SNES
459561b2408cSBarry Smith 
459661b2408cSBarry Smith    Input Parameters:
459761b2408cSBarry Smith +  snes - the SNES context
459861b2408cSBarry Smith .  x - input vector
459961b2408cSBarry Smith .  A, B - the matrices
460061b2408cSBarry Smith -  ctx - user context
460161b2408cSBarry Smith 
460261b2408cSBarry Smith    Output Parameter:
460361b2408cSBarry Smith .  flag - structure of the matrix
460461b2408cSBarry Smith 
460561b2408cSBarry Smith    Level: developer
460661b2408cSBarry Smith 
460761b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
460861b2408cSBarry Smith 
460961b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
461061b2408cSBarry Smith @*/
46117087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
461261b2408cSBarry Smith {
461361b2408cSBarry Smith   PetscErrorCode    ierr;
461461b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
461561b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
461661b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
461761b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
461861b2408cSBarry Smith 
461961b2408cSBarry Smith   PetscFunctionBegin;
462061b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
462161b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
462261b2408cSBarry Smith 
462361b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
462461b2408cSBarry Smith 
462561b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
462661b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
462761b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
462861b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
462961b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
463061b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
463161b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
463261b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
463361b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
463461b2408cSBarry Smith   prhs[5] =  sctx->ctx;
4635b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
463661b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
463761b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
463861b2408cSBarry Smith   mxDestroyArray(prhs[0]);
463961b2408cSBarry Smith   mxDestroyArray(prhs[1]);
464061b2408cSBarry Smith   mxDestroyArray(prhs[2]);
464161b2408cSBarry Smith   mxDestroyArray(prhs[3]);
464261b2408cSBarry Smith   mxDestroyArray(prhs[4]);
464361b2408cSBarry Smith   mxDestroyArray(plhs[0]);
464461b2408cSBarry Smith   mxDestroyArray(plhs[1]);
464561b2408cSBarry Smith   PetscFunctionReturn(0);
464661b2408cSBarry Smith }
464761b2408cSBarry Smith 
464861b2408cSBarry Smith 
464961b2408cSBarry Smith #undef __FUNCT__
465061b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
465161b2408cSBarry Smith /*
465261b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
465361b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4654e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
465561b2408cSBarry Smith 
465661b2408cSBarry Smith    Logically Collective on SNES
465761b2408cSBarry Smith 
465861b2408cSBarry Smith    Input Parameters:
465961b2408cSBarry Smith +  snes - the SNES context
466061b2408cSBarry Smith .  A,B - Jacobian matrices
466161b2408cSBarry Smith .  func - function evaluation routine
466261b2408cSBarry Smith -  ctx - user context
466361b2408cSBarry Smith 
466461b2408cSBarry Smith    Calling sequence of func:
466561b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
466661b2408cSBarry Smith 
466761b2408cSBarry Smith 
466861b2408cSBarry Smith    Level: developer
466961b2408cSBarry Smith 
467061b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
467161b2408cSBarry Smith 
467261b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
467361b2408cSBarry Smith */
46747087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
467561b2408cSBarry Smith {
467661b2408cSBarry Smith   PetscErrorCode    ierr;
467761b2408cSBarry Smith   SNESMatlabContext *sctx;
467861b2408cSBarry Smith 
467961b2408cSBarry Smith   PetscFunctionBegin;
468061b2408cSBarry Smith   /* currently sctx is memory bleed */
468161b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
468261b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
468361b2408cSBarry Smith   /*
468461b2408cSBarry Smith      This should work, but it doesn't
468561b2408cSBarry Smith   sctx->ctx = ctx;
468661b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
468761b2408cSBarry Smith   */
468861b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
468961b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
469061b2408cSBarry Smith   PetscFunctionReturn(0);
469161b2408cSBarry Smith }
469269b4f73cSBarry Smith 
4693f9eb7ae2SShri Abhyankar #undef __FUNCT__
4694f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
4695f9eb7ae2SShri Abhyankar /*
4696f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
4697f9eb7ae2SShri Abhyankar 
4698f9eb7ae2SShri Abhyankar    Collective on SNES
4699f9eb7ae2SShri Abhyankar 
4700f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
4701f9eb7ae2SShri Abhyankar @*/
47027087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
4703f9eb7ae2SShri Abhyankar {
4704f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
470548f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
4706f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
4707f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
4708f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
4709f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
4710f9eb7ae2SShri Abhyankar 
4711f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4712f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4713f9eb7ae2SShri Abhyankar 
4714f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4715f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4716f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
4717f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
4718f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
4719f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
4720f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
4721f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
4722f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
4723f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4724f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
4725f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
4726f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
4727f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
4728f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
4729f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
4730f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4731f9eb7ae2SShri Abhyankar }
4732f9eb7ae2SShri Abhyankar 
4733f9eb7ae2SShri Abhyankar 
4734f9eb7ae2SShri Abhyankar #undef __FUNCT__
4735f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
4736f9eb7ae2SShri Abhyankar /*
4737e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
4738f9eb7ae2SShri Abhyankar 
4739f9eb7ae2SShri Abhyankar    Level: developer
4740f9eb7ae2SShri Abhyankar 
4741f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
4742f9eb7ae2SShri Abhyankar 
4743f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
4744f9eb7ae2SShri Abhyankar */
47457087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
4746f9eb7ae2SShri Abhyankar {
4747f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
4748f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
4749f9eb7ae2SShri Abhyankar 
4750f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4751f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
4752f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
4753f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4754f9eb7ae2SShri Abhyankar   /*
4755f9eb7ae2SShri Abhyankar      This should work, but it doesn't
4756f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
4757f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
4758f9eb7ae2SShri Abhyankar   */
4759f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
4760f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4761f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4762f9eb7ae2SShri Abhyankar }
4763f9eb7ae2SShri Abhyankar 
476469b4f73cSBarry Smith #endif
4765