xref: /petsc/src/snes/interface/snes.c (revision dfe153156869f5931ee6b299eecdcfd8470c0dd0)
19b94acceSBarry Smith 
2b45d2f2cSJed Brown #include <petsc-private/snesimpl.h>      /*I "petscsnes.h"  I*/
36cab3a1bSJed Brown #include <petscdmshell.h>          /*I "petscdmshell.h" I*/
49b94acceSBarry Smith 
5ace3abfcSBarry Smith PetscBool  SNESRegisterAllCalled = PETSC_FALSE;
68ba1e511SMatthew Knepley PetscFList SNESList              = PETSC_NULL;
78ba1e511SMatthew Knepley 
88ba1e511SMatthew Knepley /* Logging support */
97087cfbeSBarry Smith PetscClassId  SNES_CLASSID;
10f1c6b773SPeter Brune PetscLogEvent  SNES_Solve, SNES_FunctionEval, SNES_JacobianEval, SNES_GSEval;
11a09944afSBarry Smith 
12a09944afSBarry Smith #undef __FUNCT__
13cab2e9ccSBarry Smith #define __FUNCT__ "SNESDMComputeJacobian"
14cab2e9ccSBarry Smith /*
15cab2e9ccSBarry Smith     Translates from a SNES call to a DM call in computing a Jacobian
16caa4e7f2SJed Brown 
17caa4e7f2SJed Brown     This is a legacy calling sequence, should transition to dispatching through the SNESDM.
18cab2e9ccSBarry Smith */
19cab2e9ccSBarry Smith PetscErrorCode SNESDMComputeJacobian(SNES snes,Vec X,Mat *J,Mat *B,MatStructure *flag,void *ptr)
20cab2e9ccSBarry Smith {
21cab2e9ccSBarry Smith   PetscErrorCode ierr;
22cab2e9ccSBarry Smith   DM             dm;
23cab2e9ccSBarry Smith 
24cab2e9ccSBarry Smith   PetscFunctionBegin;
25cab2e9ccSBarry Smith   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
26cab2e9ccSBarry Smith   ierr = DMComputeJacobian(dm,X,*J,*B,flag);CHKERRQ(ierr);
27cab2e9ccSBarry Smith   PetscFunctionReturn(0);
28cab2e9ccSBarry Smith }
29cab2e9ccSBarry Smith 
30cab2e9ccSBarry Smith #undef __FUNCT__
31e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged"
32e113a28aSBarry Smith /*@
33e113a28aSBarry Smith    SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged.
34e113a28aSBarry Smith 
353f9fe445SBarry Smith    Logically Collective on SNES
36e113a28aSBarry Smith 
37e113a28aSBarry Smith    Input Parameters:
38e113a28aSBarry Smith +  snes - iterative context obtained from SNESCreate()
39e113a28aSBarry Smith -  flg - PETSC_TRUE indicates you want the error generated
40e113a28aSBarry Smith 
41e113a28aSBarry Smith    Options database keys:
42e113a28aSBarry Smith .  -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false)
43e113a28aSBarry Smith 
44e113a28aSBarry Smith    Level: intermediate
45e113a28aSBarry Smith 
46e113a28aSBarry Smith    Notes:
47e113a28aSBarry Smith     Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve()
48e113a28aSBarry Smith     to determine if it has converged.
49e113a28aSBarry Smith 
50e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
51e113a28aSBarry Smith 
52e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
53e113a28aSBarry Smith @*/
547087cfbeSBarry Smith PetscErrorCode  SNESSetErrorIfNotConverged(SNES snes,PetscBool  flg)
55e113a28aSBarry Smith {
56e113a28aSBarry Smith   PetscFunctionBegin;
57e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
58acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flg,2);
59e113a28aSBarry Smith   snes->errorifnotconverged = flg;
60dd568438SSatish Balay 
61e113a28aSBarry Smith   PetscFunctionReturn(0);
62e113a28aSBarry Smith }
63e113a28aSBarry Smith 
64e113a28aSBarry Smith #undef __FUNCT__
65e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged"
66e113a28aSBarry Smith /*@
67e113a28aSBarry Smith    SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge?
68e113a28aSBarry Smith 
69e113a28aSBarry Smith    Not Collective
70e113a28aSBarry Smith 
71e113a28aSBarry Smith    Input Parameter:
72e113a28aSBarry Smith .  snes - iterative context obtained from SNESCreate()
73e113a28aSBarry Smith 
74e113a28aSBarry Smith    Output Parameter:
75e113a28aSBarry Smith .  flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE
76e113a28aSBarry Smith 
77e113a28aSBarry Smith    Level: intermediate
78e113a28aSBarry Smith 
79e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
80e113a28aSBarry Smith 
81e113a28aSBarry Smith .seealso:  SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
82e113a28aSBarry Smith @*/
837087cfbeSBarry Smith PetscErrorCode  SNESGetErrorIfNotConverged(SNES snes,PetscBool  *flag)
84e113a28aSBarry Smith {
85e113a28aSBarry Smith   PetscFunctionBegin;
86e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
87e113a28aSBarry Smith   PetscValidPointer(flag,2);
88e113a28aSBarry Smith   *flag = snes->errorifnotconverged;
89e113a28aSBarry Smith   PetscFunctionReturn(0);
90e113a28aSBarry Smith }
91e113a28aSBarry Smith 
92e113a28aSBarry Smith #undef __FUNCT__
934936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError"
94e725d27bSBarry Smith /*@
954936397dSBarry Smith    SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not
964936397dSBarry Smith      in the functions domain. For example, negative pressure.
974936397dSBarry Smith 
983f9fe445SBarry Smith    Logically Collective on SNES
994936397dSBarry Smith 
1004936397dSBarry Smith    Input Parameters:
1016a388c36SPeter Brune .  snes - the SNES context
1024936397dSBarry Smith 
10328529972SSatish Balay    Level: advanced
1044936397dSBarry Smith 
1054936397dSBarry Smith .keywords: SNES, view
1064936397dSBarry Smith 
1074936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction()
1084936397dSBarry Smith @*/
1097087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionDomainError(SNES snes)
1104936397dSBarry Smith {
1114936397dSBarry Smith   PetscFunctionBegin;
1120700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1134936397dSBarry Smith   snes->domainerror = PETSC_TRUE;
1144936397dSBarry Smith   PetscFunctionReturn(0);
1154936397dSBarry Smith }
1164936397dSBarry Smith 
1176a388c36SPeter Brune 
1186a388c36SPeter Brune #undef __FUNCT__
1196a388c36SPeter Brune #define __FUNCT__ "SNESGetFunctionDomainError"
1206a388c36SPeter Brune /*@
121c77b2880SPeter Brune    SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction;
1226a388c36SPeter Brune 
1236a388c36SPeter Brune    Logically Collective on SNES
1246a388c36SPeter Brune 
1256a388c36SPeter Brune    Input Parameters:
1266a388c36SPeter Brune .  snes - the SNES context
1276a388c36SPeter Brune 
1286a388c36SPeter Brune    Output Parameters:
1296a388c36SPeter Brune .  domainerror Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise.
1306a388c36SPeter Brune 
1316a388c36SPeter Brune    Level: advanced
1326a388c36SPeter Brune 
1336a388c36SPeter Brune .keywords: SNES, view
1346a388c36SPeter Brune 
1356a388c36SPeter Brune .seealso: SNESSetFunctionDomainError, SNESComputeFunction()
1366a388c36SPeter Brune @*/
1376a388c36SPeter Brune PetscErrorCode  SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror)
1386a388c36SPeter Brune {
1396a388c36SPeter Brune   PetscFunctionBegin;
1406a388c36SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1416a388c36SPeter Brune   PetscValidPointer(domainerror, 2);
1426a388c36SPeter Brune   *domainerror = snes->domainerror;
1436a388c36SPeter Brune   PetscFunctionReturn(0);
1446a388c36SPeter Brune }
1456a388c36SPeter Brune 
1466a388c36SPeter Brune 
1474936397dSBarry Smith #undef __FUNCT__
1484a2ae208SSatish Balay #define __FUNCT__ "SNESView"
1497e2c5f70SBarry Smith /*@C
1509b94acceSBarry Smith    SNESView - Prints the SNES data structure.
1519b94acceSBarry Smith 
1524c49b128SBarry Smith    Collective on SNES
153fee21e36SBarry Smith 
154c7afd0dbSLois Curfman McInnes    Input Parameters:
155c7afd0dbSLois Curfman McInnes +  SNES - the SNES context
156c7afd0dbSLois Curfman McInnes -  viewer - visualization context
157c7afd0dbSLois Curfman McInnes 
1589b94acceSBarry Smith    Options Database Key:
159c8a8ba5cSLois Curfman McInnes .  -snes_view - Calls SNESView() at end of SNESSolve()
1609b94acceSBarry Smith 
1619b94acceSBarry Smith    Notes:
1629b94acceSBarry Smith    The available visualization contexts include
163b0a32e0cSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
164b0a32e0cSBarry Smith -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
165c8a8ba5cSLois Curfman McInnes          output where only the first processor opens
166c8a8ba5cSLois Curfman McInnes          the file.  All other processors send their
167c8a8ba5cSLois Curfman McInnes          data to the first processor to print.
1689b94acceSBarry Smith 
1693e081fefSLois Curfman McInnes    The user can open an alternative visualization context with
170b0a32e0cSBarry Smith    PetscViewerASCIIOpen() - output to a specified file.
1719b94acceSBarry Smith 
17236851e7fSLois Curfman McInnes    Level: beginner
17336851e7fSLois Curfman McInnes 
1749b94acceSBarry Smith .keywords: SNES, view
1759b94acceSBarry Smith 
176b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen()
1779b94acceSBarry Smith @*/
1787087cfbeSBarry Smith PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
1799b94acceSBarry Smith {
180fa9f3622SBarry Smith   SNESKSPEW           *kctx;
181dfbe8321SBarry Smith   PetscErrorCode      ierr;
18294b7f48cSBarry Smith   KSP                 ksp;
1837f1410a3SPeter Brune   SNESLineSearch      linesearch;
184ace3abfcSBarry Smith   PetscBool           iascii,isstring;
1859b94acceSBarry Smith 
1863a40ed3dSBarry Smith   PetscFunctionBegin;
1870700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1883050cee2SBarry Smith   if (!viewer) {
1897adad957SLisandro Dalcin     ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
1903050cee2SBarry Smith   }
1910700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
192c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,viewer,2);
19374679c65SBarry Smith 
1942692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1952692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
19632077d6dSBarry Smith   if (iascii) {
197317d6ea6SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr);
198e7788613SBarry Smith     if (snes->ops->view) {
199b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
200e7788613SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
201b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2020ef38995SBarry Smith     }
20377431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr);
204a83599f4SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%G, absolute=%G, solution=%G\n",
205c60f73f4SPeter Brune                  snes->rtol,snes->abstol,snes->stol);CHKERRQ(ierr);
20677431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr);
20777431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr);
2089b94acceSBarry Smith     if (snes->ksp_ewconv) {
209fa9f3622SBarry Smith       kctx = (SNESKSPEW *)snes->kspconvctx;
2109b94acceSBarry Smith       if (kctx) {
21177431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr);
212a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr);
213a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr);
2149b94acceSBarry Smith       }
2159b94acceSBarry Smith     }
216eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
217eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");CHKERRQ(ierr);
218eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
219eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr);
220eb1f6c34SBarry Smith     }
221eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
222eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");CHKERRQ(ierr);
223eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
22442f4f86dSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr);
225eb1f6c34SBarry Smith     }
2260f5bd95cSBarry Smith   } else if (isstring) {
227317d6ea6SBarry Smith     const char *type;
228454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
229b0a32e0cSBarry Smith     ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr);
23019bcc07fSBarry Smith   }
23142f4f86dSBarry Smith   if (snes->pc && snes->usespc) {
2324a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2334a0c5b0cSMatthew G Knepley     ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr);
2344a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2354a0c5b0cSMatthew G Knepley   }
2362c155ee1SBarry Smith   if (snes->usesksp) {
2372c155ee1SBarry Smith     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
238b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
23994b7f48cSBarry Smith     ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
240b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2412c155ee1SBarry Smith   }
2427f1410a3SPeter Brune   if (snes->linesearch) {
2437f1410a3SPeter Brune     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2447f1410a3SPeter Brune     ierr = SNESGetSNESLineSearch(snes, &linesearch);CHKERRQ(ierr);
2457f1410a3SPeter Brune     ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr);
2467f1410a3SPeter Brune     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2477f1410a3SPeter Brune   }
2483a40ed3dSBarry Smith   PetscFunctionReturn(0);
2499b94acceSBarry Smith }
2509b94acceSBarry Smith 
25176b2cf59SMatthew Knepley /*
25276b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
25376b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
25476b2cf59SMatthew Knepley */
25576b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
256a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
2576849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
25876b2cf59SMatthew Knepley 
259e74ef692SMatthew Knepley #undef __FUNCT__
260e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker"
261ac226902SBarry Smith /*@C
26276b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
26376b2cf59SMatthew Knepley 
26476b2cf59SMatthew Knepley   Not Collective
26576b2cf59SMatthew Knepley 
26676b2cf59SMatthew Knepley   Input Parameter:
26776b2cf59SMatthew Knepley . snescheck - function that checks for options
26876b2cf59SMatthew Knepley 
26976b2cf59SMatthew Knepley   Level: developer
27076b2cf59SMatthew Knepley 
27176b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
27276b2cf59SMatthew Knepley @*/
2737087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
27476b2cf59SMatthew Knepley {
27576b2cf59SMatthew Knepley   PetscFunctionBegin;
27676b2cf59SMatthew Knepley   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
277e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
27876b2cf59SMatthew Knepley   }
27976b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
28076b2cf59SMatthew Knepley   PetscFunctionReturn(0);
28176b2cf59SMatthew Knepley }
28276b2cf59SMatthew Knepley 
2837087cfbeSBarry Smith extern PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
284aa3661deSLisandro Dalcin 
285aa3661deSLisandro Dalcin #undef __FUNCT__
286aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private"
287ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool  hasOperator, PetscInt version)
288aa3661deSLisandro Dalcin {
289aa3661deSLisandro Dalcin   Mat            J;
290aa3661deSLisandro Dalcin   KSP            ksp;
291aa3661deSLisandro Dalcin   PC             pc;
292ace3abfcSBarry Smith   PetscBool      match;
293aa3661deSLisandro Dalcin   PetscErrorCode ierr;
294aa3661deSLisandro Dalcin 
295aa3661deSLisandro Dalcin   PetscFunctionBegin;
2960700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
297aa3661deSLisandro Dalcin 
29898613b67SLisandro Dalcin   if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
29998613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
30098613b67SLisandro Dalcin     ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr);
30198613b67SLisandro Dalcin   }
30298613b67SLisandro Dalcin 
303aa3661deSLisandro Dalcin   if (version == 1) {
304aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
30598613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
3069c6ac3b3SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
307aa3661deSLisandro Dalcin   } else if (version == 2) {
308e32f2f54SBarry Smith     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
30982a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
310aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
311aa3661deSLisandro Dalcin #else
312e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
313aa3661deSLisandro Dalcin #endif
314a8248277SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
315aa3661deSLisandro Dalcin 
316aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
317d3462f78SMatthew Knepley   if (hasOperator) {
318aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
319aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
320aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
321aa3661deSLisandro Dalcin   } else {
322aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
323aa3661deSLisandro Dalcin        provided preconditioner matrix with the default matrix free version. */
3246cab3a1bSJed Brown     void *functx;
3256cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
3266cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
327aa3661deSLisandro Dalcin     /* Force no preconditioner */
328aa3661deSLisandro Dalcin     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
329aa3661deSLisandro Dalcin     ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
330aa3661deSLisandro Dalcin     ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
331aa3661deSLisandro Dalcin     if (!match) {
332aa3661deSLisandro Dalcin       ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
333aa3661deSLisandro Dalcin       ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
334aa3661deSLisandro Dalcin     }
335aa3661deSLisandro Dalcin   }
3366bf464f9SBarry Smith   ierr = MatDestroy(&J);CHKERRQ(ierr);
337aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
338aa3661deSLisandro Dalcin }
339aa3661deSLisandro Dalcin 
3404a2ae208SSatish Balay #undef __FUNCT__
341*dfe15315SJed Brown #define __FUNCT__ "DMRestrictHook_SNESVecSol"
342*dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx)
343*dfe15315SJed Brown {
344*dfe15315SJed Brown   SNES snes = (SNES)ctx;
345*dfe15315SJed Brown   PetscErrorCode ierr;
346*dfe15315SJed Brown   Vec Xfine,Xfine_named = PETSC_NULL,Xcoarse;
347*dfe15315SJed Brown 
348*dfe15315SJed Brown   PetscFunctionBegin;
349*dfe15315SJed Brown   if (dmfine == snes->dm) Xfine = snes->vec_sol;
350*dfe15315SJed Brown   else {
351*dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);
352*dfe15315SJed Brown     Xfine = Xfine_named;
353*dfe15315SJed Brown   }
354*dfe15315SJed Brown   ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
355*dfe15315SJed Brown   ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr);
356*dfe15315SJed Brown   ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr);
357*dfe15315SJed Brown   ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
358*dfe15315SJed Brown   if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);}
359*dfe15315SJed Brown   PetscFunctionReturn(0);
360*dfe15315SJed Brown }
361*dfe15315SJed Brown 
362*dfe15315SJed Brown #undef __FUNCT__
363caa4e7f2SJed Brown #define __FUNCT__ "KSPComputeOperators_SNES"
364caa4e7f2SJed Brown static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,MatStructure *mstruct,void *ctx)
365caa4e7f2SJed Brown {
366caa4e7f2SJed Brown   SNES snes = (SNES)ctx;
367caa4e7f2SJed Brown   PetscErrorCode ierr;
368caa4e7f2SJed Brown   Mat Asave = A,Bsave = B;
369*dfe15315SJed Brown   Vec X,Xnamed = PETSC_NULL;
370*dfe15315SJed Brown   DM dmsave;
371caa4e7f2SJed Brown 
372caa4e7f2SJed Brown   PetscFunctionBegin;
373*dfe15315SJed Brown   dmsave = snes->dm;
374*dfe15315SJed Brown   ierr = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr);
375*dfe15315SJed Brown   if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */
376*dfe15315SJed Brown   else {                                     /* We are on a coarser level, this vec was initialized using a DM restrict hook */
377*dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
378*dfe15315SJed Brown     X = Xnamed;
379*dfe15315SJed Brown   }
380*dfe15315SJed Brown   ierr = SNESComputeJacobian(snes,X,&A,&B,mstruct);CHKERRQ(ierr);
381caa4e7f2SJed Brown   if (A != Asave || B != Bsave) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_SUP,"No support for changing matrices at this time");
382*dfe15315SJed Brown   if (Xnamed) {
383*dfe15315SJed Brown     ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
384*dfe15315SJed Brown   }
385*dfe15315SJed Brown   snes->dm = dmsave;
386caa4e7f2SJed Brown   PetscFunctionReturn(0);
387caa4e7f2SJed Brown }
388caa4e7f2SJed Brown 
389caa4e7f2SJed Brown #undef __FUNCT__
3906cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices"
3916cab3a1bSJed Brown /*@
3926cab3a1bSJed Brown    SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX()
3936cab3a1bSJed Brown 
3946cab3a1bSJed Brown    Collective
3956cab3a1bSJed Brown 
3966cab3a1bSJed Brown    Input Arguments:
3976cab3a1bSJed Brown .  snes - snes to configure
3986cab3a1bSJed Brown 
3996cab3a1bSJed Brown    Level: developer
4006cab3a1bSJed Brown 
4016cab3a1bSJed Brown .seealso: SNESSetUp()
4026cab3a1bSJed Brown @*/
4036cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes)
4046cab3a1bSJed Brown {
4056cab3a1bSJed Brown   PetscErrorCode ierr;
4066cab3a1bSJed Brown   DM             dm;
4076cab3a1bSJed Brown   SNESDM         sdm;
4086cab3a1bSJed Brown 
4096cab3a1bSJed Brown   PetscFunctionBegin;
4106cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4116cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
412caa4e7f2SJed Brown   if (!sdm->computejacobian) {
4136cab3a1bSJed Brown     Mat J,B;
4146cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4156cab3a1bSJed Brown     if (snes->mf_operator) {
4166cab3a1bSJed Brown       ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4176cab3a1bSJed Brown       ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4186cab3a1bSJed Brown       ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4196cab3a1bSJed Brown     } else {
4206cab3a1bSJed Brown       J = B;
4216cab3a1bSJed Brown       ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
4226cab3a1bSJed Brown     }
4236cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr);
4246cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
4256cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
4266cab3a1bSJed Brown   } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) {
4276cab3a1bSJed Brown     Mat J;
4286cab3a1bSJed Brown     void *functx;
4296cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4306cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4316cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4326cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
4336cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
4346cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
435caa4e7f2SJed Brown   } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
4366cab3a1bSJed Brown     Mat J,B;
4376cab3a1bSJed Brown     void *functx;
4386cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4396cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4406cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4416cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4426cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
4436cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,functx);CHKERRQ(ierr);
4446cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
4456cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
446caa4e7f2SJed Brown   } else if (!snes->jacobian_pre) {
4476cab3a1bSJed Brown     Mat J,B;
4486cab3a1bSJed Brown     J = snes->jacobian;
4496cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4506cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
4516cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
4526cab3a1bSJed Brown   }
453caa4e7f2SJed Brown   {
454caa4e7f2SJed Brown     PetscBool flg = PETSC_FALSE;
455caa4e7f2SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_kspcompute",&flg,PETSC_NULL);CHKERRQ(ierr);
456caa4e7f2SJed Brown     if (flg) {                  /* Plan to transition to this model */
457caa4e7f2SJed Brown       KSP ksp;
458caa4e7f2SJed Brown       ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
459caa4e7f2SJed Brown       ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr);
460*dfe15315SJed Brown       ierr = DMCoarsenHookAdd(snes->dm,PETSC_NULL,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr);
461caa4e7f2SJed Brown     }
462caa4e7f2SJed Brown   }
4636cab3a1bSJed Brown   PetscFunctionReturn(0);
4646cab3a1bSJed Brown }
4656cab3a1bSJed Brown 
4666cab3a1bSJed Brown #undef __FUNCT__
4674a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions"
4689b94acceSBarry Smith /*@
46994b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
4709b94acceSBarry Smith 
471c7afd0dbSLois Curfman McInnes    Collective on SNES
472c7afd0dbSLois Curfman McInnes 
4739b94acceSBarry Smith    Input Parameter:
4749b94acceSBarry Smith .  snes - the SNES context
4759b94acceSBarry Smith 
47636851e7fSLois Curfman McInnes    Options Database Keys:
477ea630c6eSPeter Brune +  -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas
47882738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
47982738288SBarry Smith                 of the change in the solution between steps
48070441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
481b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
482b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
483b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
4844839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
485ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
486a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
487e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
488b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
4892492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
49082738288SBarry Smith                                solver; hence iterations will continue until max_it
4911fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
49282738288SBarry Smith                                of convergence test
493e8105e01SRichard Katz .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
494e8105e01SRichard Katz                                        filename given prints to stdout
495a6570f20SBarry Smith .  -snes_monitor_solution - plots solution at each iteration
496a6570f20SBarry Smith .  -snes_monitor_residual - plots residual (not its norm) at each iteration
497a6570f20SBarry Smith .  -snes_monitor_solution_update - plots update to solution at each iteration
498a6570f20SBarry Smith .  -snes_monitor_draw - plots residual norm at each iteration
499e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
5005968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
501fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
50282738288SBarry Smith 
50382738288SBarry Smith     Options Database for Eisenstat-Walker method:
504fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
5054b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
50636851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
50736851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
50836851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
50936851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
51036851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
51136851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
51282738288SBarry Smith 
51311ca99fdSLois Curfman McInnes    Notes:
51411ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
5150598bfebSBarry Smith    the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>.
51683e2fdc7SBarry Smith 
51736851e7fSLois Curfman McInnes    Level: beginner
51836851e7fSLois Curfman McInnes 
5199b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
5209b94acceSBarry Smith 
52169ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
5229b94acceSBarry Smith @*/
5237087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
5249b94acceSBarry Smith {
525872b6db9SPeter Brune   PetscBool               flg,mf,mf_operator,pcset;
526efd51863SBarry Smith   PetscInt                i,indx,lag,mf_version,grids;
527aa3661deSLisandro Dalcin   MatStructure            matflag;
52885385478SLisandro Dalcin   const char              *deft = SNESLS;
52985385478SLisandro Dalcin   const char              *convtests[] = {"default","skip"};
53085385478SLisandro Dalcin   SNESKSPEW               *kctx = NULL;
531e8105e01SRichard Katz   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
53251e86f29SPeter Brune   const char              *optionsprefix;
533649052a6SBarry Smith   PetscViewer             monviewer;
53485385478SLisandro Dalcin   PetscErrorCode          ierr;
5359b94acceSBarry Smith 
5363a40ed3dSBarry Smith   PetscFunctionBegin;
5370700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
538ca161407SBarry Smith 
539186905e3SBarry Smith   if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
5403194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
5417adad957SLisandro Dalcin     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
542b0a32e0cSBarry Smith     ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
543d64ed03dSBarry Smith     if (flg) {
544186905e3SBarry Smith       ierr = SNESSetType(snes,type);CHKERRQ(ierr);
5457adad957SLisandro Dalcin     } else if (!((PetscObject)snes)->type_name) {
546186905e3SBarry Smith       ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
547d64ed03dSBarry Smith     }
54890d69ab7SBarry Smith     /* not used here, but called so will go into help messaage */
549909c8a9fSBarry Smith     ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr);
55093c39befSBarry Smith 
551c60f73f4SPeter Brune     ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);CHKERRQ(ierr);
55257034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr);
553186905e3SBarry Smith 
55457034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr);
555b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr);
556b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr);
55750ffb88aSMatthew Knepley     ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr);
558ddf469c8SBarry Smith     ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr);
559acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr);
56085385478SLisandro Dalcin 
561a8054027SBarry Smith     ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
562a8054027SBarry Smith     if (flg) {
563a8054027SBarry Smith       ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
564a8054027SBarry Smith     }
565e35cf81dSBarry Smith     ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
566e35cf81dSBarry Smith     if (flg) {
567e35cf81dSBarry Smith       ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
568e35cf81dSBarry Smith     }
569efd51863SBarry Smith     ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
570efd51863SBarry Smith     if (flg) {
571efd51863SBarry Smith       ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
572efd51863SBarry Smith     }
573a8054027SBarry Smith 
57485385478SLisandro Dalcin     ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
57585385478SLisandro Dalcin     if (flg) {
57685385478SLisandro Dalcin       switch (indx) {
5777f7931b9SBarry Smith       case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break;
5787f7931b9SBarry Smith       case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);    break;
57985385478SLisandro Dalcin       }
58085385478SLisandro Dalcin     }
58185385478SLisandro Dalcin 
582acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr);
583186905e3SBarry Smith 
58485385478SLisandro Dalcin     kctx = (SNESKSPEW *)snes->kspconvctx;
58585385478SLisandro Dalcin 
586acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr);
587186905e3SBarry Smith 
588fa9f3622SBarry Smith     ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr);
589fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr);
590fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr);
591fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr);
592fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr);
593fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr);
594fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr);
595186905e3SBarry Smith 
59690d69ab7SBarry Smith     flg  = PETSC_FALSE;
597acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
598a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
599eabae89aSBarry Smith 
600a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
601e8105e01SRichard Katz     if (flg) {
602649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
603649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
604e8105e01SRichard Katz     }
605eabae89aSBarry Smith 
606b271bb04SBarry Smith     ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
607b271bb04SBarry Smith     if (flg) {
608b271bb04SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr);
609b271bb04SBarry Smith     }
610b271bb04SBarry Smith 
611a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
612eabae89aSBarry Smith     if (flg) {
613649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
614f1bef1bcSMatthew Knepley       ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr);
615e8105e01SRichard Katz     }
616eabae89aSBarry Smith 
617a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
618eabae89aSBarry Smith     if (flg) {
619649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
620649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
621eabae89aSBarry Smith     }
622eabae89aSBarry Smith 
6235180491cSLisandro Dalcin     ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
6245180491cSLisandro Dalcin     if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);}
6255180491cSLisandro Dalcin 
62690d69ab7SBarry Smith     flg  = PETSC_FALSE;
627acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
628a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
62990d69ab7SBarry Smith     flg  = PETSC_FALSE;
630acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
631a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
63290d69ab7SBarry Smith     flg  = PETSC_FALSE;
633acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
634a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
63590d69ab7SBarry Smith     flg  = PETSC_FALSE;
636acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
637a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
63890d69ab7SBarry Smith     flg  = PETSC_FALSE;
639acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
640b271bb04SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
641e24b481bSBarry Smith 
64290d69ab7SBarry Smith     flg  = PETSC_FALSE;
643acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
6444b27c08aSLois Curfman McInnes     if (flg) {
6456cab3a1bSJed Brown       void *functx;
6466cab3a1bSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
6476cab3a1bSJed Brown       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr);
648ae15b995SBarry Smith       ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
6499b94acceSBarry Smith     }
650639f9d9dSBarry Smith 
651aa3661deSLisandro Dalcin     mf = mf_operator = PETSC_FALSE;
652aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
653acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr);
654a8248277SBarry Smith     if (flg && mf_operator) {
655a8248277SBarry Smith       snes->mf_operator = PETSC_TRUE;
656a8248277SBarry Smith       mf = PETSC_TRUE;
657a8248277SBarry Smith     }
658aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
659acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr);
660aa3661deSLisandro Dalcin     if (!flg && mf_operator) mf = PETSC_TRUE;
661aa3661deSLisandro Dalcin     mf_version = 1;
662aa3661deSLisandro Dalcin     ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr);
663aa3661deSLisandro Dalcin 
664d28543b3SPeter Brune 
66589b92e6fSPeter Brune     /* GS Options */
66689b92e6fSPeter Brune     ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr);
66789b92e6fSPeter Brune 
66876b2cf59SMatthew Knepley     for(i = 0; i < numberofsetfromoptions; i++) {
66976b2cf59SMatthew Knepley       ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
67076b2cf59SMatthew Knepley     }
67176b2cf59SMatthew Knepley 
672e7788613SBarry Smith     if (snes->ops->setfromoptions) {
673e7788613SBarry Smith       ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr);
674639f9d9dSBarry Smith     }
6755d973c19SBarry Smith 
6765d973c19SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
6775d973c19SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr);
678b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
6794bbc92c1SBarry Smith 
680aa3661deSLisandro Dalcin   if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); }
6811cee3971SBarry Smith 
6821cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
683aa3661deSLisandro Dalcin   ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
684aa3661deSLisandro Dalcin   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr);
68585385478SLisandro Dalcin   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
68693993e2dSLois Curfman McInnes 
6879e764e56SPeter Brune   if (!snes->linesearch) {
688f1c6b773SPeter Brune     ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
6899e764e56SPeter Brune   }
690f1c6b773SPeter Brune   ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr);
6919e764e56SPeter Brune 
69251e86f29SPeter Brune   /* if someone has set the SNES PC type, create it. */
69351e86f29SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
69451e86f29SPeter Brune   ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr);
69551e86f29SPeter Brune   if (pcset && (!snes->pc)) {
69651e86f29SPeter Brune     ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr);
69751e86f29SPeter Brune   }
6984a0c5b0cSMatthew G Knepley   if (snes->pc) {
699fde0ff24SPeter Brune     ierr = SNESSetOptionsPrefix(snes->pc, optionsprefix);CHKERRQ(ierr);
700fde0ff24SPeter Brune     ierr = SNESAppendOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr);
7014a0c5b0cSMatthew G Knepley     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
70288976e71SPeter Brune     /* default to 1 iteration */
70388976e71SPeter Brune     ierr = SNESSetTolerances(snes->pc, snes->pc->abstol, snes->pc->rtol, snes->pc->stol, 1, snes->pc->max_funcs);CHKERRQ(ierr);
7044a0c5b0cSMatthew G Knepley     ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr);
7054a0c5b0cSMatthew G Knepley   }
7063a40ed3dSBarry Smith   PetscFunctionReturn(0);
7079b94acceSBarry Smith }
7089b94acceSBarry Smith 
709d25893d9SBarry Smith #undef __FUNCT__
710d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext"
711d25893d9SBarry Smith /*@
712d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
713d25893d9SBarry Smith    the nonlinear solvers.
714d25893d9SBarry Smith 
715d25893d9SBarry Smith    Logically Collective on SNES
716d25893d9SBarry Smith 
717d25893d9SBarry Smith    Input Parameters:
718d25893d9SBarry Smith +  snes - the SNES context
719d25893d9SBarry Smith .  compute - function to compute the context
720d25893d9SBarry Smith -  destroy - function to destroy the context
721d25893d9SBarry Smith 
722d25893d9SBarry Smith    Level: intermediate
723d25893d9SBarry Smith 
724d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
725d25893d9SBarry Smith 
726d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
727d25893d9SBarry Smith @*/
728d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
729d25893d9SBarry Smith {
730d25893d9SBarry Smith   PetscFunctionBegin;
731d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
732d25893d9SBarry Smith   snes->ops->usercompute = compute;
733d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
734d25893d9SBarry Smith   PetscFunctionReturn(0);
735d25893d9SBarry Smith }
736a847f771SSatish Balay 
7374a2ae208SSatish Balay #undef __FUNCT__
7384a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
739b07ff414SBarry Smith /*@
7409b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
7419b94acceSBarry Smith    the nonlinear solvers.
7429b94acceSBarry Smith 
7433f9fe445SBarry Smith    Logically Collective on SNES
744fee21e36SBarry Smith 
745c7afd0dbSLois Curfman McInnes    Input Parameters:
746c7afd0dbSLois Curfman McInnes +  snes - the SNES context
747c7afd0dbSLois Curfman McInnes -  usrP - optional user context
748c7afd0dbSLois Curfman McInnes 
74936851e7fSLois Curfman McInnes    Level: intermediate
75036851e7fSLois Curfman McInnes 
7519b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
7529b94acceSBarry Smith 
753d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext()
7549b94acceSBarry Smith @*/
7557087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
7569b94acceSBarry Smith {
7571b2093e4SBarry Smith   PetscErrorCode ierr;
758b07ff414SBarry Smith   KSP            ksp;
7591b2093e4SBarry Smith 
7603a40ed3dSBarry Smith   PetscFunctionBegin;
7610700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
762b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
763b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
7649b94acceSBarry Smith   snes->user = usrP;
7653a40ed3dSBarry Smith   PetscFunctionReturn(0);
7669b94acceSBarry Smith }
76774679c65SBarry Smith 
7684a2ae208SSatish Balay #undef __FUNCT__
7694a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
770b07ff414SBarry Smith /*@
7719b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
7729b94acceSBarry Smith    nonlinear solvers.
7739b94acceSBarry Smith 
774c7afd0dbSLois Curfman McInnes    Not Collective
775c7afd0dbSLois Curfman McInnes 
7769b94acceSBarry Smith    Input Parameter:
7779b94acceSBarry Smith .  snes - SNES context
7789b94acceSBarry Smith 
7799b94acceSBarry Smith    Output Parameter:
7809b94acceSBarry Smith .  usrP - user context
7819b94acceSBarry Smith 
78236851e7fSLois Curfman McInnes    Level: intermediate
78336851e7fSLois Curfman McInnes 
7849b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
7859b94acceSBarry Smith 
7869b94acceSBarry Smith .seealso: SNESSetApplicationContext()
7879b94acceSBarry Smith @*/
788e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
7899b94acceSBarry Smith {
7903a40ed3dSBarry Smith   PetscFunctionBegin;
7910700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
792e71120c6SJed Brown   *(void**)usrP = snes->user;
7933a40ed3dSBarry Smith   PetscFunctionReturn(0);
7949b94acceSBarry Smith }
79574679c65SBarry Smith 
7964a2ae208SSatish Balay #undef __FUNCT__
7974a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
7989b94acceSBarry Smith /*@
799c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
800c8228a4eSBarry Smith    at this time.
8019b94acceSBarry Smith 
802c7afd0dbSLois Curfman McInnes    Not Collective
803c7afd0dbSLois Curfman McInnes 
8049b94acceSBarry Smith    Input Parameter:
8059b94acceSBarry Smith .  snes - SNES context
8069b94acceSBarry Smith 
8079b94acceSBarry Smith    Output Parameter:
8089b94acceSBarry Smith .  iter - iteration number
8099b94acceSBarry Smith 
810c8228a4eSBarry Smith    Notes:
811c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
812c8228a4eSBarry Smith 
813c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
81408405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
81508405cd6SLois Curfman McInnes .vb
81608405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
81708405cd6SLois Curfman McInnes       if (!(it % 2)) {
81808405cd6SLois Curfman McInnes         [compute Jacobian here]
81908405cd6SLois Curfman McInnes       }
82008405cd6SLois Curfman McInnes .ve
821c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
82208405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
823c8228a4eSBarry Smith 
82436851e7fSLois Curfman McInnes    Level: intermediate
82536851e7fSLois Curfman McInnes 
8262b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
8272b668275SBarry Smith 
828b850b91aSLisandro Dalcin .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
8299b94acceSBarry Smith @*/
8307087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
8319b94acceSBarry Smith {
8323a40ed3dSBarry Smith   PetscFunctionBegin;
8330700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8344482741eSBarry Smith   PetscValidIntPointer(iter,2);
8359b94acceSBarry Smith   *iter = snes->iter;
8363a40ed3dSBarry Smith   PetscFunctionReturn(0);
8379b94acceSBarry Smith }
83874679c65SBarry Smith 
8394a2ae208SSatish Balay #undef __FUNCT__
840360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber"
841360c497dSPeter Brune /*@
842360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
843360c497dSPeter Brune 
844360c497dSPeter Brune    Not Collective
845360c497dSPeter Brune 
846360c497dSPeter Brune    Input Parameter:
847360c497dSPeter Brune .  snes - SNES context
848360c497dSPeter Brune .  iter - iteration number
849360c497dSPeter Brune 
850360c497dSPeter Brune    Level: developer
851360c497dSPeter Brune 
852360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number,
853360c497dSPeter Brune 
854360c497dSPeter Brune .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
855360c497dSPeter Brune @*/
856360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
857360c497dSPeter Brune {
858360c497dSPeter Brune   PetscErrorCode ierr;
859360c497dSPeter Brune 
860360c497dSPeter Brune   PetscFunctionBegin;
861360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
862360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
863360c497dSPeter Brune   snes->iter = iter;
864360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
865360c497dSPeter Brune   PetscFunctionReturn(0);
866360c497dSPeter Brune }
867360c497dSPeter Brune 
868360c497dSPeter Brune #undef __FUNCT__
8694a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm"
8709b94acceSBarry Smith /*@
8719b94acceSBarry Smith    SNESGetFunctionNorm - Gets the norm of the current function that was set
8729b94acceSBarry Smith    with SNESSSetFunction().
8739b94acceSBarry Smith 
874c7afd0dbSLois Curfman McInnes    Collective on SNES
875c7afd0dbSLois Curfman McInnes 
8769b94acceSBarry Smith    Input Parameter:
8779b94acceSBarry Smith .  snes - SNES context
8789b94acceSBarry Smith 
8799b94acceSBarry Smith    Output Parameter:
8809b94acceSBarry Smith .  fnorm - 2-norm of function
8819b94acceSBarry Smith 
88236851e7fSLois Curfman McInnes    Level: intermediate
88336851e7fSLois Curfman McInnes 
8849b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm
885a86d99e1SLois Curfman McInnes 
886b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
8879b94acceSBarry Smith @*/
8887087cfbeSBarry Smith PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
8899b94acceSBarry Smith {
8903a40ed3dSBarry Smith   PetscFunctionBegin;
8910700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8924482741eSBarry Smith   PetscValidScalarPointer(fnorm,2);
8939b94acceSBarry Smith   *fnorm = snes->norm;
8943a40ed3dSBarry Smith   PetscFunctionReturn(0);
8959b94acceSBarry Smith }
89674679c65SBarry Smith 
897360c497dSPeter Brune 
898360c497dSPeter Brune #undef __FUNCT__
899360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm"
900360c497dSPeter Brune /*@
901360c497dSPeter Brune    SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm().
902360c497dSPeter Brune 
903360c497dSPeter Brune    Collective on SNES
904360c497dSPeter Brune 
905360c497dSPeter Brune    Input Parameter:
906360c497dSPeter Brune .  snes - SNES context
907360c497dSPeter Brune .  fnorm - 2-norm of function
908360c497dSPeter Brune 
909360c497dSPeter Brune    Level: developer
910360c497dSPeter Brune 
911360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm
912360c497dSPeter Brune 
913360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm().
914360c497dSPeter Brune @*/
915360c497dSPeter Brune PetscErrorCode  SNESSetFunctionNorm(SNES snes,PetscReal fnorm)
916360c497dSPeter Brune {
917360c497dSPeter Brune 
918360c497dSPeter Brune   PetscErrorCode ierr;
919360c497dSPeter Brune 
920360c497dSPeter Brune   PetscFunctionBegin;
921360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
922360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
923360c497dSPeter Brune   snes->norm = fnorm;
924360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
925360c497dSPeter Brune   PetscFunctionReturn(0);
926360c497dSPeter Brune }
927360c497dSPeter Brune 
9284a2ae208SSatish Balay #undef __FUNCT__
929b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
9309b94acceSBarry Smith /*@
931b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
9329b94acceSBarry Smith    attempted by the nonlinear solver.
9339b94acceSBarry Smith 
934c7afd0dbSLois Curfman McInnes    Not Collective
935c7afd0dbSLois Curfman McInnes 
9369b94acceSBarry Smith    Input Parameter:
9379b94acceSBarry Smith .  snes - SNES context
9389b94acceSBarry Smith 
9399b94acceSBarry Smith    Output Parameter:
9409b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
9419b94acceSBarry Smith 
942c96a6f78SLois Curfman McInnes    Notes:
943c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
944c96a6f78SLois Curfman McInnes 
94536851e7fSLois Curfman McInnes    Level: intermediate
94636851e7fSLois Curfman McInnes 
9479b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
94858ebbce7SBarry Smith 
949e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
95058ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
9519b94acceSBarry Smith @*/
9527087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
9539b94acceSBarry Smith {
9543a40ed3dSBarry Smith   PetscFunctionBegin;
9550700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9564482741eSBarry Smith   PetscValidIntPointer(nfails,2);
95750ffb88aSMatthew Knepley   *nfails = snes->numFailures;
95850ffb88aSMatthew Knepley   PetscFunctionReturn(0);
95950ffb88aSMatthew Knepley }
96050ffb88aSMatthew Knepley 
96150ffb88aSMatthew Knepley #undef __FUNCT__
962b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
96350ffb88aSMatthew Knepley /*@
964b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
96550ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
96650ffb88aSMatthew Knepley 
96750ffb88aSMatthew Knepley    Not Collective
96850ffb88aSMatthew Knepley 
96950ffb88aSMatthew Knepley    Input Parameters:
97050ffb88aSMatthew Knepley +  snes     - SNES context
97150ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
97250ffb88aSMatthew Knepley 
97350ffb88aSMatthew Knepley    Level: intermediate
97450ffb88aSMatthew Knepley 
97550ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
97658ebbce7SBarry Smith 
977e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
97858ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
97950ffb88aSMatthew Knepley @*/
9807087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
98150ffb88aSMatthew Knepley {
98250ffb88aSMatthew Knepley   PetscFunctionBegin;
9830700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
98450ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
98550ffb88aSMatthew Knepley   PetscFunctionReturn(0);
98650ffb88aSMatthew Knepley }
98750ffb88aSMatthew Knepley 
98850ffb88aSMatthew Knepley #undef __FUNCT__
989b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
99050ffb88aSMatthew Knepley /*@
991b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
99250ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
99350ffb88aSMatthew Knepley 
99450ffb88aSMatthew Knepley    Not Collective
99550ffb88aSMatthew Knepley 
99650ffb88aSMatthew Knepley    Input Parameter:
99750ffb88aSMatthew Knepley .  snes     - SNES context
99850ffb88aSMatthew Knepley 
99950ffb88aSMatthew Knepley    Output Parameter:
100050ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
100150ffb88aSMatthew Knepley 
100250ffb88aSMatthew Knepley    Level: intermediate
100350ffb88aSMatthew Knepley 
100450ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
100558ebbce7SBarry Smith 
1006e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
100758ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
100858ebbce7SBarry Smith 
100950ffb88aSMatthew Knepley @*/
10107087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
101150ffb88aSMatthew Knepley {
101250ffb88aSMatthew Knepley   PetscFunctionBegin;
10130700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10144482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
101550ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
10163a40ed3dSBarry Smith   PetscFunctionReturn(0);
10179b94acceSBarry Smith }
1018a847f771SSatish Balay 
10194a2ae208SSatish Balay #undef __FUNCT__
10202541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
10212541af92SBarry Smith /*@
10222541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
10232541af92SBarry Smith      done by SNES.
10242541af92SBarry Smith 
10252541af92SBarry Smith    Not Collective
10262541af92SBarry Smith 
10272541af92SBarry Smith    Input Parameter:
10282541af92SBarry Smith .  snes     - SNES context
10292541af92SBarry Smith 
10302541af92SBarry Smith    Output Parameter:
10312541af92SBarry Smith .  nfuncs - number of evaluations
10322541af92SBarry Smith 
10332541af92SBarry Smith    Level: intermediate
10342541af92SBarry Smith 
10352541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
103658ebbce7SBarry Smith 
1037e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
10382541af92SBarry Smith @*/
10397087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
10402541af92SBarry Smith {
10412541af92SBarry Smith   PetscFunctionBegin;
10420700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10432541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
10442541af92SBarry Smith   *nfuncs = snes->nfuncs;
10452541af92SBarry Smith   PetscFunctionReturn(0);
10462541af92SBarry Smith }
10472541af92SBarry Smith 
10482541af92SBarry Smith #undef __FUNCT__
10493d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
10503d4c4710SBarry Smith /*@
10513d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
10523d4c4710SBarry Smith    linear solvers.
10533d4c4710SBarry Smith 
10543d4c4710SBarry Smith    Not Collective
10553d4c4710SBarry Smith 
10563d4c4710SBarry Smith    Input Parameter:
10573d4c4710SBarry Smith .  snes - SNES context
10583d4c4710SBarry Smith 
10593d4c4710SBarry Smith    Output Parameter:
10603d4c4710SBarry Smith .  nfails - number of failed solves
10613d4c4710SBarry Smith 
10623d4c4710SBarry Smith    Notes:
10633d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
10643d4c4710SBarry Smith 
10653d4c4710SBarry Smith    Level: intermediate
10663d4c4710SBarry Smith 
10673d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
106858ebbce7SBarry Smith 
1069e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
10703d4c4710SBarry Smith @*/
10717087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
10723d4c4710SBarry Smith {
10733d4c4710SBarry Smith   PetscFunctionBegin;
10740700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10753d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
10763d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
10773d4c4710SBarry Smith   PetscFunctionReturn(0);
10783d4c4710SBarry Smith }
10793d4c4710SBarry Smith 
10803d4c4710SBarry Smith #undef __FUNCT__
10813d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
10823d4c4710SBarry Smith /*@
10833d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
10843d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
10853d4c4710SBarry Smith 
10863f9fe445SBarry Smith    Logically Collective on SNES
10873d4c4710SBarry Smith 
10883d4c4710SBarry Smith    Input Parameters:
10893d4c4710SBarry Smith +  snes     - SNES context
10903d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
10913d4c4710SBarry Smith 
10923d4c4710SBarry Smith    Level: intermediate
10933d4c4710SBarry Smith 
1094a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
10953d4c4710SBarry Smith 
10963d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
10973d4c4710SBarry Smith 
109858ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
10993d4c4710SBarry Smith @*/
11007087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
11013d4c4710SBarry Smith {
11023d4c4710SBarry Smith   PetscFunctionBegin;
11030700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1104c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
11053d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
11063d4c4710SBarry Smith   PetscFunctionReturn(0);
11073d4c4710SBarry Smith }
11083d4c4710SBarry Smith 
11093d4c4710SBarry Smith #undef __FUNCT__
11103d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
11113d4c4710SBarry Smith /*@
11123d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
11133d4c4710SBarry Smith      are allowed before SNES terminates
11143d4c4710SBarry Smith 
11153d4c4710SBarry Smith    Not Collective
11163d4c4710SBarry Smith 
11173d4c4710SBarry Smith    Input Parameter:
11183d4c4710SBarry Smith .  snes     - SNES context
11193d4c4710SBarry Smith 
11203d4c4710SBarry Smith    Output Parameter:
11213d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
11223d4c4710SBarry Smith 
11233d4c4710SBarry Smith    Level: intermediate
11243d4c4710SBarry Smith 
11253d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
11263d4c4710SBarry Smith 
11273d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
11283d4c4710SBarry Smith 
1129e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
11303d4c4710SBarry Smith @*/
11317087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
11323d4c4710SBarry Smith {
11333d4c4710SBarry Smith   PetscFunctionBegin;
11340700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11353d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
11363d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
11373d4c4710SBarry Smith   PetscFunctionReturn(0);
11383d4c4710SBarry Smith }
11393d4c4710SBarry Smith 
11403d4c4710SBarry Smith #undef __FUNCT__
1141b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
1142c96a6f78SLois Curfman McInnes /*@
1143b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1144c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1145c96a6f78SLois Curfman McInnes 
1146c7afd0dbSLois Curfman McInnes    Not Collective
1147c7afd0dbSLois Curfman McInnes 
1148c96a6f78SLois Curfman McInnes    Input Parameter:
1149c96a6f78SLois Curfman McInnes .  snes - SNES context
1150c96a6f78SLois Curfman McInnes 
1151c96a6f78SLois Curfman McInnes    Output Parameter:
1152c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1153c96a6f78SLois Curfman McInnes 
1154c96a6f78SLois Curfman McInnes    Notes:
1155c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1156c96a6f78SLois Curfman McInnes 
115736851e7fSLois Curfman McInnes    Level: intermediate
115836851e7fSLois Curfman McInnes 
1159c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
11602b668275SBarry Smith 
11618c7482ecSBarry Smith .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
1162c96a6f78SLois Curfman McInnes @*/
11637087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
1164c96a6f78SLois Curfman McInnes {
11653a40ed3dSBarry Smith   PetscFunctionBegin;
11660700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11674482741eSBarry Smith   PetscValidIntPointer(lits,2);
1168c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
11693a40ed3dSBarry Smith   PetscFunctionReturn(0);
1170c96a6f78SLois Curfman McInnes }
1171c96a6f78SLois Curfman McInnes 
11724a2ae208SSatish Balay #undef __FUNCT__
117394b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP"
117452baeb72SSatish Balay /*@
117594b7f48cSBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
11769b94acceSBarry Smith 
117794b7f48cSBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
1178c7afd0dbSLois Curfman McInnes 
11799b94acceSBarry Smith    Input Parameter:
11809b94acceSBarry Smith .  snes - the SNES context
11819b94acceSBarry Smith 
11829b94acceSBarry Smith    Output Parameter:
118394b7f48cSBarry Smith .  ksp - the KSP context
11849b94acceSBarry Smith 
11859b94acceSBarry Smith    Notes:
118694b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
11879b94acceSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
11882999313aSBarry Smith    PC contexts as well.
11899b94acceSBarry Smith 
119036851e7fSLois Curfman McInnes    Level: beginner
119136851e7fSLois Curfman McInnes 
119294b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
11939b94acceSBarry Smith 
11942999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
11959b94acceSBarry Smith @*/
11967087cfbeSBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
11979b94acceSBarry Smith {
11981cee3971SBarry Smith   PetscErrorCode ierr;
11991cee3971SBarry Smith 
12003a40ed3dSBarry Smith   PetscFunctionBegin;
12010700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12024482741eSBarry Smith   PetscValidPointer(ksp,2);
12031cee3971SBarry Smith 
12041cee3971SBarry Smith   if (!snes->ksp) {
12051cee3971SBarry Smith     ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr);
12061cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
12071cee3971SBarry Smith     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
12081cee3971SBarry Smith   }
120994b7f48cSBarry Smith   *ksp = snes->ksp;
12103a40ed3dSBarry Smith   PetscFunctionReturn(0);
12119b94acceSBarry Smith }
121282bf6240SBarry Smith 
12134a2ae208SSatish Balay #undef __FUNCT__
12142999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
12152999313aSBarry Smith /*@
12162999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
12172999313aSBarry Smith 
12182999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
12192999313aSBarry Smith 
12202999313aSBarry Smith    Input Parameters:
12212999313aSBarry Smith +  snes - the SNES context
12222999313aSBarry Smith -  ksp - the KSP context
12232999313aSBarry Smith 
12242999313aSBarry Smith    Notes:
12252999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
12262999313aSBarry Smith    so this routine is rarely needed.
12272999313aSBarry Smith 
12282999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
12292999313aSBarry Smith    decreased by one.
12302999313aSBarry Smith 
12312999313aSBarry Smith    Level: developer
12322999313aSBarry Smith 
12332999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
12342999313aSBarry Smith 
12352999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
12362999313aSBarry Smith @*/
12377087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
12382999313aSBarry Smith {
12392999313aSBarry Smith   PetscErrorCode ierr;
12402999313aSBarry Smith 
12412999313aSBarry Smith   PetscFunctionBegin;
12420700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12430700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
12442999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
12457dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1246906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
12472999313aSBarry Smith   snes->ksp = ksp;
12482999313aSBarry Smith   PetscFunctionReturn(0);
12492999313aSBarry Smith }
12502999313aSBarry Smith 
12517adad957SLisandro Dalcin #if 0
12522999313aSBarry Smith #undef __FUNCT__
12534a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc"
12546849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
1255e24b481bSBarry Smith {
1256e24b481bSBarry Smith   PetscFunctionBegin;
1257e24b481bSBarry Smith   PetscFunctionReturn(0);
1258e24b481bSBarry Smith }
12597adad957SLisandro Dalcin #endif
1260e24b481bSBarry Smith 
12619b94acceSBarry Smith /* -----------------------------------------------------------*/
12624a2ae208SSatish Balay #undef __FUNCT__
12634a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
126452baeb72SSatish Balay /*@
12659b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
12669b94acceSBarry Smith 
1267c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1268c7afd0dbSLois Curfman McInnes 
1269c7afd0dbSLois Curfman McInnes    Input Parameters:
1270906ed7ccSBarry Smith .  comm - MPI communicator
12719b94acceSBarry Smith 
12729b94acceSBarry Smith    Output Parameter:
12739b94acceSBarry Smith .  outsnes - the new SNES context
12749b94acceSBarry Smith 
1275c7afd0dbSLois Curfman McInnes    Options Database Keys:
1276c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1277c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1278c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1279c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1280c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1281c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1282c1f60f51SBarry Smith 
128336851e7fSLois Curfman McInnes    Level: beginner
128436851e7fSLois Curfman McInnes 
12859b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
12869b94acceSBarry Smith 
1287a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1288a8054027SBarry Smith 
12899b94acceSBarry Smith @*/
12907087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
12919b94acceSBarry Smith {
1292dfbe8321SBarry Smith   PetscErrorCode      ierr;
12939b94acceSBarry Smith   SNES                snes;
1294fa9f3622SBarry Smith   SNESKSPEW           *kctx;
129537fcc0dbSBarry Smith 
12963a40ed3dSBarry Smith   PetscFunctionBegin;
1297ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
12988ba1e511SMatthew Knepley   *outsnes = PETSC_NULL;
12998ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
13008ba1e511SMatthew Knepley   ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr);
13018ba1e511SMatthew Knepley #endif
13028ba1e511SMatthew Knepley 
13033194b578SJed Brown   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
13047adad957SLisandro Dalcin 
130585385478SLisandro Dalcin   snes->ops->converged    = SNESDefaultConverged;
13062c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
130788976e71SPeter Brune   snes->tolerancesset     = PETSC_FALSE;
13089b94acceSBarry Smith   snes->max_its           = 50;
13099750a799SBarry Smith   snes->max_funcs	  = 10000;
13109b94acceSBarry Smith   snes->norm		  = 0.0;
1311b4874afaSBarry Smith   snes->rtol		  = 1.e-8;
1312b4874afaSBarry Smith   snes->ttol              = 0.0;
131370441072SBarry Smith   snes->abstol		  = 1.e-50;
1314c60f73f4SPeter Brune   snes->stol		  = 1.e-8;
13154b27c08aSLois Curfman McInnes   snes->deltatol	  = 1.e-12;
13169b94acceSBarry Smith   snes->nfuncs            = 0;
131750ffb88aSMatthew Knepley   snes->numFailures       = 0;
131850ffb88aSMatthew Knepley   snes->maxFailures       = 1;
13197a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1320e35cf81dSBarry Smith   snes->lagjacobian       = 1;
1321a8054027SBarry Smith   snes->lagpreconditioner = 1;
1322639f9d9dSBarry Smith   snes->numbermonitors    = 0;
13239b94acceSBarry Smith   snes->data              = 0;
13244dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1325186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
13266f24a144SLois Curfman McInnes   snes->nwork             = 0;
132758c9b817SLisandro Dalcin   snes->work              = 0;
132858c9b817SLisandro Dalcin   snes->nvwork            = 0;
132958c9b817SLisandro Dalcin   snes->vwork             = 0;
1330758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1331758f92a0SBarry Smith   snes->conv_hist_max     = 0;
1332758f92a0SBarry Smith   snes->conv_hist         = PETSC_NULL;
1333758f92a0SBarry Smith   snes->conv_hist_its     = PETSC_NULL;
1334758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1335184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
133689b92e6fSPeter Brune   snes->gssweeps          = 1;
13379b94acceSBarry Smith 
13383d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
13393d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
13403d4c4710SBarry Smith 
13419b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
134238f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr);
13439b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
13449b94acceSBarry Smith   kctx->version     = 2;
13459b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
13469b94acceSBarry Smith                              this was too large for some test cases */
134775567043SBarry Smith   kctx->rtol_last   = 0.0;
13489b94acceSBarry Smith   kctx->rtol_max    = .9;
13499b94acceSBarry Smith   kctx->gamma       = 1.0;
135062d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
135171f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
13529b94acceSBarry Smith   kctx->threshold   = .1;
135375567043SBarry Smith   kctx->lresid_last = 0.0;
135475567043SBarry Smith   kctx->norm_last   = 0.0;
13559b94acceSBarry Smith 
13569b94acceSBarry Smith   *outsnes = snes;
13573a40ed3dSBarry Smith   PetscFunctionReturn(0);
13589b94acceSBarry Smith }
13599b94acceSBarry Smith 
13604a2ae208SSatish Balay #undef __FUNCT__
13614a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
13629b94acceSBarry Smith /*@C
13639b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
13649b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
13659b94acceSBarry Smith    equations.
13669b94acceSBarry Smith 
13673f9fe445SBarry Smith    Logically Collective on SNES
1368fee21e36SBarry Smith 
1369c7afd0dbSLois Curfman McInnes    Input Parameters:
1370c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1371c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1372de044059SHong Zhang .  func - function evaluation routine
1373c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1374c7afd0dbSLois Curfman McInnes          function evaluation routine (may be PETSC_NULL)
13759b94acceSBarry Smith 
1376c7afd0dbSLois Curfman McInnes    Calling sequence of func:
13778d76a1e5SLois Curfman McInnes $    func (SNES snes,Vec x,Vec f,void *ctx);
1378c7afd0dbSLois Curfman McInnes 
1379c586c404SJed Brown +  snes - the SNES context
1380c586c404SJed Brown .  x - state at which to evaluate residual
1381c586c404SJed Brown .  f - vector to put residual
1382c7afd0dbSLois Curfman McInnes -  ctx - optional user-defined function context
13839b94acceSBarry Smith 
13849b94acceSBarry Smith    Notes:
13859b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
13869b94acceSBarry Smith $      f'(x) x = -f(x),
1387c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
13889b94acceSBarry Smith 
138936851e7fSLois Curfman McInnes    Level: beginner
139036851e7fSLois Curfman McInnes 
13919b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
13929b94acceSBarry Smith 
13938b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard()
13949b94acceSBarry Smith @*/
13957087cfbeSBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
13969b94acceSBarry Smith {
139785385478SLisandro Dalcin   PetscErrorCode ierr;
13986cab3a1bSJed Brown   DM             dm;
13996cab3a1bSJed Brown 
14003a40ed3dSBarry Smith   PetscFunctionBegin;
14010700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1402d2a683ecSLisandro Dalcin   if (r) {
1403d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1404d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
140585385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
14066bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
140785385478SLisandro Dalcin     snes->vec_func = r;
1408d2a683ecSLisandro Dalcin   }
14096cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
14106cab3a1bSJed Brown   ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr);
14113a40ed3dSBarry Smith   PetscFunctionReturn(0);
14129b94acceSBarry Smith }
14139b94acceSBarry Smith 
1414646217ecSPeter Brune 
1415646217ecSPeter Brune #undef __FUNCT__
1416646217ecSPeter Brune #define __FUNCT__ "SNESSetGS"
1417c79ef259SPeter Brune /*@C
1418c79ef259SPeter Brune    SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for
1419c79ef259SPeter Brune    use with composed nonlinear solvers.
1420c79ef259SPeter Brune 
1421c79ef259SPeter Brune    Input Parameters:
1422c79ef259SPeter Brune +  snes   - the SNES context
1423c79ef259SPeter Brune .  gsfunc - function evaluation routine
1424c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
1425c79ef259SPeter Brune             smoother evaluation routine (may be PETSC_NULL)
1426c79ef259SPeter Brune 
1427c79ef259SPeter Brune    Calling sequence of func:
1428c79ef259SPeter Brune $    func (SNES snes,Vec x,Vec b,void *ctx);
1429c79ef259SPeter Brune 
1430c79ef259SPeter Brune +  X   - solution vector
1431c79ef259SPeter Brune .  B   - RHS vector
1432d28543b3SPeter Brune -  ctx - optional user-defined Gauss-Seidel context
1433c79ef259SPeter Brune 
1434c79ef259SPeter Brune    Notes:
1435c79ef259SPeter Brune    The GS routines are used by the composed nonlinear solver to generate
1436c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
1437c79ef259SPeter Brune 
1438d28543b3SPeter Brune    Level: intermediate
1439c79ef259SPeter Brune 
1440d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel
1441c79ef259SPeter Brune 
1442c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS()
1443c79ef259SPeter Brune @*/
14446cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx)
14456cab3a1bSJed Brown {
14466cab3a1bSJed Brown   PetscErrorCode ierr;
14476cab3a1bSJed Brown   DM dm;
14486cab3a1bSJed Brown 
1449646217ecSPeter Brune   PetscFunctionBegin;
14506cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
14516cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
14526cab3a1bSJed Brown   ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr);
1453646217ecSPeter Brune   PetscFunctionReturn(0);
1454646217ecSPeter Brune }
1455646217ecSPeter Brune 
1456d25893d9SBarry Smith #undef __FUNCT__
145789b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps"
145889b92e6fSPeter Brune /*@
145989b92e6fSPeter Brune    SNESSetGSSweeps - Sets the number of sweeps of GS to use.
146089b92e6fSPeter Brune 
146189b92e6fSPeter Brune    Input Parameters:
146289b92e6fSPeter Brune +  snes   - the SNES context
146389b92e6fSPeter Brune -  sweeps  - the number of sweeps of GS to perform.
146489b92e6fSPeter Brune 
146589b92e6fSPeter Brune    Level: intermediate
146689b92e6fSPeter Brune 
146789b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
146889b92e6fSPeter Brune 
146989b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps()
147089b92e6fSPeter Brune @*/
147189b92e6fSPeter Brune 
147289b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) {
147389b92e6fSPeter Brune   PetscFunctionBegin;
147489b92e6fSPeter Brune   snes->gssweeps = sweeps;
147589b92e6fSPeter Brune   PetscFunctionReturn(0);
147689b92e6fSPeter Brune }
147789b92e6fSPeter Brune 
147889b92e6fSPeter Brune 
147989b92e6fSPeter Brune #undef __FUNCT__
148089b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps"
148189b92e6fSPeter Brune /*@
148289b92e6fSPeter Brune    SNESGetGSSweeps - Gets the number of sweeps GS will use.
148389b92e6fSPeter Brune 
148489b92e6fSPeter Brune    Input Parameters:
148589b92e6fSPeter Brune .  snes   - the SNES context
148689b92e6fSPeter Brune 
148789b92e6fSPeter Brune    Output Parameters:
148889b92e6fSPeter Brune .  sweeps  - the number of sweeps of GS to perform.
148989b92e6fSPeter Brune 
149089b92e6fSPeter Brune    Level: intermediate
149189b92e6fSPeter Brune 
149289b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
149389b92e6fSPeter Brune 
149489b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps()
149589b92e6fSPeter Brune @*/
149689b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) {
149789b92e6fSPeter Brune   PetscFunctionBegin;
149889b92e6fSPeter Brune   *sweeps = snes->gssweeps;
149989b92e6fSPeter Brune   PetscFunctionReturn(0);
150089b92e6fSPeter Brune }
150189b92e6fSPeter Brune 
150289b92e6fSPeter Brune #undef __FUNCT__
15038b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction"
15048b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
15058b0a5094SBarry Smith {
15068b0a5094SBarry Smith   PetscErrorCode ierr;
15076cab3a1bSJed Brown   void *functx,*jacctx;
15086cab3a1bSJed Brown 
15098b0a5094SBarry Smith   PetscFunctionBegin;
15106cab3a1bSJed Brown   ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
15116cab3a1bSJed Brown   ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr);
15128b0a5094SBarry Smith   /*  A(x)*x - b(x) */
15136cab3a1bSJed Brown   ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr);
15146cab3a1bSJed Brown   ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr);
15158b0a5094SBarry Smith   ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
15168b0a5094SBarry Smith   ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
15178b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
15188b0a5094SBarry Smith   ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr);
15198b0a5094SBarry Smith   PetscFunctionReturn(0);
15208b0a5094SBarry Smith }
15218b0a5094SBarry Smith 
15228b0a5094SBarry Smith #undef __FUNCT__
15238b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian"
15248b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
15258b0a5094SBarry Smith {
15268b0a5094SBarry Smith   PetscFunctionBegin;
15278b0a5094SBarry Smith   *flag = snes->matstruct;
15288b0a5094SBarry Smith   PetscFunctionReturn(0);
15298b0a5094SBarry Smith }
15308b0a5094SBarry Smith 
15318b0a5094SBarry Smith #undef __FUNCT__
15328b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard"
15338b0a5094SBarry Smith /*@C
15340d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
15358b0a5094SBarry Smith 
15368b0a5094SBarry Smith    Logically Collective on SNES
15378b0a5094SBarry Smith 
15388b0a5094SBarry Smith    Input Parameters:
15398b0a5094SBarry Smith +  snes - the SNES context
15408b0a5094SBarry Smith .  r - vector to store function value
15418b0a5094SBarry Smith .  func - function evaluation routine
15428b0a5094SBarry 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)
15438b0a5094SBarry Smith .  mat - matrix to store A
15448b0a5094SBarry Smith .  mfunc  - function to compute matrix value
15458b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
15468b0a5094SBarry Smith          function evaluation routine (may be PETSC_NULL)
15478b0a5094SBarry Smith 
15488b0a5094SBarry Smith    Calling sequence of func:
15498b0a5094SBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
15508b0a5094SBarry Smith 
15518b0a5094SBarry Smith +  f - function vector
15528b0a5094SBarry Smith -  ctx - optional user-defined function context
15538b0a5094SBarry Smith 
15548b0a5094SBarry Smith    Calling sequence of mfunc:
15558b0a5094SBarry Smith $     mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx);
15568b0a5094SBarry Smith 
15578b0a5094SBarry Smith +  x - input vector
15588b0a5094SBarry 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(),
15598b0a5094SBarry Smith           normally just pass mat in this location
15608b0a5094SBarry Smith .  mat - form A(x) matrix
15618b0a5094SBarry Smith .  flag - flag indicating information about the preconditioner matrix
15628b0a5094SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
15638b0a5094SBarry Smith -  ctx - [optional] user-defined Jacobian context
15648b0a5094SBarry Smith 
15658b0a5094SBarry Smith    Notes:
15668b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
15678b0a5094SBarry Smith 
15688b0a5094SBarry 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}
15698b0a5094SBarry 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.
15708b0a5094SBarry Smith 
15718b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
15728b0a5094SBarry Smith 
15730d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
15740d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
15758b0a5094SBarry Smith 
15768b0a5094SBarry 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
15778b0a5094SBarry 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
15788b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
15798b0a5094SBarry Smith 
15808b0a5094SBarry Smith    Level: beginner
15818b0a5094SBarry Smith 
15828b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function
15838b0a5094SBarry Smith 
15840d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard()
15858b0a5094SBarry Smith @*/
15868b0a5094SBarry 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)
15878b0a5094SBarry Smith {
15888b0a5094SBarry Smith   PetscErrorCode ierr;
15898b0a5094SBarry Smith   PetscFunctionBegin;
15908b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15918b0a5094SBarry Smith   snes->ops->computepfunction = func;
15928b0a5094SBarry Smith   snes->ops->computepjacobian = mfunc;
15938b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
15948b0a5094SBarry Smith   ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
15958b0a5094SBarry Smith   PetscFunctionReturn(0);
15968b0a5094SBarry Smith }
15978b0a5094SBarry Smith 
15988b0a5094SBarry Smith #undef __FUNCT__
1599d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess"
1600d25893d9SBarry Smith /*@C
1601d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1602d25893d9SBarry Smith 
1603d25893d9SBarry Smith    Logically Collective on SNES
1604d25893d9SBarry Smith 
1605d25893d9SBarry Smith    Input Parameters:
1606d25893d9SBarry Smith +  snes - the SNES context
1607d25893d9SBarry Smith .  func - function evaluation routine
1608d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
1609d25893d9SBarry Smith          function evaluation routine (may be PETSC_NULL)
1610d25893d9SBarry Smith 
1611d25893d9SBarry Smith    Calling sequence of func:
1612d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
1613d25893d9SBarry Smith 
1614d25893d9SBarry Smith .  f - function vector
1615d25893d9SBarry Smith -  ctx - optional user-defined function context
1616d25893d9SBarry Smith 
1617d25893d9SBarry Smith    Level: intermediate
1618d25893d9SBarry Smith 
1619d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
1620d25893d9SBarry Smith 
1621d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1622d25893d9SBarry Smith @*/
1623d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1624d25893d9SBarry Smith {
1625d25893d9SBarry Smith   PetscFunctionBegin;
1626d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1627d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
1628d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
1629d25893d9SBarry Smith   PetscFunctionReturn(0);
1630d25893d9SBarry Smith }
1631d25893d9SBarry Smith 
16323ab0aad5SBarry Smith /* --------------------------------------------------------------- */
16333ab0aad5SBarry Smith #undef __FUNCT__
16341096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
16351096aae1SMatthew Knepley /*@C
16361096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
16371096aae1SMatthew Knepley    it assumes a zero right hand side.
16381096aae1SMatthew Knepley 
16393f9fe445SBarry Smith    Logically Collective on SNES
16401096aae1SMatthew Knepley 
16411096aae1SMatthew Knepley    Input Parameter:
16421096aae1SMatthew Knepley .  snes - the SNES context
16431096aae1SMatthew Knepley 
16441096aae1SMatthew Knepley    Output Parameter:
1645bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
16461096aae1SMatthew Knepley 
16471096aae1SMatthew Knepley    Level: intermediate
16481096aae1SMatthew Knepley 
16491096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
16501096aae1SMatthew Knepley 
165185385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
16521096aae1SMatthew Knepley @*/
16537087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
16541096aae1SMatthew Knepley {
16551096aae1SMatthew Knepley   PetscFunctionBegin;
16560700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
16571096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
165885385478SLisandro Dalcin   *rhs = snes->vec_rhs;
16591096aae1SMatthew Knepley   PetscFunctionReturn(0);
16601096aae1SMatthew Knepley }
16611096aae1SMatthew Knepley 
16621096aae1SMatthew Knepley #undef __FUNCT__
16634a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
16649b94acceSBarry Smith /*@
166536851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
16669b94acceSBarry Smith                          SNESSetFunction().
16679b94acceSBarry Smith 
1668c7afd0dbSLois Curfman McInnes    Collective on SNES
1669c7afd0dbSLois Curfman McInnes 
16709b94acceSBarry Smith    Input Parameters:
1671c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1672c7afd0dbSLois Curfman McInnes -  x - input vector
16739b94acceSBarry Smith 
16749b94acceSBarry Smith    Output Parameter:
16753638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
16769b94acceSBarry Smith 
16771bffabb2SLois Curfman McInnes    Notes:
167836851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
167936851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
168036851e7fSLois Curfman McInnes    themselves.
168136851e7fSLois Curfman McInnes 
168236851e7fSLois Curfman McInnes    Level: developer
168336851e7fSLois Curfman McInnes 
16849b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
16859b94acceSBarry Smith 
1686a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
16879b94acceSBarry Smith @*/
16887087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
16899b94acceSBarry Smith {
1690dfbe8321SBarry Smith   PetscErrorCode ierr;
16916cab3a1bSJed Brown   DM             dm;
16926cab3a1bSJed Brown   SNESDM         sdm;
16939b94acceSBarry Smith 
16943a40ed3dSBarry Smith   PetscFunctionBegin;
16950700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
16960700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
16970700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
1698c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
1699c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
17004ec14c9cSBarry Smith   VecValidValues(x,2,PETSC_TRUE);
1701184914b5SBarry Smith 
17026cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
17036cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
1704d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
17056cab3a1bSJed Brown   if (sdm->computefunction) {
1706d64ed03dSBarry Smith     PetscStackPush("SNES user function");
17076cab3a1bSJed Brown     ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
1708d64ed03dSBarry Smith     PetscStackPop;
170973250ac0SBarry Smith   } else if (snes->dm) {
1710644e2e5bSBarry Smith     ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr);
1711c90fad12SPeter Brune   } else if (snes->vec_rhs) {
1712c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
1713644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
171485385478SLisandro Dalcin   if (snes->vec_rhs) {
171585385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
17163ab0aad5SBarry Smith   }
1717ae3c334cSLois Curfman McInnes   snes->nfuncs++;
1718d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
17194ec14c9cSBarry Smith   VecValidValues(y,3,PETSC_FALSE);
17203a40ed3dSBarry Smith   PetscFunctionReturn(0);
17219b94acceSBarry Smith }
17229b94acceSBarry Smith 
17234a2ae208SSatish Balay #undef __FUNCT__
1724646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS"
1725c79ef259SPeter Brune /*@
1726c79ef259SPeter Brune    SNESComputeGS - Calls the Gauss-Seidel function that has been set with
1727c79ef259SPeter Brune                    SNESSetGS().
1728c79ef259SPeter Brune 
1729c79ef259SPeter Brune    Collective on SNES
1730c79ef259SPeter Brune 
1731c79ef259SPeter Brune    Input Parameters:
1732c79ef259SPeter Brune +  snes - the SNES context
1733c79ef259SPeter Brune .  x - input vector
1734c79ef259SPeter Brune -  b - rhs vector
1735c79ef259SPeter Brune 
1736c79ef259SPeter Brune    Output Parameter:
1737c79ef259SPeter Brune .  x - new solution vector
1738c79ef259SPeter Brune 
1739c79ef259SPeter Brune    Notes:
1740c79ef259SPeter Brune    SNESComputeGS() is typically used within composed nonlinear solver
1741c79ef259SPeter Brune    implementations, so most users would not generally call this routine
1742c79ef259SPeter Brune    themselves.
1743c79ef259SPeter Brune 
1744c79ef259SPeter Brune    Level: developer
1745c79ef259SPeter Brune 
1746c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function
1747c79ef259SPeter Brune 
1748c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction()
1749c79ef259SPeter Brune @*/
1750646217ecSPeter Brune PetscErrorCode  SNESComputeGS(SNES snes,Vec b,Vec x)
1751646217ecSPeter Brune {
1752646217ecSPeter Brune   PetscErrorCode ierr;
175389b92e6fSPeter Brune   PetscInt i;
17546cab3a1bSJed Brown   DM dm;
17556cab3a1bSJed Brown   SNESDM sdm;
1756646217ecSPeter Brune 
1757646217ecSPeter Brune   PetscFunctionBegin;
1758646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1759646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
1760646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
1761646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
1762646217ecSPeter Brune   if(b) PetscCheckSameComm(snes,1,b,3);
17634ec14c9cSBarry Smith   if (b) VecValidValues(b,2,PETSC_TRUE);
1764701cf23dSPeter Brune   ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
17656cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
17666cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
17676cab3a1bSJed Brown   if (sdm->computegs) {
176889b92e6fSPeter Brune     for (i = 0; i < snes->gssweeps; i++) {
1769646217ecSPeter Brune       PetscStackPush("SNES user GS");
17706cab3a1bSJed Brown       ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
1771646217ecSPeter Brune       PetscStackPop;
177289b92e6fSPeter Brune     }
1773646217ecSPeter Brune   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve().");
1774701cf23dSPeter Brune   ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
17754ec14c9cSBarry Smith   VecValidValues(x,3,PETSC_FALSE);
1776646217ecSPeter Brune   PetscFunctionReturn(0);
1777646217ecSPeter Brune }
1778646217ecSPeter Brune 
1779646217ecSPeter Brune 
1780646217ecSPeter Brune #undef __FUNCT__
17814a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
178262fef451SLois Curfman McInnes /*@
178362fef451SLois Curfman McInnes    SNESComputeJacobian - Computes the Jacobian matrix that has been
178462fef451SLois Curfman McInnes    set with SNESSetJacobian().
178562fef451SLois Curfman McInnes 
1786c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
1787c7afd0dbSLois Curfman McInnes 
178862fef451SLois Curfman McInnes    Input Parameters:
1789c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1790c7afd0dbSLois Curfman McInnes -  x - input vector
179162fef451SLois Curfman McInnes 
179262fef451SLois Curfman McInnes    Output Parameters:
1793c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
179462fef451SLois Curfman McInnes .  B - optional preconditioning matrix
17952b668275SBarry Smith -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1796fee21e36SBarry Smith 
1797e35cf81dSBarry Smith   Options Database Keys:
1798e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
1799693365a8SJed Brown .    -snes_lag_jacobian <lag>
1800693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
1801693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
1802693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
18034c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
1804c01495d3SJed Brown .    -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference
1805c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
1806c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
1807c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
1808c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
18094c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
1810c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
1811c01495d3SJed Brown 
1812e35cf81dSBarry Smith 
181362fef451SLois Curfman McInnes    Notes:
181462fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
181562fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
181662fef451SLois Curfman McInnes 
181794b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the
1818dc5a77f8SLois Curfman McInnes    flag parameter.
181962fef451SLois Curfman McInnes 
182036851e7fSLois Curfman McInnes    Level: developer
182136851e7fSLois Curfman McInnes 
182262fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
182362fef451SLois Curfman McInnes 
1824e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
182562fef451SLois Curfman McInnes @*/
18267087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
18279b94acceSBarry Smith {
1828dfbe8321SBarry Smith   PetscErrorCode ierr;
1829ace3abfcSBarry Smith   PetscBool      flag;
18306cab3a1bSJed Brown   DM             dm;
18316cab3a1bSJed Brown   SNESDM         sdm;
18323a40ed3dSBarry Smith 
18333a40ed3dSBarry Smith   PetscFunctionBegin;
18340700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
18350700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
18364482741eSBarry Smith   PetscValidPointer(flg,5);
1837c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
18384ec14c9cSBarry Smith   VecValidValues(X,2,PETSC_TRUE);
18396cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
18406cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
18416cab3a1bSJed Brown   if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
1842ebd3b9afSBarry Smith 
1843ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
1844ebd3b9afSBarry Smith 
1845fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
1846fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
1847fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
1848fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
1849e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1850e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
1851ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1852ebd3b9afSBarry Smith     if (flag) {
1853ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1854ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1855ebd3b9afSBarry Smith     }
1856e35cf81dSBarry Smith     PetscFunctionReturn(0);
1857e35cf81dSBarry Smith   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
1858e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1859e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
1860ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1861ebd3b9afSBarry Smith     if (flag) {
1862ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1863ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1864ebd3b9afSBarry Smith     }
1865e35cf81dSBarry Smith     PetscFunctionReturn(0);
1866e35cf81dSBarry Smith   }
1867e35cf81dSBarry Smith 
1868c4fc05e7SBarry Smith   *flg = DIFFERENT_NONZERO_PATTERN;
1869e35cf81dSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1870d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
18716cab3a1bSJed Brown   ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr);
1872d64ed03dSBarry Smith   PetscStackPop;
1873d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1874a8054027SBarry Smith 
18753b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
18763b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
18773b4f5425SBarry Smith     snes->lagpreconditioner = -1;
18783b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
1879a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1880a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
1881a8054027SBarry Smith   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
1882a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1883a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
1884a8054027SBarry Smith   }
1885a8054027SBarry Smith 
18866d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
18870700a824SBarry Smith   /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
18880700a824SBarry Smith     PetscValidHeaderSpecific(*B,MAT_CLASSID,4);   */
1889693365a8SJed Brown   {
1890693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
1891693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr);
1892693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
1893693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
1894693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr);
1895693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
1896693365a8SJed Brown       Mat Bexp_mine = PETSC_NULL,Bexp,FDexp;
1897693365a8SJed Brown       MatStructure mstruct;
1898693365a8SJed Brown       PetscViewer vdraw,vstdout;
18996b3a5b13SJed Brown       PetscBool flg;
1900693365a8SJed Brown       if (flag_operator) {
1901693365a8SJed Brown         ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr);
1902693365a8SJed Brown         Bexp = Bexp_mine;
1903693365a8SJed Brown       } else {
1904693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
1905693365a8SJed Brown         ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
1906693365a8SJed Brown         if (flg) Bexp = *B;
1907693365a8SJed Brown         else {
1908693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
1909693365a8SJed Brown           ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr);
1910693365a8SJed Brown           Bexp = Bexp_mine;
1911693365a8SJed Brown         }
1912693365a8SJed Brown       }
1913693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
1914693365a8SJed Brown       ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr);
1915693365a8SJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
1916693365a8SJed Brown       if (flag_draw || flag_contour) {
1917693365a8SJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
1918693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
1919693365a8SJed Brown       } else vdraw = PETSC_NULL;
1920693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr);
1921693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
1922693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
1923693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
1924693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
1925693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
1926693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
1927693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
1928693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
1929693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
1930693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
1931693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
1932693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
1933693365a8SJed Brown       }
1934693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
1935693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
1936693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
1937693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
1938693365a8SJed Brown     }
1939693365a8SJed Brown   }
19404c30e9fbSJed Brown   {
19416719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
19426719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
19434c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr);
19446719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr);
19454c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
19464c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
19476719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr);
19486719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr);
19496719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr);
19506719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
19514c30e9fbSJed Brown       Mat Bfd;
19524c30e9fbSJed Brown       MatStructure mstruct;
19534c30e9fbSJed Brown       PetscViewer vdraw,vstdout;
19544c30e9fbSJed Brown       ISColoring iscoloring;
19554c30e9fbSJed Brown       MatFDColoring matfdcoloring;
19564c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
19574c30e9fbSJed Brown       void *funcctx;
19586719d8e4SJed Brown       PetscReal norm1,norm2,normmax;
19594c30e9fbSJed Brown 
19604c30e9fbSJed Brown       ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
19614c30e9fbSJed Brown       ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
19624c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
19634c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
19644c30e9fbSJed Brown 
19654c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
19664c30e9fbSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr);
19674c30e9fbSJed Brown       ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr);
19684c30e9fbSJed Brown       ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
19694c30e9fbSJed Brown       ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
19704c30e9fbSJed Brown       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
19714c30e9fbSJed Brown       ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr);
19724c30e9fbSJed Brown       ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
19734c30e9fbSJed Brown 
19744c30e9fbSJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
19754c30e9fbSJed Brown       if (flag_draw || flag_contour) {
19764c30e9fbSJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
19774c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
19784c30e9fbSJed Brown       } else vdraw = PETSC_NULL;
19794c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
19806719d8e4SJed Brown       if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);}
19814c30e9fbSJed Brown       if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);}
19824c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
19836719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
19844c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
19854c30e9fbSJed Brown       ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
19864c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
19876719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
19884c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
19896719d8e4SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr);
19906719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
19914c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
19924c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
19934c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
19944c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
19954c30e9fbSJed Brown       }
19964c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
19976719d8e4SJed Brown 
19986719d8e4SJed Brown       if (flag_threshold) {
19996719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
20006719d8e4SJed Brown         ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr);
20016719d8e4SJed Brown         ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr);
20026719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
20036719d8e4SJed Brown           const PetscScalar *ba,*ca;
20046719d8e4SJed Brown           const PetscInt *bj,*cj;
20056719d8e4SJed Brown           PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
20066719d8e4SJed Brown           PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0;
20076719d8e4SJed Brown           ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
20086719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
20096719d8e4SJed Brown           if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
20106719d8e4SJed Brown           for (j=0; j<bn; j++) {
20116719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
20126719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
20136719d8e4SJed Brown               maxentrycol = bj[j];
20146719d8e4SJed Brown               maxentry = PetscRealPart(ba[j]);
20156719d8e4SJed Brown             }
20166719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
20176719d8e4SJed Brown               maxdiffcol = bj[j];
20186719d8e4SJed Brown               maxdiff = PetscRealPart(ca[j]);
20196719d8e4SJed Brown             }
20206719d8e4SJed Brown             if (rdiff > maxrdiff) {
20216719d8e4SJed Brown               maxrdiffcol = bj[j];
20226719d8e4SJed Brown               maxrdiff = rdiff;
20236719d8e4SJed Brown             }
20246719d8e4SJed Brown           }
20256719d8e4SJed Brown           if (maxrdiff > 1) {
20266719d8e4SJed 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);
20276719d8e4SJed Brown             for (j=0; j<bn; j++) {
20286719d8e4SJed Brown               PetscReal rdiff;
20296719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
20306719d8e4SJed Brown               if (rdiff > 1) {
20316719d8e4SJed Brown                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr);
20326719d8e4SJed Brown               }
20336719d8e4SJed Brown             }
20346719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
20356719d8e4SJed Brown           }
20366719d8e4SJed Brown           ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
20376719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
20386719d8e4SJed Brown         }
20396719d8e4SJed Brown       }
20404c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
20414c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
20424c30e9fbSJed Brown     }
20434c30e9fbSJed Brown   }
20443a40ed3dSBarry Smith   PetscFunctionReturn(0);
20459b94acceSBarry Smith }
20469b94acceSBarry Smith 
20474a2ae208SSatish Balay #undef __FUNCT__
20484a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
20499b94acceSBarry Smith /*@C
20509b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2051044dda88SLois Curfman McInnes    location to store the matrix.
20529b94acceSBarry Smith 
20533f9fe445SBarry Smith    Logically Collective on SNES and Mat
2054c7afd0dbSLois Curfman McInnes 
20559b94acceSBarry Smith    Input Parameters:
2056c7afd0dbSLois Curfman McInnes +  snes - the SNES context
20579b94acceSBarry Smith .  A - Jacobian matrix
20589b94acceSBarry Smith .  B - preconditioner matrix (usually same as the Jacobian)
2059efd51863SBarry Smith .  func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value)
2060c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
2061efd51863SBarry Smith          Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value)
20629b94acceSBarry Smith 
20639b94acceSBarry Smith    Calling sequence of func:
20648d76a1e5SLois Curfman McInnes $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
20659b94acceSBarry Smith 
2066c7afd0dbSLois Curfman McInnes +  x - input vector
20679b94acceSBarry Smith .  A - Jacobian matrix
20689b94acceSBarry Smith .  B - preconditioner matrix, usually the same as A
2069ac21db08SLois Curfman McInnes .  flag - flag indicating information about the preconditioner matrix
20702b668275SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
2071c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined Jacobian context
20729b94acceSBarry Smith 
20739b94acceSBarry Smith    Notes:
207494b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the flag
20752cd2dfdcSLois Curfman McInnes    output parameter in the routine func().  Be sure to read this information!
2076ac21db08SLois Curfman McInnes 
2077ac21db08SLois Curfman McInnes    The routine func() takes Mat * as the matrix arguments rather than Mat.
20789b94acceSBarry Smith    This allows the Jacobian evaluation routine to replace A and/or B with a
20799b94acceSBarry Smith    completely new new matrix structure (not just different matrix elements)
20809b94acceSBarry Smith    when appropriate, for instance, if the nonzero structure is changing
20819b94acceSBarry Smith    throughout the global iterations.
20829b94acceSBarry Smith 
208316913363SBarry Smith    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
208416913363SBarry Smith    each matrix.
208516913363SBarry Smith 
2086a8a26c1eSJed Brown    If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument
2087a8a26c1eSJed Brown    must be a MatFDColoring.
2088a8a26c1eSJed Brown 
2089c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2090c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2091c3cc8fd1SJed Brown 
209236851e7fSLois Curfman McInnes    Level: beginner
209336851e7fSLois Curfman McInnes 
20949b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
20959b94acceSBarry Smith 
20963ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
20979b94acceSBarry Smith @*/
20987087cfbeSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
20999b94acceSBarry Smith {
2100dfbe8321SBarry Smith   PetscErrorCode ierr;
21016cab3a1bSJed Brown   DM             dm;
21023a7fca6bSBarry Smith 
21033a40ed3dSBarry Smith   PetscFunctionBegin;
21040700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
21050700a824SBarry Smith   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
21060700a824SBarry Smith   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
2107c9780b6fSBarry Smith   if (A) PetscCheckSameComm(snes,1,A,2);
210806975374SJed Brown   if (B) PetscCheckSameComm(snes,1,B,3);
21096cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
21106cab3a1bSJed Brown   ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr);
21113a7fca6bSBarry Smith   if (A) {
21127dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
21136bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
21149b94acceSBarry Smith     snes->jacobian = A;
21153a7fca6bSBarry Smith   }
21163a7fca6bSBarry Smith   if (B) {
21177dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
21186bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
21199b94acceSBarry Smith     snes->jacobian_pre = B;
21203a7fca6bSBarry Smith   }
21213a40ed3dSBarry Smith   PetscFunctionReturn(0);
21229b94acceSBarry Smith }
212362fef451SLois Curfman McInnes 
21244a2ae208SSatish Balay #undef __FUNCT__
21254a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
2126c2aafc4cSSatish Balay /*@C
2127b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2128b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2129b4fd4287SBarry Smith 
2130c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2131c7afd0dbSLois Curfman McInnes 
2132b4fd4287SBarry Smith    Input Parameter:
2133b4fd4287SBarry Smith .  snes - the nonlinear solver context
2134b4fd4287SBarry Smith 
2135b4fd4287SBarry Smith    Output Parameters:
2136c7afd0dbSLois Curfman McInnes +  A - location to stash Jacobian matrix (or PETSC_NULL)
2137b4fd4287SBarry Smith .  B - location to stash preconditioner matrix (or PETSC_NULL)
213870e92668SMatthew Knepley .  func - location to put Jacobian function (or PETSC_NULL)
213970e92668SMatthew Knepley -  ctx - location to stash Jacobian ctx (or PETSC_NULL)
2140fee21e36SBarry Smith 
214136851e7fSLois Curfman McInnes    Level: advanced
214236851e7fSLois Curfman McInnes 
2143b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian()
2144b4fd4287SBarry Smith @*/
21457087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
2146b4fd4287SBarry Smith {
21476cab3a1bSJed Brown   PetscErrorCode ierr;
21486cab3a1bSJed Brown   DM             dm;
21496cab3a1bSJed Brown   SNESDM         sdm;
21506cab3a1bSJed Brown 
21513a40ed3dSBarry Smith   PetscFunctionBegin;
21520700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2153b4fd4287SBarry Smith   if (A)    *A    = snes->jacobian;
2154b4fd4287SBarry Smith   if (B)    *B    = snes->jacobian_pre;
21556cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
21566cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
21576cab3a1bSJed Brown   if (func) *func = sdm->computejacobian;
21586cab3a1bSJed Brown   if (ctx)  *ctx  = sdm->jacobianctx;
21593a40ed3dSBarry Smith   PetscFunctionReturn(0);
2160b4fd4287SBarry Smith }
2161b4fd4287SBarry Smith 
21629b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
21639b94acceSBarry Smith 
21644a2ae208SSatish Balay #undef __FUNCT__
21654a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
21669b94acceSBarry Smith /*@
21679b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
2168272ac6f2SLois Curfman McInnes    of a nonlinear solver.
21699b94acceSBarry Smith 
2170fee21e36SBarry Smith    Collective on SNES
2171fee21e36SBarry Smith 
2172c7afd0dbSLois Curfman McInnes    Input Parameters:
217370e92668SMatthew Knepley .  snes - the SNES context
2174c7afd0dbSLois Curfman McInnes 
2175272ac6f2SLois Curfman McInnes    Notes:
2176272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
2177272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
2178272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
2179272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
2180272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
2181272ac6f2SLois Curfman McInnes 
218236851e7fSLois Curfman McInnes    Level: advanced
218336851e7fSLois Curfman McInnes 
21849b94acceSBarry Smith .keywords: SNES, nonlinear, setup
21859b94acceSBarry Smith 
21869b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
21879b94acceSBarry Smith @*/
21887087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
21899b94acceSBarry Smith {
2190dfbe8321SBarry Smith   PetscErrorCode ierr;
21916cab3a1bSJed Brown   DM             dm;
21926cab3a1bSJed Brown   SNESDM         sdm;
21933a40ed3dSBarry Smith 
21943a40ed3dSBarry Smith   PetscFunctionBegin;
21950700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
21964dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
21979b94acceSBarry Smith 
21987adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
219985385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
220085385478SLisandro Dalcin   }
220185385478SLisandro Dalcin 
2202a63bb30eSJed Brown   ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
220317186662SBarry Smith   if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
220458c9b817SLisandro Dalcin   if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
220558c9b817SLisandro Dalcin 
220658c9b817SLisandro Dalcin   if (!snes->vec_sol_update /* && snes->vec_sol */) {
220758c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
220858c9b817SLisandro Dalcin     ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr);
220958c9b817SLisandro Dalcin   }
221058c9b817SLisandro Dalcin 
22116cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
22126cab3a1bSJed Brown   ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */
22136cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
22146cab3a1bSJed Brown   if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc");
22156cab3a1bSJed Brown   if (!snes->vec_func) {
22166cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2217214df951SJed Brown   }
2218efd51863SBarry Smith 
2219b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
2220b710008aSBarry Smith 
2221f1c6b773SPeter Brune   if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);}
22229e764e56SPeter Brune 
2223d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
2224d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
2225d25893d9SBarry Smith   }
2226d25893d9SBarry Smith 
2227410397dcSLisandro Dalcin   if (snes->ops->setup) {
2228410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2229410397dcSLisandro Dalcin   }
223058c9b817SLisandro Dalcin 
22317aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
22323a40ed3dSBarry Smith   PetscFunctionReturn(0);
22339b94acceSBarry Smith }
22349b94acceSBarry Smith 
22354a2ae208SSatish Balay #undef __FUNCT__
223637596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
223737596af1SLisandro Dalcin /*@
223837596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
223937596af1SLisandro Dalcin 
224037596af1SLisandro Dalcin    Collective on SNES
224137596af1SLisandro Dalcin 
224237596af1SLisandro Dalcin    Input Parameter:
224337596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
224437596af1SLisandro Dalcin 
2245d25893d9SBarry Smith    Level: intermediate
2246d25893d9SBarry Smith 
2247d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
224837596af1SLisandro Dalcin 
224937596af1SLisandro Dalcin .keywords: SNES, destroy
225037596af1SLisandro Dalcin 
225137596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
225237596af1SLisandro Dalcin @*/
225337596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
225437596af1SLisandro Dalcin {
225537596af1SLisandro Dalcin   PetscErrorCode ierr;
225637596af1SLisandro Dalcin 
225737596af1SLisandro Dalcin   PetscFunctionBegin;
225837596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2259d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
2260d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
2261d25893d9SBarry Smith     snes->user = PETSC_NULL;
2262d25893d9SBarry Smith   }
22638a23116dSBarry Smith   if (snes->pc) {
22648a23116dSBarry Smith     ierr = SNESReset(snes->pc);CHKERRQ(ierr);
22658a23116dSBarry Smith   }
22668a23116dSBarry Smith 
226737596af1SLisandro Dalcin   if (snes->ops->reset) {
226837596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
226937596af1SLisandro Dalcin   }
22709e764e56SPeter Brune   if (snes->ksp) {
22719e764e56SPeter Brune     ierr = KSPReset(snes->ksp);CHKERRQ(ierr);
22729e764e56SPeter Brune   }
22739e764e56SPeter Brune 
22749e764e56SPeter Brune   if (snes->linesearch) {
2275f1c6b773SPeter Brune     ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr);
22769e764e56SPeter Brune   }
22779e764e56SPeter Brune 
22786bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
22796bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
22806bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
22816bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
22826bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
22836bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2284c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
2285c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
228637596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
228737596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
228837596af1SLisandro Dalcin   PetscFunctionReturn(0);
228937596af1SLisandro Dalcin }
229037596af1SLisandro Dalcin 
229137596af1SLisandro Dalcin #undef __FUNCT__
22924a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
229352baeb72SSatish Balay /*@
22949b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
22959b94acceSBarry Smith    with SNESCreate().
22969b94acceSBarry Smith 
2297c7afd0dbSLois Curfman McInnes    Collective on SNES
2298c7afd0dbSLois Curfman McInnes 
22999b94acceSBarry Smith    Input Parameter:
23009b94acceSBarry Smith .  snes - the SNES context
23019b94acceSBarry Smith 
230236851e7fSLois Curfman McInnes    Level: beginner
230336851e7fSLois Curfman McInnes 
23049b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
23059b94acceSBarry Smith 
230663a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
23079b94acceSBarry Smith @*/
23086bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
23099b94acceSBarry Smith {
23106849ba73SBarry Smith   PetscErrorCode ierr;
23113a40ed3dSBarry Smith 
23123a40ed3dSBarry Smith   PetscFunctionBegin;
23136bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
23146bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
23156bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2316d4bb536fSBarry Smith 
23176bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
23188a23116dSBarry Smith   ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr);
23196b8b9a38SLisandro Dalcin 
2320be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
23216bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
23226bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
23236d4c513bSLisandro Dalcin 
23246bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
23256bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
2326f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr);
23276b8b9a38SLisandro Dalcin 
23286bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
23296bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
23306bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
23316b8b9a38SLisandro Dalcin   }
23326bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
23336bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
23346bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
233558c9b817SLisandro Dalcin   }
23366bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2337a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
23383a40ed3dSBarry Smith  PetscFunctionReturn(0);
23399b94acceSBarry Smith }
23409b94acceSBarry Smith 
23419b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
23429b94acceSBarry Smith 
23434a2ae208SSatish Balay #undef __FUNCT__
2344a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
2345a8054027SBarry Smith /*@
2346a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2347a8054027SBarry Smith 
23483f9fe445SBarry Smith    Logically Collective on SNES
2349a8054027SBarry Smith 
2350a8054027SBarry Smith    Input Parameters:
2351a8054027SBarry Smith +  snes - the SNES context
2352a8054027SBarry 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
23533b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2354a8054027SBarry Smith 
2355a8054027SBarry Smith    Options Database Keys:
2356a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2357a8054027SBarry Smith 
2358a8054027SBarry Smith    Notes:
2359a8054027SBarry Smith    The default is 1
2360a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2361a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2362a8054027SBarry Smith 
2363a8054027SBarry Smith    Level: intermediate
2364a8054027SBarry Smith 
2365a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2366a8054027SBarry Smith 
2367e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2368a8054027SBarry Smith 
2369a8054027SBarry Smith @*/
23707087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2371a8054027SBarry Smith {
2372a8054027SBarry Smith   PetscFunctionBegin;
23730700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2374e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2375e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2376c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2377a8054027SBarry Smith   snes->lagpreconditioner = lag;
2378a8054027SBarry Smith   PetscFunctionReturn(0);
2379a8054027SBarry Smith }
2380a8054027SBarry Smith 
2381a8054027SBarry Smith #undef __FUNCT__
2382efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
2383efd51863SBarry Smith /*@
2384efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2385efd51863SBarry Smith 
2386efd51863SBarry Smith    Logically Collective on SNES
2387efd51863SBarry Smith 
2388efd51863SBarry Smith    Input Parameters:
2389efd51863SBarry Smith +  snes - the SNES context
2390efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
2391efd51863SBarry Smith 
2392efd51863SBarry Smith    Options Database Keys:
2393efd51863SBarry Smith .    -snes_grid_sequence <steps>
2394efd51863SBarry Smith 
2395efd51863SBarry Smith    Level: intermediate
2396efd51863SBarry Smith 
2397c0df2a02SJed Brown    Notes:
2398c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2399c0df2a02SJed Brown 
2400efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2401efd51863SBarry Smith 
2402efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2403efd51863SBarry Smith 
2404efd51863SBarry Smith @*/
2405efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2406efd51863SBarry Smith {
2407efd51863SBarry Smith   PetscFunctionBegin;
2408efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2409efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
2410efd51863SBarry Smith   snes->gridsequence = steps;
2411efd51863SBarry Smith   PetscFunctionReturn(0);
2412efd51863SBarry Smith }
2413efd51863SBarry Smith 
2414efd51863SBarry Smith #undef __FUNCT__
2415a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
2416a8054027SBarry Smith /*@
2417a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
2418a8054027SBarry Smith 
24193f9fe445SBarry Smith    Not Collective
2420a8054027SBarry Smith 
2421a8054027SBarry Smith    Input Parameter:
2422a8054027SBarry Smith .  snes - the SNES context
2423a8054027SBarry Smith 
2424a8054027SBarry Smith    Output Parameter:
2425a8054027SBarry 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
24263b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2427a8054027SBarry Smith 
2428a8054027SBarry Smith    Options Database Keys:
2429a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2430a8054027SBarry Smith 
2431a8054027SBarry Smith    Notes:
2432a8054027SBarry Smith    The default is 1
2433a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2434a8054027SBarry Smith 
2435a8054027SBarry Smith    Level: intermediate
2436a8054027SBarry Smith 
2437a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2438a8054027SBarry Smith 
2439a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
2440a8054027SBarry Smith 
2441a8054027SBarry Smith @*/
24427087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
2443a8054027SBarry Smith {
2444a8054027SBarry Smith   PetscFunctionBegin;
24450700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2446a8054027SBarry Smith   *lag = snes->lagpreconditioner;
2447a8054027SBarry Smith   PetscFunctionReturn(0);
2448a8054027SBarry Smith }
2449a8054027SBarry Smith 
2450a8054027SBarry Smith #undef __FUNCT__
2451e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
2452e35cf81dSBarry Smith /*@
2453e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
2454e35cf81dSBarry Smith      often the preconditioner is rebuilt.
2455e35cf81dSBarry Smith 
24563f9fe445SBarry Smith    Logically Collective on SNES
2457e35cf81dSBarry Smith 
2458e35cf81dSBarry Smith    Input Parameters:
2459e35cf81dSBarry Smith +  snes - the SNES context
2460e35cf81dSBarry 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
2461fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
2462e35cf81dSBarry Smith 
2463e35cf81dSBarry Smith    Options Database Keys:
2464e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2465e35cf81dSBarry Smith 
2466e35cf81dSBarry Smith    Notes:
2467e35cf81dSBarry Smith    The default is 1
2468e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2469fe3ffe1eSBarry 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
2470fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
2471e35cf81dSBarry Smith 
2472e35cf81dSBarry Smith    Level: intermediate
2473e35cf81dSBarry Smith 
2474e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2475e35cf81dSBarry Smith 
2476e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
2477e35cf81dSBarry Smith 
2478e35cf81dSBarry Smith @*/
24797087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
2480e35cf81dSBarry Smith {
2481e35cf81dSBarry Smith   PetscFunctionBegin;
24820700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2483e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2484e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2485c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2486e35cf81dSBarry Smith   snes->lagjacobian = lag;
2487e35cf81dSBarry Smith   PetscFunctionReturn(0);
2488e35cf81dSBarry Smith }
2489e35cf81dSBarry Smith 
2490e35cf81dSBarry Smith #undef __FUNCT__
2491e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
2492e35cf81dSBarry Smith /*@
2493e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
2494e35cf81dSBarry Smith 
24953f9fe445SBarry Smith    Not Collective
2496e35cf81dSBarry Smith 
2497e35cf81dSBarry Smith    Input Parameter:
2498e35cf81dSBarry Smith .  snes - the SNES context
2499e35cf81dSBarry Smith 
2500e35cf81dSBarry Smith    Output Parameter:
2501e35cf81dSBarry 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
2502e35cf81dSBarry Smith          the Jacobian is built etc.
2503e35cf81dSBarry Smith 
2504e35cf81dSBarry Smith    Options Database Keys:
2505e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2506e35cf81dSBarry Smith 
2507e35cf81dSBarry Smith    Notes:
2508e35cf81dSBarry Smith    The default is 1
2509e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2510e35cf81dSBarry Smith 
2511e35cf81dSBarry Smith    Level: intermediate
2512e35cf81dSBarry Smith 
2513e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2514e35cf81dSBarry Smith 
2515e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
2516e35cf81dSBarry Smith 
2517e35cf81dSBarry Smith @*/
25187087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
2519e35cf81dSBarry Smith {
2520e35cf81dSBarry Smith   PetscFunctionBegin;
25210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2522e35cf81dSBarry Smith   *lag = snes->lagjacobian;
2523e35cf81dSBarry Smith   PetscFunctionReturn(0);
2524e35cf81dSBarry Smith }
2525e35cf81dSBarry Smith 
2526e35cf81dSBarry Smith #undef __FUNCT__
25274a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
25289b94acceSBarry Smith /*@
2529d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
25309b94acceSBarry Smith 
25313f9fe445SBarry Smith    Logically Collective on SNES
2532c7afd0dbSLois Curfman McInnes 
25339b94acceSBarry Smith    Input Parameters:
2534c7afd0dbSLois Curfman McInnes +  snes - the SNES context
253570441072SBarry Smith .  abstol - absolute convergence tolerance
253633174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
253733174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
253833174efeSLois Curfman McInnes            of the change in the solution between steps
253933174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2540c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2541fee21e36SBarry Smith 
254233174efeSLois Curfman McInnes    Options Database Keys:
254370441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
2544c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
2545c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
2546c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
2547c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
25489b94acceSBarry Smith 
2549d7a720efSLois Curfman McInnes    Notes:
25509b94acceSBarry Smith    The default maximum number of iterations is 50.
25519b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
25529b94acceSBarry Smith 
255336851e7fSLois Curfman McInnes    Level: intermediate
255436851e7fSLois Curfman McInnes 
255533174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
25569b94acceSBarry Smith 
25572492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
25589b94acceSBarry Smith @*/
25597087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
25609b94acceSBarry Smith {
25613a40ed3dSBarry Smith   PetscFunctionBegin;
25620700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2563c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
2564c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
2565c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
2566c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
2567c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
2568c5eb9154SBarry Smith 
2569ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
2570ab54825eSJed Brown     if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol);
2571ab54825eSJed Brown     snes->abstol = abstol;
2572ab54825eSJed Brown   }
2573ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
2574ab54825eSJed 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);
2575ab54825eSJed Brown     snes->rtol = rtol;
2576ab54825eSJed Brown   }
2577ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
2578ab54825eSJed Brown     if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol);
2579c60f73f4SPeter Brune     snes->stol = stol;
2580ab54825eSJed Brown   }
2581ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
2582ab54825eSJed Brown     if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
2583ab54825eSJed Brown     snes->max_its = maxit;
2584ab54825eSJed Brown   }
2585ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
2586ab54825eSJed Brown     if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
2587ab54825eSJed Brown     snes->max_funcs = maxf;
2588ab54825eSJed Brown   }
258988976e71SPeter Brune   snes->tolerancesset = PETSC_TRUE;
25903a40ed3dSBarry Smith   PetscFunctionReturn(0);
25919b94acceSBarry Smith }
25929b94acceSBarry Smith 
25934a2ae208SSatish Balay #undef __FUNCT__
25944a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
25959b94acceSBarry Smith /*@
259633174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
259733174efeSLois Curfman McInnes 
2598c7afd0dbSLois Curfman McInnes    Not Collective
2599c7afd0dbSLois Curfman McInnes 
260033174efeSLois Curfman McInnes    Input Parameters:
2601c7afd0dbSLois Curfman McInnes +  snes - the SNES context
260285385478SLisandro Dalcin .  atol - absolute convergence tolerance
260333174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
260433174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
260533174efeSLois Curfman McInnes            of the change in the solution between steps
260633174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2607c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2608fee21e36SBarry Smith 
260933174efeSLois Curfman McInnes    Notes:
261033174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
261133174efeSLois Curfman McInnes 
261236851e7fSLois Curfman McInnes    Level: intermediate
261336851e7fSLois Curfman McInnes 
261433174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
261533174efeSLois Curfman McInnes 
261633174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
261733174efeSLois Curfman McInnes @*/
26187087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
261933174efeSLois Curfman McInnes {
26203a40ed3dSBarry Smith   PetscFunctionBegin;
26210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
262285385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
262333174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
2624c60f73f4SPeter Brune   if (stol)  *stol  = snes->stol;
262533174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
262633174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
26273a40ed3dSBarry Smith   PetscFunctionReturn(0);
262833174efeSLois Curfman McInnes }
262933174efeSLois Curfman McInnes 
26304a2ae208SSatish Balay #undef __FUNCT__
26314a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
263233174efeSLois Curfman McInnes /*@
26339b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
26349b94acceSBarry Smith 
26353f9fe445SBarry Smith    Logically Collective on SNES
2636fee21e36SBarry Smith 
2637c7afd0dbSLois Curfman McInnes    Input Parameters:
2638c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2639c7afd0dbSLois Curfman McInnes -  tol - tolerance
2640c7afd0dbSLois Curfman McInnes 
26419b94acceSBarry Smith    Options Database Key:
2642c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
26439b94acceSBarry Smith 
264436851e7fSLois Curfman McInnes    Level: intermediate
264536851e7fSLois Curfman McInnes 
26469b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
26479b94acceSBarry Smith 
26482492ecdbSBarry Smith .seealso: SNESSetTolerances()
26499b94acceSBarry Smith @*/
26507087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
26519b94acceSBarry Smith {
26523a40ed3dSBarry Smith   PetscFunctionBegin;
26530700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2654c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
26559b94acceSBarry Smith   snes->deltatol = tol;
26563a40ed3dSBarry Smith   PetscFunctionReturn(0);
26579b94acceSBarry Smith }
26589b94acceSBarry Smith 
2659df9fa365SBarry Smith /*
2660df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
2661df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
2662df9fa365SBarry Smith    macros instead of functions
2663df9fa365SBarry Smith */
26644a2ae208SSatish Balay #undef __FUNCT__
2665a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
26667087cfbeSBarry Smith PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2667ce1608b8SBarry Smith {
2668dfbe8321SBarry Smith   PetscErrorCode ierr;
2669ce1608b8SBarry Smith 
2670ce1608b8SBarry Smith   PetscFunctionBegin;
26710700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2672a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
2673ce1608b8SBarry Smith   PetscFunctionReturn(0);
2674ce1608b8SBarry Smith }
2675ce1608b8SBarry Smith 
26764a2ae208SSatish Balay #undef __FUNCT__
2677a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
26787087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2679df9fa365SBarry Smith {
2680dfbe8321SBarry Smith   PetscErrorCode ierr;
2681df9fa365SBarry Smith 
2682df9fa365SBarry Smith   PetscFunctionBegin;
2683a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2684df9fa365SBarry Smith   PetscFunctionReturn(0);
2685df9fa365SBarry Smith }
2686df9fa365SBarry Smith 
26874a2ae208SSatish Balay #undef __FUNCT__
2688a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
26896bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
2690df9fa365SBarry Smith {
2691dfbe8321SBarry Smith   PetscErrorCode ierr;
2692df9fa365SBarry Smith 
2693df9fa365SBarry Smith   PetscFunctionBegin;
2694a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2695df9fa365SBarry Smith   PetscFunctionReturn(0);
2696df9fa365SBarry Smith }
2697df9fa365SBarry Smith 
26987087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
2699b271bb04SBarry Smith #undef __FUNCT__
2700b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
27017087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2702b271bb04SBarry Smith {
2703b271bb04SBarry Smith   PetscDrawLG      lg;
2704b271bb04SBarry Smith   PetscErrorCode   ierr;
2705b271bb04SBarry Smith   PetscReal        x,y,per;
2706b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
2707b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
2708b271bb04SBarry Smith   PetscDraw        draw;
2709b271bb04SBarry Smith   PetscFunctionBegin;
2710b271bb04SBarry Smith   if (!monctx) {
2711b271bb04SBarry Smith     MPI_Comm    comm;
2712b271bb04SBarry Smith 
2713b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2714b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
2715b271bb04SBarry Smith   }
2716b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
2717b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2718b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2719b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
2720b271bb04SBarry Smith   x = (PetscReal) n;
2721b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
2722b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2723b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2724b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2725b271bb04SBarry Smith   }
2726b271bb04SBarry Smith 
2727b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
2728b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2729b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2730b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
2731b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
2732b271bb04SBarry Smith   x = (PetscReal) n;
2733b271bb04SBarry Smith   y = 100.0*per;
2734b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2735b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2736b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2737b271bb04SBarry Smith   }
2738b271bb04SBarry Smith 
2739b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
2740b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2741b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2742b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
2743b271bb04SBarry Smith   x = (PetscReal) n;
2744b271bb04SBarry Smith   y = (prev - rnorm)/prev;
2745b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2746b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2747b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2748b271bb04SBarry Smith   }
2749b271bb04SBarry Smith 
2750b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
2751b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2752b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2753b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
2754b271bb04SBarry Smith   x = (PetscReal) n;
2755b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
2756b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
2757b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2758b271bb04SBarry Smith   }
2759b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2760b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2761b271bb04SBarry Smith   }
2762b271bb04SBarry Smith   prev = rnorm;
2763b271bb04SBarry Smith   PetscFunctionReturn(0);
2764b271bb04SBarry Smith }
2765b271bb04SBarry Smith 
2766b271bb04SBarry Smith #undef __FUNCT__
2767b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
27687087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2769b271bb04SBarry Smith {
2770b271bb04SBarry Smith   PetscErrorCode ierr;
2771b271bb04SBarry Smith 
2772b271bb04SBarry Smith   PetscFunctionBegin;
2773b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2774b271bb04SBarry Smith   PetscFunctionReturn(0);
2775b271bb04SBarry Smith }
2776b271bb04SBarry Smith 
2777b271bb04SBarry Smith #undef __FUNCT__
2778b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
27796bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG *draw)
2780b271bb04SBarry Smith {
2781b271bb04SBarry Smith   PetscErrorCode ierr;
2782b271bb04SBarry Smith 
2783b271bb04SBarry Smith   PetscFunctionBegin;
2784b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2785b271bb04SBarry Smith   PetscFunctionReturn(0);
2786b271bb04SBarry Smith }
2787b271bb04SBarry Smith 
27887a03ce2fSLisandro Dalcin #undef __FUNCT__
27897a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
2790228d79bcSJed Brown /*@
2791228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
2792228d79bcSJed Brown 
2793228d79bcSJed Brown    Collective on SNES
2794228d79bcSJed Brown 
2795228d79bcSJed Brown    Input Parameters:
2796228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
2797228d79bcSJed Brown .  iter - iteration number
2798228d79bcSJed Brown -  rnorm - relative norm of the residual
2799228d79bcSJed Brown 
2800228d79bcSJed Brown    Notes:
2801228d79bcSJed Brown    This routine is called by the SNES implementations.
2802228d79bcSJed Brown    It does not typically need to be called by the user.
2803228d79bcSJed Brown 
2804228d79bcSJed Brown    Level: developer
2805228d79bcSJed Brown 
2806228d79bcSJed Brown .seealso: SNESMonitorSet()
2807228d79bcSJed Brown @*/
28087a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
28097a03ce2fSLisandro Dalcin {
28107a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
28117a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
28127a03ce2fSLisandro Dalcin 
28137a03ce2fSLisandro Dalcin   PetscFunctionBegin;
28147a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
28157a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
28167a03ce2fSLisandro Dalcin   }
28177a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
28187a03ce2fSLisandro Dalcin }
28197a03ce2fSLisandro Dalcin 
28209b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
28219b94acceSBarry Smith 
28224a2ae208SSatish Balay #undef __FUNCT__
2823a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
28249b94acceSBarry Smith /*@C
2825a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
28269b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
28279b94acceSBarry Smith    progress.
28289b94acceSBarry Smith 
28293f9fe445SBarry Smith    Logically Collective on SNES
2830fee21e36SBarry Smith 
2831c7afd0dbSLois Curfman McInnes    Input Parameters:
2832c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2833c7afd0dbSLois Curfman McInnes .  func - monitoring routine
2834b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
2835e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
2836b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
2837b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
28389b94acceSBarry Smith 
2839c7afd0dbSLois Curfman McInnes    Calling sequence of func:
2840a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
2841c7afd0dbSLois Curfman McInnes 
2842c7afd0dbSLois Curfman McInnes +    snes - the SNES context
2843c7afd0dbSLois Curfman McInnes .    its - iteration number
2844c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
284540a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
28469b94acceSBarry Smith 
28479665c990SLois Curfman McInnes    Options Database Keys:
2848a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
2849a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
2850a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
2851cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
2852c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
2853a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
2854c7afd0dbSLois Curfman McInnes                             does not cancel those set via
2855c7afd0dbSLois Curfman McInnes                             the options database.
28569665c990SLois Curfman McInnes 
2857639f9d9dSBarry Smith    Notes:
28586bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
2859a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
28606bc08f3fSLois Curfman McInnes    order in which they were set.
2861639f9d9dSBarry Smith 
2862025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
2863025f1a04SBarry Smith 
286436851e7fSLois Curfman McInnes    Level: intermediate
286536851e7fSLois Curfman McInnes 
28669b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
28679b94acceSBarry Smith 
2868a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
28699b94acceSBarry Smith @*/
2870c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
28719b94acceSBarry Smith {
2872b90d0a6eSBarry Smith   PetscInt       i;
2873649052a6SBarry Smith   PetscErrorCode ierr;
2874b90d0a6eSBarry Smith 
28753a40ed3dSBarry Smith   PetscFunctionBegin;
28760700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
287717186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
2878b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
2879649052a6SBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
2880649052a6SBarry Smith       if (monitordestroy) {
2881c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
2882649052a6SBarry Smith       }
2883b90d0a6eSBarry Smith       PetscFunctionReturn(0);
2884b90d0a6eSBarry Smith     }
2885b90d0a6eSBarry Smith   }
2886b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
2887b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
2888639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
28893a40ed3dSBarry Smith   PetscFunctionReturn(0);
28909b94acceSBarry Smith }
28919b94acceSBarry Smith 
28924a2ae208SSatish Balay #undef __FUNCT__
2893a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
28945cd90555SBarry Smith /*@C
2895a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
28965cd90555SBarry Smith 
28973f9fe445SBarry Smith    Logically Collective on SNES
2898c7afd0dbSLois Curfman McInnes 
28995cd90555SBarry Smith    Input Parameters:
29005cd90555SBarry Smith .  snes - the SNES context
29015cd90555SBarry Smith 
29021a480d89SAdministrator    Options Database Key:
2903a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
2904a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
2905c7afd0dbSLois Curfman McInnes     set via the options database
29065cd90555SBarry Smith 
29075cd90555SBarry Smith    Notes:
29085cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
29095cd90555SBarry Smith 
291036851e7fSLois Curfman McInnes    Level: intermediate
291136851e7fSLois Curfman McInnes 
29125cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
29135cd90555SBarry Smith 
2914a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
29155cd90555SBarry Smith @*/
29167087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
29175cd90555SBarry Smith {
2918d952e501SBarry Smith   PetscErrorCode ierr;
2919d952e501SBarry Smith   PetscInt       i;
2920d952e501SBarry Smith 
29215cd90555SBarry Smith   PetscFunctionBegin;
29220700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2923d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
2924d952e501SBarry Smith     if (snes->monitordestroy[i]) {
29253c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
2926d952e501SBarry Smith     }
2927d952e501SBarry Smith   }
29285cd90555SBarry Smith   snes->numbermonitors = 0;
29295cd90555SBarry Smith   PetscFunctionReturn(0);
29305cd90555SBarry Smith }
29315cd90555SBarry Smith 
29324a2ae208SSatish Balay #undef __FUNCT__
29334a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
29349b94acceSBarry Smith /*@C
29359b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
29369b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
29379b94acceSBarry Smith 
29383f9fe445SBarry Smith    Logically Collective on SNES
2939fee21e36SBarry Smith 
2940c7afd0dbSLois Curfman McInnes    Input Parameters:
2941c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2942c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
29437f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
29447f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
29459b94acceSBarry Smith 
2946c7afd0dbSLois Curfman McInnes    Calling sequence of func:
294706ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
2948c7afd0dbSLois Curfman McInnes 
2949c7afd0dbSLois Curfman McInnes +    snes - the SNES context
295006ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
2951c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
2952184914b5SBarry Smith .    reason - reason for convergence/divergence
2953c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
29544b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
29554b27c08aSLois Curfman McInnes -    f - 2-norm of function
29569b94acceSBarry Smith 
295736851e7fSLois Curfman McInnes    Level: advanced
295836851e7fSLois Curfman McInnes 
29599b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
29609b94acceSBarry Smith 
296185385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
29629b94acceSBarry Smith @*/
29637087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
29649b94acceSBarry Smith {
29657f7931b9SBarry Smith   PetscErrorCode ierr;
29667f7931b9SBarry Smith 
29673a40ed3dSBarry Smith   PetscFunctionBegin;
29680700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
296985385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
29707f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
29717f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
29727f7931b9SBarry Smith   }
297385385478SLisandro Dalcin   snes->ops->converged        = func;
29747f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
297585385478SLisandro Dalcin   snes->cnvP                  = cctx;
29763a40ed3dSBarry Smith   PetscFunctionReturn(0);
29779b94acceSBarry Smith }
29789b94acceSBarry Smith 
29794a2ae208SSatish Balay #undef __FUNCT__
29804a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
298152baeb72SSatish Balay /*@
2982184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
2983184914b5SBarry Smith 
2984184914b5SBarry Smith    Not Collective
2985184914b5SBarry Smith 
2986184914b5SBarry Smith    Input Parameter:
2987184914b5SBarry Smith .  snes - the SNES context
2988184914b5SBarry Smith 
2989184914b5SBarry Smith    Output Parameter:
29904d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
2991184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
2992184914b5SBarry Smith 
2993184914b5SBarry Smith    Level: intermediate
2994184914b5SBarry Smith 
2995184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
2996184914b5SBarry Smith 
2997184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
2998184914b5SBarry Smith 
299985385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
3000184914b5SBarry Smith @*/
30017087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
3002184914b5SBarry Smith {
3003184914b5SBarry Smith   PetscFunctionBegin;
30040700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
30054482741eSBarry Smith   PetscValidPointer(reason,2);
3006184914b5SBarry Smith   *reason = snes->reason;
3007184914b5SBarry Smith   PetscFunctionReturn(0);
3008184914b5SBarry Smith }
3009184914b5SBarry Smith 
30104a2ae208SSatish Balay #undef __FUNCT__
30114a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
3012c9005455SLois Curfman McInnes /*@
3013c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
3014c9005455SLois Curfman McInnes 
30153f9fe445SBarry Smith    Logically Collective on SNES
3016fee21e36SBarry Smith 
3017c7afd0dbSLois Curfman McInnes    Input Parameters:
3018c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
30198c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
3020cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
3021758f92a0SBarry Smith .  na  - size of a and its
302264731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
3023758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
3024c7afd0dbSLois Curfman McInnes 
3025308dcc3eSBarry Smith    Notes:
3026308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
3027308dcc3eSBarry Smith    default array of length 10000 is allocated.
3028308dcc3eSBarry Smith 
3029c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
3030c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
3031c9005455SLois Curfman McInnes    during the section of code that is being timed.
3032c9005455SLois Curfman McInnes 
303336851e7fSLois Curfman McInnes    Level: intermediate
303436851e7fSLois Curfman McInnes 
3035c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
3036758f92a0SBarry Smith 
303708405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
3038758f92a0SBarry Smith 
3039c9005455SLois Curfman McInnes @*/
30407087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
3041c9005455SLois Curfman McInnes {
3042308dcc3eSBarry Smith   PetscErrorCode ierr;
3043308dcc3eSBarry Smith 
30443a40ed3dSBarry Smith   PetscFunctionBegin;
30450700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
30464482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
3047a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
3048308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
3049308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
3050308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
3051308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
3052308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
3053308dcc3eSBarry Smith   }
3054c9005455SLois Curfman McInnes   snes->conv_hist       = a;
3055758f92a0SBarry Smith   snes->conv_hist_its   = its;
3056758f92a0SBarry Smith   snes->conv_hist_max   = na;
3057a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
3058758f92a0SBarry Smith   snes->conv_hist_reset = reset;
3059758f92a0SBarry Smith   PetscFunctionReturn(0);
3060758f92a0SBarry Smith }
3061758f92a0SBarry Smith 
3062308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3063c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
3064c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
3065308dcc3eSBarry Smith EXTERN_C_BEGIN
3066308dcc3eSBarry Smith #undef __FUNCT__
3067308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
3068308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
3069308dcc3eSBarry Smith {
3070308dcc3eSBarry Smith   mxArray        *mat;
3071308dcc3eSBarry Smith   PetscInt       i;
3072308dcc3eSBarry Smith   PetscReal      *ar;
3073308dcc3eSBarry Smith 
3074308dcc3eSBarry Smith   PetscFunctionBegin;
3075308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
3076308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
3077308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
3078308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
3079308dcc3eSBarry Smith   }
3080308dcc3eSBarry Smith   PetscFunctionReturn(mat);
3081308dcc3eSBarry Smith }
3082308dcc3eSBarry Smith EXTERN_C_END
3083308dcc3eSBarry Smith #endif
3084308dcc3eSBarry Smith 
3085308dcc3eSBarry Smith 
30864a2ae208SSatish Balay #undef __FUNCT__
30874a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
30880c4c9dddSBarry Smith /*@C
3089758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
3090758f92a0SBarry Smith 
30913f9fe445SBarry Smith    Not Collective
3092758f92a0SBarry Smith 
3093758f92a0SBarry Smith    Input Parameter:
3094758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
3095758f92a0SBarry Smith 
3096758f92a0SBarry Smith    Output Parameters:
3097758f92a0SBarry Smith .  a   - array to hold history
3098758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
3099758f92a0SBarry Smith          negative if not converged) for each solve.
3100758f92a0SBarry Smith -  na  - size of a and its
3101758f92a0SBarry Smith 
3102758f92a0SBarry Smith    Notes:
3103758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
3104758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
3105758f92a0SBarry Smith 
3106758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
3107758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
3108758f92a0SBarry Smith    during the section of code that is being timed.
3109758f92a0SBarry Smith 
3110758f92a0SBarry Smith    Level: intermediate
3111758f92a0SBarry Smith 
3112758f92a0SBarry Smith .keywords: SNES, get, convergence, history
3113758f92a0SBarry Smith 
3114758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
3115758f92a0SBarry Smith 
3116758f92a0SBarry Smith @*/
31177087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3118758f92a0SBarry Smith {
3119758f92a0SBarry Smith   PetscFunctionBegin;
31200700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3121758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
3122758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
3123758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
31243a40ed3dSBarry Smith   PetscFunctionReturn(0);
3125c9005455SLois Curfman McInnes }
3126c9005455SLois Curfman McInnes 
3127e74ef692SMatthew Knepley #undef __FUNCT__
3128e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
3129ac226902SBarry Smith /*@C
313076b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
3131eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
31327e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
313376b2cf59SMatthew Knepley 
31343f9fe445SBarry Smith   Logically Collective on SNES
313576b2cf59SMatthew Knepley 
313676b2cf59SMatthew Knepley   Input Parameters:
313776b2cf59SMatthew Knepley . snes - The nonlinear solver context
313876b2cf59SMatthew Knepley . func - The function
313976b2cf59SMatthew Knepley 
314076b2cf59SMatthew Knepley   Calling sequence of func:
3141b5d30489SBarry Smith . func (SNES snes, PetscInt step);
314276b2cf59SMatthew Knepley 
314376b2cf59SMatthew Knepley . step - The current step of the iteration
314476b2cf59SMatthew Knepley 
3145fe97e370SBarry Smith   Level: advanced
3146fe97e370SBarry Smith 
3147fe97e370SBarry 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()
3148fe97e370SBarry Smith         This is not used by most users.
314976b2cf59SMatthew Knepley 
315076b2cf59SMatthew Knepley .keywords: SNES, update
3151b5d30489SBarry Smith 
315285385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
315376b2cf59SMatthew Knepley @*/
31547087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
315576b2cf59SMatthew Knepley {
315676b2cf59SMatthew Knepley   PetscFunctionBegin;
31570700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
3158e7788613SBarry Smith   snes->ops->update = func;
315976b2cf59SMatthew Knepley   PetscFunctionReturn(0);
316076b2cf59SMatthew Knepley }
316176b2cf59SMatthew Knepley 
3162e74ef692SMatthew Knepley #undef __FUNCT__
3163e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
316476b2cf59SMatthew Knepley /*@
316576b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
316676b2cf59SMatthew Knepley 
316776b2cf59SMatthew Knepley   Not collective
316876b2cf59SMatthew Knepley 
316976b2cf59SMatthew Knepley   Input Parameters:
317076b2cf59SMatthew Knepley . snes - The nonlinear solver context
317176b2cf59SMatthew Knepley . step - The current step of the iteration
317276b2cf59SMatthew Knepley 
3173205452f4SMatthew Knepley   Level: intermediate
3174205452f4SMatthew Knepley 
317576b2cf59SMatthew Knepley .keywords: SNES, update
3176a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
317776b2cf59SMatthew Knepley @*/
31787087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
317976b2cf59SMatthew Knepley {
318076b2cf59SMatthew Knepley   PetscFunctionBegin;
318176b2cf59SMatthew Knepley   PetscFunctionReturn(0);
318276b2cf59SMatthew Knepley }
318376b2cf59SMatthew Knepley 
31844a2ae208SSatish Balay #undef __FUNCT__
31854a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
31869b94acceSBarry Smith /*
31879b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
31889b94acceSBarry Smith    positive parameter delta.
31899b94acceSBarry Smith 
31909b94acceSBarry Smith     Input Parameters:
3191c7afd0dbSLois Curfman McInnes +   snes - the SNES context
31929b94acceSBarry Smith .   y - approximate solution of linear system
31939b94acceSBarry Smith .   fnorm - 2-norm of current function
3194c7afd0dbSLois Curfman McInnes -   delta - trust region size
31959b94acceSBarry Smith 
31969b94acceSBarry Smith     Output Parameters:
3197c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
31989b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
31999b94acceSBarry Smith     region, and exceeds zero otherwise.
3200c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
32019b94acceSBarry Smith 
32029b94acceSBarry Smith     Note:
32034b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
32049b94acceSBarry Smith     is set to be the maximum allowable step size.
32059b94acceSBarry Smith 
32069b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
32079b94acceSBarry Smith */
3208dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
32099b94acceSBarry Smith {
3210064f8208SBarry Smith   PetscReal      nrm;
3211ea709b57SSatish Balay   PetscScalar    cnorm;
3212dfbe8321SBarry Smith   PetscErrorCode ierr;
32133a40ed3dSBarry Smith 
32143a40ed3dSBarry Smith   PetscFunctionBegin;
32150700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
32160700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3217c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
3218184914b5SBarry Smith 
3219064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
3220064f8208SBarry Smith   if (nrm > *delta) {
3221064f8208SBarry Smith      nrm = *delta/nrm;
3222064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
3223064f8208SBarry Smith      cnorm = nrm;
32242dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
32259b94acceSBarry Smith      *ynorm = *delta;
32269b94acceSBarry Smith   } else {
32279b94acceSBarry Smith      *gpnorm = 0.0;
3228064f8208SBarry Smith      *ynorm = nrm;
32299b94acceSBarry Smith   }
32303a40ed3dSBarry Smith   PetscFunctionReturn(0);
32319b94acceSBarry Smith }
32329b94acceSBarry Smith 
32334a2ae208SSatish Balay #undef __FUNCT__
32344a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
32356ce558aeSBarry Smith /*@C
3236f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
3237f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
32389b94acceSBarry Smith 
3239c7afd0dbSLois Curfman McInnes    Collective on SNES
3240c7afd0dbSLois Curfman McInnes 
3241b2002411SLois Curfman McInnes    Input Parameters:
3242c7afd0dbSLois Curfman McInnes +  snes - the SNES context
32433cebf274SJed Brown .  b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero.
324485385478SLisandro Dalcin -  x - the solution vector.
32459b94acceSBarry Smith 
3246b2002411SLois Curfman McInnes    Notes:
32478ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
32488ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
32498ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
32508ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
32518ddd3da0SLois Curfman McInnes 
325236851e7fSLois Curfman McInnes    Level: beginner
325336851e7fSLois Curfman McInnes 
32549b94acceSBarry Smith .keywords: SNES, nonlinear, solve
32559b94acceSBarry Smith 
3256c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
32579b94acceSBarry Smith @*/
32587087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
32599b94acceSBarry Smith {
3260dfbe8321SBarry Smith   PetscErrorCode ierr;
3261ace3abfcSBarry Smith   PetscBool      flg;
3262eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
3263eabae89aSBarry Smith   PetscViewer    viewer;
3264efd51863SBarry Smith   PetscInt       grid;
3265a69afd8bSBarry Smith   Vec            xcreated = PETSC_NULL;
3266caa4e7f2SJed Brown   DM             dm;
3267052efed2SBarry Smith 
32683a40ed3dSBarry Smith   PetscFunctionBegin;
32690700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3270a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3271a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
32720700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
327385385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
327485385478SLisandro Dalcin 
3275caa4e7f2SJed Brown   if (!x) {
3276caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3277caa4e7f2SJed Brown     ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr);
3278a69afd8bSBarry Smith     x    = xcreated;
3279a69afd8bSBarry Smith   }
3280a69afd8bSBarry Smith 
3281a8248277SBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);}
3282efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
3283efd51863SBarry Smith 
328485385478SLisandro Dalcin     /* set solution vector */
3285efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
32866bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
328785385478SLisandro Dalcin     snes->vec_sol = x;
3288caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3289caa4e7f2SJed Brown 
3290caa4e7f2SJed Brown     /* set affine vector if provided */
329185385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
32926bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
329385385478SLisandro Dalcin     snes->vec_rhs = b;
329485385478SLisandro Dalcin 
329570e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
32963f149594SLisandro Dalcin 
32977eee914bSBarry Smith     if (!grid) {
32987eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
3299d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
3300dd568438SSatish Balay       } else if (snes->dm) {
3301dd568438SSatish Balay         PetscBool ig;
3302dd568438SSatish Balay         ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr);
3303dd568438SSatish Balay         if (ig) {
33047eee914bSBarry Smith           ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr);
33057eee914bSBarry Smith         }
3306d25893d9SBarry Smith       }
3307dd568438SSatish Balay     }
3308d25893d9SBarry Smith 
3309abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
331050ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
3311d5e45103SBarry Smith 
33123f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
33134936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
331485385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
33154936397dSBarry Smith     if (snes->domainerror){
33164936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
33174936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
33184936397dSBarry Smith     }
331917186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
33203f149594SLisandro Dalcin 
33217adad957SLisandro Dalcin     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
3322eabae89aSBarry Smith     if (flg && !PetscPreLoadingOn) {
33237adad957SLisandro Dalcin       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
3324eabae89aSBarry Smith       ierr = SNESView(snes,viewer);CHKERRQ(ierr);
33256bf464f9SBarry Smith       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3326eabae89aSBarry Smith     }
3327eabae89aSBarry Smith 
332890d69ab7SBarry Smith     flg  = PETSC_FALSE;
3329acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
3330da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
33315968eb51SBarry Smith     if (snes->printreason) {
3332a8248277SBarry Smith       ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
33335968eb51SBarry Smith       if (snes->reason > 0) {
3334c7e7b494SJed 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);
33355968eb51SBarry Smith       } else {
3336c7e7b494SJed 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);
33375968eb51SBarry Smith       }
3338a8248277SBarry Smith       ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
33395968eb51SBarry Smith     }
33405968eb51SBarry Smith 
33418501fc72SJed Brown     flg = PETSC_FALSE;
33428501fc72SJed Brown     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
33438501fc72SJed Brown     if (flg) {
33448501fc72SJed Brown       PetscViewer viewer;
33458501fc72SJed Brown       ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
33468501fc72SJed Brown       ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr);
33478501fc72SJed Brown       ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr);
33488501fc72SJed Brown       ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr);
33498501fc72SJed Brown       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
33508501fc72SJed Brown     }
33518501fc72SJed Brown 
3352e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
3353efd51863SBarry Smith     if (grid <  snes->gridsequence) {
3354efd51863SBarry Smith       DM  fine;
3355efd51863SBarry Smith       Vec xnew;
3356efd51863SBarry Smith       Mat interp;
3357efd51863SBarry Smith 
3358efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
3359c5c77316SJed Brown       if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
3360e727c939SJed Brown       ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
3361efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
3362efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
3363efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
3364efd51863SBarry Smith       x    = xnew;
3365efd51863SBarry Smith 
3366efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
3367efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
3368efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
3369a8248277SBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);
3370efd51863SBarry Smith     }
3371efd51863SBarry Smith   }
3372a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
33733a40ed3dSBarry Smith   PetscFunctionReturn(0);
33749b94acceSBarry Smith }
33759b94acceSBarry Smith 
33769b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
33779b94acceSBarry Smith 
33784a2ae208SSatish Balay #undef __FUNCT__
33794a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
338082bf6240SBarry Smith /*@C
33814b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
33829b94acceSBarry Smith 
3383fee21e36SBarry Smith    Collective on SNES
3384fee21e36SBarry Smith 
3385c7afd0dbSLois Curfman McInnes    Input Parameters:
3386c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3387454a90a3SBarry Smith -  type - a known method
3388c7afd0dbSLois Curfman McInnes 
3389c7afd0dbSLois Curfman McInnes    Options Database Key:
3390454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
3391c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
3392ae12b187SLois Curfman McInnes 
33939b94acceSBarry Smith    Notes:
3394e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
33954b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
3396c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
33974b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
3398c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
33999b94acceSBarry Smith 
3400ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
3401ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
3402ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
3403ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
3404ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
3405ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
3406ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
3407ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
3408ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
3409b0a32e0cSBarry Smith   appropriate method.
341036851e7fSLois Curfman McInnes 
341136851e7fSLois Curfman McInnes   Level: intermediate
3412a703fe33SLois Curfman McInnes 
3413454a90a3SBarry Smith .keywords: SNES, set, type
3414435da068SBarry Smith 
3415435da068SBarry Smith .seealso: SNESType, SNESCreate()
3416435da068SBarry Smith 
34179b94acceSBarry Smith @*/
34187087cfbeSBarry Smith PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
34199b94acceSBarry Smith {
3420dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
3421ace3abfcSBarry Smith   PetscBool      match;
34223a40ed3dSBarry Smith 
34233a40ed3dSBarry Smith   PetscFunctionBegin;
34240700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
34254482741eSBarry Smith   PetscValidCharPointer(type,2);
342682bf6240SBarry Smith 
34276831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
34280f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
342992ff6ae8SBarry Smith 
34304b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
3431e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
343275396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
3433b5c23020SJed Brown   if (snes->ops->destroy) {
3434b5c23020SJed Brown     ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
3435b5c23020SJed Brown     snes->ops->destroy = PETSC_NULL;
3436b5c23020SJed Brown   }
343775396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
343875396ef9SLisandro Dalcin   snes->ops->setup          = 0;
343975396ef9SLisandro Dalcin   snes->ops->solve          = 0;
344075396ef9SLisandro Dalcin   snes->ops->view           = 0;
344175396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
344275396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
344375396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
344475396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
3445454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
344603bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
34479fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
34489fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
34499fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
34509fb22e1aSBarry Smith   }
34519fb22e1aSBarry Smith #endif
34523a40ed3dSBarry Smith   PetscFunctionReturn(0);
34539b94acceSBarry Smith }
34549b94acceSBarry Smith 
3455a847f771SSatish Balay 
34569b94acceSBarry Smith /* --------------------------------------------------------------------- */
34574a2ae208SSatish Balay #undef __FUNCT__
34584a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
345952baeb72SSatish Balay /*@
34609b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
3461f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
34629b94acceSBarry Smith 
3463fee21e36SBarry Smith    Not Collective
3464fee21e36SBarry Smith 
346536851e7fSLois Curfman McInnes    Level: advanced
346636851e7fSLois Curfman McInnes 
34679b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
34689b94acceSBarry Smith 
34699b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
34709b94acceSBarry Smith @*/
34717087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
34729b94acceSBarry Smith {
3473dfbe8321SBarry Smith   PetscErrorCode ierr;
347482bf6240SBarry Smith 
34753a40ed3dSBarry Smith   PetscFunctionBegin;
34761441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
34774c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
34783a40ed3dSBarry Smith   PetscFunctionReturn(0);
34799b94acceSBarry Smith }
34809b94acceSBarry Smith 
34814a2ae208SSatish Balay #undef __FUNCT__
34824a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
34839b94acceSBarry Smith /*@C
34849a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
34859b94acceSBarry Smith 
3486c7afd0dbSLois Curfman McInnes    Not Collective
3487c7afd0dbSLois Curfman McInnes 
34889b94acceSBarry Smith    Input Parameter:
34894b0e389bSBarry Smith .  snes - nonlinear solver context
34909b94acceSBarry Smith 
34919b94acceSBarry Smith    Output Parameter:
34923a7fca6bSBarry Smith .  type - SNES method (a character string)
34939b94acceSBarry Smith 
349436851e7fSLois Curfman McInnes    Level: intermediate
349536851e7fSLois Curfman McInnes 
3496454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
34979b94acceSBarry Smith @*/
34987087cfbeSBarry Smith PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
34999b94acceSBarry Smith {
35003a40ed3dSBarry Smith   PetscFunctionBegin;
35010700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35024482741eSBarry Smith   PetscValidPointer(type,2);
35037adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
35043a40ed3dSBarry Smith   PetscFunctionReturn(0);
35059b94acceSBarry Smith }
35069b94acceSBarry Smith 
35074a2ae208SSatish Balay #undef __FUNCT__
35084a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
350952baeb72SSatish Balay /*@
35109b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
3511c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
35129b94acceSBarry Smith 
3513c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3514c7afd0dbSLois Curfman McInnes 
35159b94acceSBarry Smith    Input Parameter:
35169b94acceSBarry Smith .  snes - the SNES context
35179b94acceSBarry Smith 
35189b94acceSBarry Smith    Output Parameter:
35199b94acceSBarry Smith .  x - the solution
35209b94acceSBarry Smith 
352170e92668SMatthew Knepley    Level: intermediate
352236851e7fSLois Curfman McInnes 
35239b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
35249b94acceSBarry Smith 
352585385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
35269b94acceSBarry Smith @*/
35277087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
35289b94acceSBarry Smith {
35293a40ed3dSBarry Smith   PetscFunctionBegin;
35300700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35314482741eSBarry Smith   PetscValidPointer(x,2);
353285385478SLisandro Dalcin   *x = snes->vec_sol;
353370e92668SMatthew Knepley   PetscFunctionReturn(0);
353470e92668SMatthew Knepley }
353570e92668SMatthew Knepley 
353670e92668SMatthew Knepley #undef __FUNCT__
35374a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
353852baeb72SSatish Balay /*@
35399b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
35409b94acceSBarry Smith    stored.
35419b94acceSBarry Smith 
3542c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3543c7afd0dbSLois Curfman McInnes 
35449b94acceSBarry Smith    Input Parameter:
35459b94acceSBarry Smith .  snes - the SNES context
35469b94acceSBarry Smith 
35479b94acceSBarry Smith    Output Parameter:
35489b94acceSBarry Smith .  x - the solution update
35499b94acceSBarry Smith 
355036851e7fSLois Curfman McInnes    Level: advanced
355136851e7fSLois Curfman McInnes 
35529b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
35539b94acceSBarry Smith 
355485385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
35559b94acceSBarry Smith @*/
35567087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
35579b94acceSBarry Smith {
35583a40ed3dSBarry Smith   PetscFunctionBegin;
35590700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35604482741eSBarry Smith   PetscValidPointer(x,2);
356185385478SLisandro Dalcin   *x = snes->vec_sol_update;
35623a40ed3dSBarry Smith   PetscFunctionReturn(0);
35639b94acceSBarry Smith }
35649b94acceSBarry Smith 
35654a2ae208SSatish Balay #undef __FUNCT__
35664a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
35679b94acceSBarry Smith /*@C
35683638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
35699b94acceSBarry Smith 
3570a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
3571c7afd0dbSLois Curfman McInnes 
35729b94acceSBarry Smith    Input Parameter:
35739b94acceSBarry Smith .  snes - the SNES context
35749b94acceSBarry Smith 
35759b94acceSBarry Smith    Output Parameter:
35767bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
357770e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
357870e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
35799b94acceSBarry Smith 
358036851e7fSLois Curfman McInnes    Level: advanced
358136851e7fSLois Curfman McInnes 
3582a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
35839b94acceSBarry Smith 
35844b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
35859b94acceSBarry Smith @*/
35867087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
35879b94acceSBarry Smith {
3588a63bb30eSJed Brown   PetscErrorCode ierr;
35896cab3a1bSJed Brown   DM             dm;
3590a63bb30eSJed Brown 
35913a40ed3dSBarry Smith   PetscFunctionBegin;
35920700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3593a63bb30eSJed Brown   if (r) {
3594a63bb30eSJed Brown     if (!snes->vec_func) {
3595a63bb30eSJed Brown       if (snes->vec_rhs) {
3596a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
3597a63bb30eSJed Brown       } else if (snes->vec_sol) {
3598a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
3599a63bb30eSJed Brown       } else if (snes->dm) {
3600a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
3601a63bb30eSJed Brown       }
3602a63bb30eSJed Brown     }
3603a63bb30eSJed Brown     *r = snes->vec_func;
3604a63bb30eSJed Brown   }
36056cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
36066cab3a1bSJed Brown   ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr);
36073a40ed3dSBarry Smith   PetscFunctionReturn(0);
36089b94acceSBarry Smith }
36099b94acceSBarry Smith 
3610c79ef259SPeter Brune /*@C
3611c79ef259SPeter Brune    SNESGetGS - Returns the GS function and context.
3612c79ef259SPeter Brune 
3613c79ef259SPeter Brune    Input Parameter:
3614c79ef259SPeter Brune .  snes - the SNES context
3615c79ef259SPeter Brune 
3616c79ef259SPeter Brune    Output Parameter:
3617c79ef259SPeter Brune +  gsfunc - the function (or PETSC_NULL)
3618c79ef259SPeter Brune -  ctx    - the function context (or PETSC_NULL)
3619c79ef259SPeter Brune 
3620c79ef259SPeter Brune    Level: advanced
3621c79ef259SPeter Brune 
3622c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
3623c79ef259SPeter Brune 
3624c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction()
3625c79ef259SPeter Brune @*/
3626c79ef259SPeter Brune 
36274a2ae208SSatish Balay #undef __FUNCT__
3628646217ecSPeter Brune #define __FUNCT__ "SNESGetGS"
3629646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx)
3630646217ecSPeter Brune {
36316cab3a1bSJed Brown   PetscErrorCode ierr;
36326cab3a1bSJed Brown   DM             dm;
36336cab3a1bSJed Brown 
3634646217ecSPeter Brune   PetscFunctionBegin;
3635646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36366cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
36376cab3a1bSJed Brown   ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr);
3638646217ecSPeter Brune   PetscFunctionReturn(0);
3639646217ecSPeter Brune }
3640646217ecSPeter Brune 
36414a2ae208SSatish Balay #undef __FUNCT__
36424a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
36433c7409f5SSatish Balay /*@C
36443c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
3645d850072dSLois Curfman McInnes    SNES options in the database.
36463c7409f5SSatish Balay 
36473f9fe445SBarry Smith    Logically Collective on SNES
3648fee21e36SBarry Smith 
3649c7afd0dbSLois Curfman McInnes    Input Parameter:
3650c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3651c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3652c7afd0dbSLois Curfman McInnes 
3653d850072dSLois Curfman McInnes    Notes:
3654a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3655c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3656d850072dSLois Curfman McInnes 
365736851e7fSLois Curfman McInnes    Level: advanced
365836851e7fSLois Curfman McInnes 
36593c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
3660a86d99e1SLois Curfman McInnes 
3661a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
36623c7409f5SSatish Balay @*/
36637087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
36643c7409f5SSatish Balay {
3665dfbe8321SBarry Smith   PetscErrorCode ierr;
36663c7409f5SSatish Balay 
36673a40ed3dSBarry Smith   PetscFunctionBegin;
36680700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3669639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
36701cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
367194b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
36723a40ed3dSBarry Smith   PetscFunctionReturn(0);
36733c7409f5SSatish Balay }
36743c7409f5SSatish Balay 
36754a2ae208SSatish Balay #undef __FUNCT__
36764a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
36773c7409f5SSatish Balay /*@C
3678f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
3679d850072dSLois Curfman McInnes    SNES options in the database.
36803c7409f5SSatish Balay 
36813f9fe445SBarry Smith    Logically Collective on SNES
3682fee21e36SBarry Smith 
3683c7afd0dbSLois Curfman McInnes    Input Parameters:
3684c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3685c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3686c7afd0dbSLois Curfman McInnes 
3687d850072dSLois Curfman McInnes    Notes:
3688a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3689c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3690d850072dSLois Curfman McInnes 
369136851e7fSLois Curfman McInnes    Level: advanced
369236851e7fSLois Curfman McInnes 
36933c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
3694a86d99e1SLois Curfman McInnes 
3695a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
36963c7409f5SSatish Balay @*/
36977087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
36983c7409f5SSatish Balay {
3699dfbe8321SBarry Smith   PetscErrorCode ierr;
37003c7409f5SSatish Balay 
37013a40ed3dSBarry Smith   PetscFunctionBegin;
37020700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3703639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
37041cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
370594b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
37063a40ed3dSBarry Smith   PetscFunctionReturn(0);
37073c7409f5SSatish Balay }
37083c7409f5SSatish Balay 
37094a2ae208SSatish Balay #undef __FUNCT__
37104a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
37119ab63eb5SSatish Balay /*@C
37123c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
37133c7409f5SSatish Balay    SNES options in the database.
37143c7409f5SSatish Balay 
3715c7afd0dbSLois Curfman McInnes    Not Collective
3716c7afd0dbSLois Curfman McInnes 
37173c7409f5SSatish Balay    Input Parameter:
37183c7409f5SSatish Balay .  snes - the SNES context
37193c7409f5SSatish Balay 
37203c7409f5SSatish Balay    Output Parameter:
37213c7409f5SSatish Balay .  prefix - pointer to the prefix string used
37223c7409f5SSatish Balay 
37234ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
37249ab63eb5SSatish Balay    sufficient length to hold the prefix.
37259ab63eb5SSatish Balay 
372636851e7fSLois Curfman McInnes    Level: advanced
372736851e7fSLois Curfman McInnes 
37283c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
3729a86d99e1SLois Curfman McInnes 
3730a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
37313c7409f5SSatish Balay @*/
37327087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
37333c7409f5SSatish Balay {
3734dfbe8321SBarry Smith   PetscErrorCode ierr;
37353c7409f5SSatish Balay 
37363a40ed3dSBarry Smith   PetscFunctionBegin;
37370700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3738639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
37393a40ed3dSBarry Smith   PetscFunctionReturn(0);
37403c7409f5SSatish Balay }
37413c7409f5SSatish Balay 
3742b2002411SLois Curfman McInnes 
37434a2ae208SSatish Balay #undef __FUNCT__
37444a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
37453cea93caSBarry Smith /*@C
37463cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
37473cea93caSBarry Smith 
37487f6c08e0SMatthew Knepley   Level: advanced
37493cea93caSBarry Smith @*/
37507087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
3751b2002411SLois Curfman McInnes {
3752e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
3753dfbe8321SBarry Smith   PetscErrorCode ierr;
3754b2002411SLois Curfman McInnes 
3755b2002411SLois Curfman McInnes   PetscFunctionBegin;
3756b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3757c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3758b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
3759b2002411SLois Curfman McInnes }
3760da9b6338SBarry Smith 
3761da9b6338SBarry Smith #undef __FUNCT__
3762da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
37637087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
3764da9b6338SBarry Smith {
3765dfbe8321SBarry Smith   PetscErrorCode ierr;
376677431f27SBarry Smith   PetscInt       N,i,j;
3767da9b6338SBarry Smith   Vec            u,uh,fh;
3768da9b6338SBarry Smith   PetscScalar    value;
3769da9b6338SBarry Smith   PetscReal      norm;
3770da9b6338SBarry Smith 
3771da9b6338SBarry Smith   PetscFunctionBegin;
3772da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
3773da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
3774da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
3775da9b6338SBarry Smith 
3776da9b6338SBarry Smith   /* currently only works for sequential */
3777da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
3778da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
3779da9b6338SBarry Smith   for (i=0; i<N; i++) {
3780da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
378177431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
3782da9b6338SBarry Smith     for (j=-10; j<11; j++) {
3783ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
3784da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
37853ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
3786da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
378777431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
3788da9b6338SBarry Smith       value = -value;
3789da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
3790da9b6338SBarry Smith     }
3791da9b6338SBarry Smith   }
37926bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
37936bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
3794da9b6338SBarry Smith   PetscFunctionReturn(0);
3795da9b6338SBarry Smith }
379671f87433Sdalcinl 
379771f87433Sdalcinl #undef __FUNCT__
3798fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
379971f87433Sdalcinl /*@
3800fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
380171f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
380271f87433Sdalcinl    Newton method.
380371f87433Sdalcinl 
38043f9fe445SBarry Smith    Logically Collective on SNES
380571f87433Sdalcinl 
380671f87433Sdalcinl    Input Parameters:
380771f87433Sdalcinl +  snes - SNES context
380871f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
380971f87433Sdalcinl 
381064ba62caSBarry Smith     Options Database:
381164ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
381264ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
381364ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
381464ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
381564ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
381664ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
381764ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
381864ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
381964ba62caSBarry Smith 
382071f87433Sdalcinl    Notes:
382171f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
382271f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
382371f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
382471f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
382571f87433Sdalcinl    solver.
382671f87433Sdalcinl 
382771f87433Sdalcinl    Level: advanced
382871f87433Sdalcinl 
382971f87433Sdalcinl    Reference:
383071f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
383171f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
383271f87433Sdalcinl 
383371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
383471f87433Sdalcinl 
3835fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
383671f87433Sdalcinl @*/
38377087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
383871f87433Sdalcinl {
383971f87433Sdalcinl   PetscFunctionBegin;
38400700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3841acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
384271f87433Sdalcinl   snes->ksp_ewconv = flag;
384371f87433Sdalcinl   PetscFunctionReturn(0);
384471f87433Sdalcinl }
384571f87433Sdalcinl 
384671f87433Sdalcinl #undef __FUNCT__
3847fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
384871f87433Sdalcinl /*@
3849fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
385071f87433Sdalcinl    for computing relative tolerance for linear solvers within an
385171f87433Sdalcinl    inexact Newton method.
385271f87433Sdalcinl 
385371f87433Sdalcinl    Not Collective
385471f87433Sdalcinl 
385571f87433Sdalcinl    Input Parameter:
385671f87433Sdalcinl .  snes - SNES context
385771f87433Sdalcinl 
385871f87433Sdalcinl    Output Parameter:
385971f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
386071f87433Sdalcinl 
386171f87433Sdalcinl    Notes:
386271f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
386371f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
386471f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
386571f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
386671f87433Sdalcinl    solver.
386771f87433Sdalcinl 
386871f87433Sdalcinl    Level: advanced
386971f87433Sdalcinl 
387071f87433Sdalcinl    Reference:
387171f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
387271f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
387371f87433Sdalcinl 
387471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
387571f87433Sdalcinl 
3876fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
387771f87433Sdalcinl @*/
38787087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
387971f87433Sdalcinl {
388071f87433Sdalcinl   PetscFunctionBegin;
38810700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
388271f87433Sdalcinl   PetscValidPointer(flag,2);
388371f87433Sdalcinl   *flag = snes->ksp_ewconv;
388471f87433Sdalcinl   PetscFunctionReturn(0);
388571f87433Sdalcinl }
388671f87433Sdalcinl 
388771f87433Sdalcinl #undef __FUNCT__
3888fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
388971f87433Sdalcinl /*@
3890fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
389171f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
389271f87433Sdalcinl    Newton method.
389371f87433Sdalcinl 
38943f9fe445SBarry Smith    Logically Collective on SNES
389571f87433Sdalcinl 
389671f87433Sdalcinl    Input Parameters:
389771f87433Sdalcinl +    snes - SNES context
389871f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
389971f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
390071f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
390171f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
390271f87433Sdalcinl              (0 <= gamma2 <= 1)
390371f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
390471f87433Sdalcinl .    alpha2 - power for safeguard
390571f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
390671f87433Sdalcinl 
390771f87433Sdalcinl    Note:
390871f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
390971f87433Sdalcinl 
391071f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
391171f87433Sdalcinl 
391271f87433Sdalcinl    Level: advanced
391371f87433Sdalcinl 
391471f87433Sdalcinl    Reference:
391571f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
391671f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
391771f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
391871f87433Sdalcinl 
391971f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
392071f87433Sdalcinl 
3921fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
392271f87433Sdalcinl @*/
39237087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
392471f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
392571f87433Sdalcinl {
3926fa9f3622SBarry Smith   SNESKSPEW *kctx;
392771f87433Sdalcinl   PetscFunctionBegin;
39280700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3929fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3930e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
3931c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
3932c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
3933c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
3934c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
3935c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
3936c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
3937c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
393871f87433Sdalcinl 
393971f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
394071f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
394171f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
394271f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
394371f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
394471f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
394571f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
394671f87433Sdalcinl 
394771f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
3948e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
394971f87433Sdalcinl   }
395071f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
3951e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
395271f87433Sdalcinl   }
395371f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
3954e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
395571f87433Sdalcinl   }
395671f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
3957e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
395871f87433Sdalcinl   }
395971f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
3960e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
396171f87433Sdalcinl   }
396271f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
3963e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
396471f87433Sdalcinl   }
396571f87433Sdalcinl   PetscFunctionReturn(0);
396671f87433Sdalcinl }
396771f87433Sdalcinl 
396871f87433Sdalcinl #undef __FUNCT__
3969fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
397071f87433Sdalcinl /*@
3971fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
397271f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
397371f87433Sdalcinl    Newton method.
397471f87433Sdalcinl 
397571f87433Sdalcinl    Not Collective
397671f87433Sdalcinl 
397771f87433Sdalcinl    Input Parameters:
397871f87433Sdalcinl      snes - SNES context
397971f87433Sdalcinl 
398071f87433Sdalcinl    Output Parameters:
398171f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
398271f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
398371f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
398471f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
398571f87433Sdalcinl              (0 <= gamma2 <= 1)
398671f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
398771f87433Sdalcinl .    alpha2 - power for safeguard
398871f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
398971f87433Sdalcinl 
399071f87433Sdalcinl    Level: advanced
399171f87433Sdalcinl 
399271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
399371f87433Sdalcinl 
3994fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
399571f87433Sdalcinl @*/
39967087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
399771f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
399871f87433Sdalcinl {
3999fa9f3622SBarry Smith   SNESKSPEW *kctx;
400071f87433Sdalcinl   PetscFunctionBegin;
40010700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4002fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4003e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
400471f87433Sdalcinl   if(version)   *version   = kctx->version;
400571f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
400671f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
400771f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
400871f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
400971f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
401071f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
401171f87433Sdalcinl   PetscFunctionReturn(0);
401271f87433Sdalcinl }
401371f87433Sdalcinl 
401471f87433Sdalcinl #undef __FUNCT__
4015fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
4016fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
401771f87433Sdalcinl {
401871f87433Sdalcinl   PetscErrorCode ierr;
4019fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
402071f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
402171f87433Sdalcinl 
402271f87433Sdalcinl   PetscFunctionBegin;
4023e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
402471f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
402571f87433Sdalcinl     rtol = kctx->rtol_0;
402671f87433Sdalcinl   } else {
402771f87433Sdalcinl     if (kctx->version == 1) {
402871f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
402971f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
403071f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
403171f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
403271f87433Sdalcinl     } else if (kctx->version == 2) {
403371f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
403471f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
403571f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
403671f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
403771f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
403871f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
403971f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
404071f87433Sdalcinl       stol = PetscMax(rtol,stol);
404171f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
404271f87433Sdalcinl       /* safeguard: avoid oversolving */
404371f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
404471f87433Sdalcinl       stol = PetscMax(rtol,stol);
404571f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
4046e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
404771f87433Sdalcinl   }
404871f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
404971f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
405071f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
405171f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
405271f87433Sdalcinl   PetscFunctionReturn(0);
405371f87433Sdalcinl }
405471f87433Sdalcinl 
405571f87433Sdalcinl #undef __FUNCT__
4056fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
4057fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
405871f87433Sdalcinl {
405971f87433Sdalcinl   PetscErrorCode ierr;
4060fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
406171f87433Sdalcinl   PCSide         pcside;
406271f87433Sdalcinl   Vec            lres;
406371f87433Sdalcinl 
406471f87433Sdalcinl   PetscFunctionBegin;
4065e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
406671f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
406771f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
406871f87433Sdalcinl   if (kctx->version == 1) {
4069b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
407071f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
407171f87433Sdalcinl       /* KSP residual is true linear residual */
407271f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
407371f87433Sdalcinl     } else {
407471f87433Sdalcinl       /* KSP residual is preconditioned residual */
407571f87433Sdalcinl       /* compute true linear residual norm */
407671f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
407771f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
407871f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
407971f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
40806bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
408171f87433Sdalcinl     }
408271f87433Sdalcinl   }
408371f87433Sdalcinl   PetscFunctionReturn(0);
408471f87433Sdalcinl }
408571f87433Sdalcinl 
408671f87433Sdalcinl #undef __FUNCT__
408771f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
408871f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
408971f87433Sdalcinl {
409071f87433Sdalcinl   PetscErrorCode ierr;
409171f87433Sdalcinl 
409271f87433Sdalcinl   PetscFunctionBegin;
4093fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
409471f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
4095fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
409671f87433Sdalcinl   PetscFunctionReturn(0);
409771f87433Sdalcinl }
40986c699258SBarry Smith 
40996c699258SBarry Smith #undef __FUNCT__
41006c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
41016c699258SBarry Smith /*@
41026c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
41036c699258SBarry Smith 
41043f9fe445SBarry Smith    Logically Collective on SNES
41056c699258SBarry Smith 
41066c699258SBarry Smith    Input Parameters:
41076c699258SBarry Smith +  snes - the preconditioner context
41086c699258SBarry Smith -  dm - the dm
41096c699258SBarry Smith 
41106c699258SBarry Smith    Level: intermediate
41116c699258SBarry Smith 
41126c699258SBarry Smith 
41136c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
41146c699258SBarry Smith @*/
41157087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
41166c699258SBarry Smith {
41176c699258SBarry Smith   PetscErrorCode ierr;
4118345fed2cSBarry Smith   KSP            ksp;
41196cab3a1bSJed Brown   SNESDM         sdm;
41206c699258SBarry Smith 
41216c699258SBarry Smith   PetscFunctionBegin;
41220700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4123d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
41246cab3a1bSJed Brown   if (snes->dm) {               /* Move the SNESDM context over to the new DM unless the new DM already has one */
41256cab3a1bSJed Brown     PetscContainer oldcontainer,container;
41266cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr);
41276cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr);
41286cab3a1bSJed Brown     if (oldcontainer && !container) {
41296cab3a1bSJed Brown       ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr);
41306cab3a1bSJed Brown       ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr);
41316cab3a1bSJed Brown       if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */
41326cab3a1bSJed Brown         sdm->originaldm = dm;
41336cab3a1bSJed Brown       }
41346cab3a1bSJed Brown     }
41356bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
41366cab3a1bSJed Brown   }
41376c699258SBarry Smith   snes->dm = dm;
4138345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4139345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4140f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
41412c155ee1SBarry Smith   if (snes->pc) {
41422c155ee1SBarry Smith     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
41432c155ee1SBarry Smith   }
41446c699258SBarry Smith   PetscFunctionReturn(0);
41456c699258SBarry Smith }
41466c699258SBarry Smith 
41476c699258SBarry Smith #undef __FUNCT__
41486c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
41496c699258SBarry Smith /*@
41506c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
41516c699258SBarry Smith 
41523f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
41536c699258SBarry Smith 
41546c699258SBarry Smith    Input Parameter:
41556c699258SBarry Smith . snes - the preconditioner context
41566c699258SBarry Smith 
41576c699258SBarry Smith    Output Parameter:
41586c699258SBarry Smith .  dm - the dm
41596c699258SBarry Smith 
41606c699258SBarry Smith    Level: intermediate
41616c699258SBarry Smith 
41626c699258SBarry Smith 
41636c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
41646c699258SBarry Smith @*/
41657087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
41666c699258SBarry Smith {
41676cab3a1bSJed Brown   PetscErrorCode ierr;
41686cab3a1bSJed Brown 
41696c699258SBarry Smith   PetscFunctionBegin;
41700700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
41716cab3a1bSJed Brown   if (!snes->dm) {
41726cab3a1bSJed Brown     ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr);
41736cab3a1bSJed Brown   }
41746c699258SBarry Smith   *dm = snes->dm;
41756c699258SBarry Smith   PetscFunctionReturn(0);
41766c699258SBarry Smith }
41770807856dSBarry Smith 
417831823bd8SMatthew G Knepley #undef __FUNCT__
417931823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
418031823bd8SMatthew G Knepley /*@
4181fd4b34e9SJed Brown   SNESSetPC - Sets the nonlinear preconditioner to be used.
418231823bd8SMatthew G Knepley 
418331823bd8SMatthew G Knepley   Collective on SNES
418431823bd8SMatthew G Knepley 
418531823bd8SMatthew G Knepley   Input Parameters:
418631823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
418731823bd8SMatthew G Knepley - pc   - the preconditioner object
418831823bd8SMatthew G Knepley 
418931823bd8SMatthew G Knepley   Notes:
419031823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
419131823bd8SMatthew G Knepley   to configure it using the API).
419231823bd8SMatthew G Knepley 
419331823bd8SMatthew G Knepley   Level: developer
419431823bd8SMatthew G Knepley 
419531823bd8SMatthew G Knepley .keywords: SNES, set, precondition
419631823bd8SMatthew G Knepley .seealso: SNESGetPC()
419731823bd8SMatthew G Knepley @*/
419831823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
419931823bd8SMatthew G Knepley {
420031823bd8SMatthew G Knepley   PetscErrorCode ierr;
420131823bd8SMatthew G Knepley 
420231823bd8SMatthew G Knepley   PetscFunctionBegin;
420331823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
420431823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
420531823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
420631823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4207bf11d3b6SBarry Smith   ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr);
420831823bd8SMatthew G Knepley   snes->pc = pc;
420931823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
421031823bd8SMatthew G Knepley   PetscFunctionReturn(0);
421131823bd8SMatthew G Knepley }
421231823bd8SMatthew G Knepley 
421331823bd8SMatthew G Knepley #undef __FUNCT__
421431823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
421531823bd8SMatthew G Knepley /*@
4216fd4b34e9SJed Brown   SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().
421731823bd8SMatthew G Knepley 
421831823bd8SMatthew G Knepley   Not Collective
421931823bd8SMatthew G Knepley 
422031823bd8SMatthew G Knepley   Input Parameter:
422131823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
422231823bd8SMatthew G Knepley 
422331823bd8SMatthew G Knepley   Output Parameter:
422431823bd8SMatthew G Knepley . pc - preconditioner context
422531823bd8SMatthew G Knepley 
422631823bd8SMatthew G Knepley   Level: developer
422731823bd8SMatthew G Knepley 
422831823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
422931823bd8SMatthew G Knepley .seealso: SNESSetPC()
423031823bd8SMatthew G Knepley @*/
423131823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
423231823bd8SMatthew G Knepley {
423331823bd8SMatthew G Knepley   PetscErrorCode ierr;
423431823bd8SMatthew G Knepley 
423531823bd8SMatthew G Knepley   PetscFunctionBegin;
423631823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
423731823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
423831823bd8SMatthew G Knepley   if (!snes->pc) {
423931823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr);
42404a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr);
424131823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
424231823bd8SMatthew G Knepley   }
424331823bd8SMatthew G Knepley   *pc = snes->pc;
424431823bd8SMatthew G Knepley   PetscFunctionReturn(0);
424531823bd8SMatthew G Knepley }
424631823bd8SMatthew G Knepley 
42479e764e56SPeter Brune #undef __FUNCT__
4248f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch"
42499e764e56SPeter Brune /*@
4250f1c6b773SPeter Brune   SNESSetSNESLineSearch - Sets the linesearch.
42519e764e56SPeter Brune 
42529e764e56SPeter Brune   Collective on SNES
42539e764e56SPeter Brune 
42549e764e56SPeter Brune   Input Parameters:
42559e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
42569e764e56SPeter Brune - linesearch   - the linesearch object
42579e764e56SPeter Brune 
42589e764e56SPeter Brune   Notes:
4259f1c6b773SPeter Brune   Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example,
42609e764e56SPeter Brune   to configure it using the API).
42619e764e56SPeter Brune 
42629e764e56SPeter Brune   Level: developer
42639e764e56SPeter Brune 
42649e764e56SPeter Brune .keywords: SNES, set, linesearch
4265f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch()
42669e764e56SPeter Brune @*/
4267f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch)
42689e764e56SPeter Brune {
42699e764e56SPeter Brune   PetscErrorCode ierr;
42709e764e56SPeter Brune 
42719e764e56SPeter Brune   PetscFunctionBegin;
42729e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4273f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
42749e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
42759e764e56SPeter Brune   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
4276f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
42779e764e56SPeter Brune   snes->linesearch = linesearch;
42789e764e56SPeter Brune   ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
42799e764e56SPeter Brune   PetscFunctionReturn(0);
42809e764e56SPeter Brune }
42819e764e56SPeter Brune 
42829e764e56SPeter Brune #undef __FUNCT__
4283f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch"
4284ea5d4fccSPeter Brune /*@C
4285f1c6b773SPeter Brune   SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch().
42869e764e56SPeter Brune 
42879e764e56SPeter Brune   Not Collective
42889e764e56SPeter Brune 
42899e764e56SPeter Brune   Input Parameter:
42909e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
42919e764e56SPeter Brune 
42929e764e56SPeter Brune   Output Parameter:
42939e764e56SPeter Brune . linesearch - linesearch context
42949e764e56SPeter Brune 
42959e764e56SPeter Brune   Level: developer
42969e764e56SPeter Brune 
42979e764e56SPeter Brune .keywords: SNES, get, linesearch
4298f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch()
42999e764e56SPeter Brune @*/
4300f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch)
43019e764e56SPeter Brune {
43029e764e56SPeter Brune   PetscErrorCode ierr;
43039e764e56SPeter Brune   const char     *optionsprefix;
43049e764e56SPeter Brune 
43059e764e56SPeter Brune   PetscFunctionBegin;
43069e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
43079e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
43089e764e56SPeter Brune   if (!snes->linesearch) {
43099e764e56SPeter Brune     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
4310f1c6b773SPeter Brune     ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr);
4311f1c6b773SPeter Brune     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
4312b1dca40bSPeter Brune     ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr);
43139e764e56SPeter Brune     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
43149e764e56SPeter Brune     ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
43159e764e56SPeter Brune   }
43169e764e56SPeter Brune   *linesearch = snes->linesearch;
43179e764e56SPeter Brune   PetscFunctionReturn(0);
43189e764e56SPeter Brune }
43199e764e56SPeter Brune 
432069b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4321c6db04a5SJed Brown #include <mex.h>
432269b4f73cSBarry Smith 
43238f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
43248f6e6473SBarry Smith 
43250807856dSBarry Smith #undef __FUNCT__
43260807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
43270807856dSBarry Smith /*
43280807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
43290807856dSBarry Smith                          SNESSetFunctionMatlab().
43300807856dSBarry Smith 
43310807856dSBarry Smith    Collective on SNES
43320807856dSBarry Smith 
43330807856dSBarry Smith    Input Parameters:
43340807856dSBarry Smith +  snes - the SNES context
43350807856dSBarry Smith -  x - input vector
43360807856dSBarry Smith 
43370807856dSBarry Smith    Output Parameter:
43380807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
43390807856dSBarry Smith 
43400807856dSBarry Smith    Notes:
43410807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
43420807856dSBarry Smith    implementations, so most users would not generally call this routine
43430807856dSBarry Smith    themselves.
43440807856dSBarry Smith 
43450807856dSBarry Smith    Level: developer
43460807856dSBarry Smith 
43470807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
43480807856dSBarry Smith 
43490807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
435061b2408cSBarry Smith */
43517087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
43520807856dSBarry Smith {
4353e650e774SBarry Smith   PetscErrorCode    ierr;
43548f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
43558f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
43568f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
435791621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
4358e650e774SBarry Smith 
43590807856dSBarry Smith   PetscFunctionBegin;
43600807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
43610807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
43620807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
43630807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
43640807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
43650807856dSBarry Smith 
43660807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
4367e650e774SBarry Smith 
436891621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4369e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4370e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
437191621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
437291621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
437391621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
43748f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
43758f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
4376b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
4377e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4378e650e774SBarry Smith   mxDestroyArray(prhs[0]);
4379e650e774SBarry Smith   mxDestroyArray(prhs[1]);
4380e650e774SBarry Smith   mxDestroyArray(prhs[2]);
43818f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
4382e650e774SBarry Smith   mxDestroyArray(plhs[0]);
43830807856dSBarry Smith   PetscFunctionReturn(0);
43840807856dSBarry Smith }
43850807856dSBarry Smith 
43860807856dSBarry Smith 
43870807856dSBarry Smith #undef __FUNCT__
43880807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
438961b2408cSBarry Smith /*
43900807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
43910807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4392e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
43930807856dSBarry Smith 
43940807856dSBarry Smith    Logically Collective on SNES
43950807856dSBarry Smith 
43960807856dSBarry Smith    Input Parameters:
43970807856dSBarry Smith +  snes - the SNES context
43980807856dSBarry Smith .  r - vector to store function value
43990807856dSBarry Smith -  func - function evaluation routine
44000807856dSBarry Smith 
44010807856dSBarry Smith    Calling sequence of func:
440261b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
44030807856dSBarry Smith 
44040807856dSBarry Smith 
44050807856dSBarry Smith    Notes:
44060807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
44070807856dSBarry Smith $      f'(x) x = -f(x),
44080807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
44090807856dSBarry Smith 
44100807856dSBarry Smith    Level: beginner
44110807856dSBarry Smith 
44120807856dSBarry Smith .keywords: SNES, nonlinear, set, function
44130807856dSBarry Smith 
44140807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
441561b2408cSBarry Smith */
44167087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
44170807856dSBarry Smith {
44180807856dSBarry Smith   PetscErrorCode    ierr;
44198f6e6473SBarry Smith   SNESMatlabContext *sctx;
44200807856dSBarry Smith 
44210807856dSBarry Smith   PetscFunctionBegin;
44228f6e6473SBarry Smith   /* currently sctx is memory bleed */
44238f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
44248f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
44258f6e6473SBarry Smith   /*
44268f6e6473SBarry Smith      This should work, but it doesn't
44278f6e6473SBarry Smith   sctx->ctx = ctx;
44288f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
44298f6e6473SBarry Smith   */
44308f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
44318f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
44320807856dSBarry Smith   PetscFunctionReturn(0);
44330807856dSBarry Smith }
443469b4f73cSBarry Smith 
443561b2408cSBarry Smith #undef __FUNCT__
443661b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
443761b2408cSBarry Smith /*
443861b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
443961b2408cSBarry Smith                          SNESSetJacobianMatlab().
444061b2408cSBarry Smith 
444161b2408cSBarry Smith    Collective on SNES
444261b2408cSBarry Smith 
444361b2408cSBarry Smith    Input Parameters:
444461b2408cSBarry Smith +  snes - the SNES context
444561b2408cSBarry Smith .  x - input vector
444661b2408cSBarry Smith .  A, B - the matrices
444761b2408cSBarry Smith -  ctx - user context
444861b2408cSBarry Smith 
444961b2408cSBarry Smith    Output Parameter:
445061b2408cSBarry Smith .  flag - structure of the matrix
445161b2408cSBarry Smith 
445261b2408cSBarry Smith    Level: developer
445361b2408cSBarry Smith 
445461b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
445561b2408cSBarry Smith 
445661b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
445761b2408cSBarry Smith @*/
44587087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
445961b2408cSBarry Smith {
446061b2408cSBarry Smith   PetscErrorCode    ierr;
446161b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
446261b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
446361b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
446461b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
446561b2408cSBarry Smith 
446661b2408cSBarry Smith   PetscFunctionBegin;
446761b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
446861b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
446961b2408cSBarry Smith 
447061b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
447161b2408cSBarry Smith 
447261b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
447361b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
447461b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
447561b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
447661b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
447761b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
447861b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
447961b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
448061b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
448161b2408cSBarry Smith   prhs[5] =  sctx->ctx;
4482b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
448361b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
448461b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
448561b2408cSBarry Smith   mxDestroyArray(prhs[0]);
448661b2408cSBarry Smith   mxDestroyArray(prhs[1]);
448761b2408cSBarry Smith   mxDestroyArray(prhs[2]);
448861b2408cSBarry Smith   mxDestroyArray(prhs[3]);
448961b2408cSBarry Smith   mxDestroyArray(prhs[4]);
449061b2408cSBarry Smith   mxDestroyArray(plhs[0]);
449161b2408cSBarry Smith   mxDestroyArray(plhs[1]);
449261b2408cSBarry Smith   PetscFunctionReturn(0);
449361b2408cSBarry Smith }
449461b2408cSBarry Smith 
449561b2408cSBarry Smith 
449661b2408cSBarry Smith #undef __FUNCT__
449761b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
449861b2408cSBarry Smith /*
449961b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
450061b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4501e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
450261b2408cSBarry Smith 
450361b2408cSBarry Smith    Logically Collective on SNES
450461b2408cSBarry Smith 
450561b2408cSBarry Smith    Input Parameters:
450661b2408cSBarry Smith +  snes - the SNES context
450761b2408cSBarry Smith .  A,B - Jacobian matrices
450861b2408cSBarry Smith .  func - function evaluation routine
450961b2408cSBarry Smith -  ctx - user context
451061b2408cSBarry Smith 
451161b2408cSBarry Smith    Calling sequence of func:
451261b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
451361b2408cSBarry Smith 
451461b2408cSBarry Smith 
451561b2408cSBarry Smith    Level: developer
451661b2408cSBarry Smith 
451761b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
451861b2408cSBarry Smith 
451961b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
452061b2408cSBarry Smith */
45217087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
452261b2408cSBarry Smith {
452361b2408cSBarry Smith   PetscErrorCode    ierr;
452461b2408cSBarry Smith   SNESMatlabContext *sctx;
452561b2408cSBarry Smith 
452661b2408cSBarry Smith   PetscFunctionBegin;
452761b2408cSBarry Smith   /* currently sctx is memory bleed */
452861b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
452961b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
453061b2408cSBarry Smith   /*
453161b2408cSBarry Smith      This should work, but it doesn't
453261b2408cSBarry Smith   sctx->ctx = ctx;
453361b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
453461b2408cSBarry Smith   */
453561b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
453661b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
453761b2408cSBarry Smith   PetscFunctionReturn(0);
453861b2408cSBarry Smith }
453969b4f73cSBarry Smith 
4540f9eb7ae2SShri Abhyankar #undef __FUNCT__
4541f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
4542f9eb7ae2SShri Abhyankar /*
4543f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
4544f9eb7ae2SShri Abhyankar 
4545f9eb7ae2SShri Abhyankar    Collective on SNES
4546f9eb7ae2SShri Abhyankar 
4547f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
4548f9eb7ae2SShri Abhyankar @*/
45497087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
4550f9eb7ae2SShri Abhyankar {
4551f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
455248f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
4553f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
4554f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
4555f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
4556f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
4557f9eb7ae2SShri Abhyankar 
4558f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4559f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4560f9eb7ae2SShri Abhyankar 
4561f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4562f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4563f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
4564f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
4565f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
4566f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
4567f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
4568f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
4569f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
4570f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4571f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
4572f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
4573f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
4574f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
4575f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
4576f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
4577f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4578f9eb7ae2SShri Abhyankar }
4579f9eb7ae2SShri Abhyankar 
4580f9eb7ae2SShri Abhyankar 
4581f9eb7ae2SShri Abhyankar #undef __FUNCT__
4582f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
4583f9eb7ae2SShri Abhyankar /*
4584e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
4585f9eb7ae2SShri Abhyankar 
4586f9eb7ae2SShri Abhyankar    Level: developer
4587f9eb7ae2SShri Abhyankar 
4588f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
4589f9eb7ae2SShri Abhyankar 
4590f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
4591f9eb7ae2SShri Abhyankar */
45927087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
4593f9eb7ae2SShri Abhyankar {
4594f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
4595f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
4596f9eb7ae2SShri Abhyankar 
4597f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4598f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
4599f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
4600f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4601f9eb7ae2SShri Abhyankar   /*
4602f9eb7ae2SShri Abhyankar      This should work, but it doesn't
4603f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
4604f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
4605f9eb7ae2SShri Abhyankar   */
4606f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
4607f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4608f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4609f9eb7ae2SShri Abhyankar }
4610f9eb7ae2SShri Abhyankar 
461169b4f73cSBarry Smith #endif
4612