xref: /petsc/src/snes/interface/snes.c (revision 251f4c6745e69799cb0300fd80598c58f96eb452)
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 
194*251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
195*251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((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);
330*251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((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__
341dfe15315SJed Brown #define __FUNCT__ "DMRestrictHook_SNESVecSol"
342dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx)
343dfe15315SJed Brown {
344dfe15315SJed Brown   SNES snes = (SNES)ctx;
345dfe15315SJed Brown   PetscErrorCode ierr;
346dfe15315SJed Brown   Vec Xfine,Xfine_named = PETSC_NULL,Xcoarse;
347dfe15315SJed Brown 
348dfe15315SJed Brown   PetscFunctionBegin;
349dfe15315SJed Brown   if (dmfine == snes->dm) Xfine = snes->vec_sol;
350dfe15315SJed Brown   else {
351dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);
352dfe15315SJed Brown     Xfine = Xfine_named;
353dfe15315SJed Brown   }
354dfe15315SJed Brown   ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
355dfe15315SJed Brown   ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr);
356dfe15315SJed Brown   ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr);
357dfe15315SJed Brown   ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
358dfe15315SJed Brown   if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);}
359dfe15315SJed Brown   PetscFunctionReturn(0);
360dfe15315SJed Brown }
361dfe15315SJed Brown 
362dfe15315SJed Brown #undef __FUNCT__
363caa4e7f2SJed Brown #define __FUNCT__ "KSPComputeOperators_SNES"
364a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can
365a6950cb2SJed Brown  * safely call SNESGetDM() in their residual evaluation routine. */
366caa4e7f2SJed Brown static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,MatStructure *mstruct,void *ctx)
367caa4e7f2SJed Brown {
368caa4e7f2SJed Brown   SNES snes = (SNES)ctx;
369caa4e7f2SJed Brown   PetscErrorCode ierr;
370caa4e7f2SJed Brown   Mat Asave = A,Bsave = B;
371dfe15315SJed Brown   Vec X,Xnamed = PETSC_NULL;
372dfe15315SJed Brown   DM dmsave;
373caa4e7f2SJed Brown 
374caa4e7f2SJed Brown   PetscFunctionBegin;
375dfe15315SJed Brown   dmsave = snes->dm;
376dfe15315SJed Brown   ierr = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr);
377dfe15315SJed Brown   if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */
378dfe15315SJed Brown   else {                                     /* We are on a coarser level, this vec was initialized using a DM restrict hook */
379dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
380dfe15315SJed Brown     X = Xnamed;
381dfe15315SJed Brown   }
382dfe15315SJed Brown   ierr = SNESComputeJacobian(snes,X,&A,&B,mstruct);CHKERRQ(ierr);
383caa4e7f2SJed Brown   if (A != Asave || B != Bsave) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_SUP,"No support for changing matrices at this time");
384dfe15315SJed Brown   if (Xnamed) {
385dfe15315SJed Brown     ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
386dfe15315SJed Brown   }
387dfe15315SJed Brown   snes->dm = dmsave;
388caa4e7f2SJed Brown   PetscFunctionReturn(0);
389caa4e7f2SJed Brown }
390caa4e7f2SJed Brown 
391caa4e7f2SJed Brown #undef __FUNCT__
3926cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices"
3936cab3a1bSJed Brown /*@
3946cab3a1bSJed Brown    SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX()
3956cab3a1bSJed Brown 
3966cab3a1bSJed Brown    Collective
3976cab3a1bSJed Brown 
3986cab3a1bSJed Brown    Input Arguments:
3996cab3a1bSJed Brown .  snes - snes to configure
4006cab3a1bSJed Brown 
4016cab3a1bSJed Brown    Level: developer
4026cab3a1bSJed Brown 
4036cab3a1bSJed Brown .seealso: SNESSetUp()
4046cab3a1bSJed Brown @*/
4056cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes)
4066cab3a1bSJed Brown {
4076cab3a1bSJed Brown   PetscErrorCode ierr;
4086cab3a1bSJed Brown   DM             dm;
4096cab3a1bSJed Brown   SNESDM         sdm;
4106cab3a1bSJed Brown 
4116cab3a1bSJed Brown   PetscFunctionBegin;
4126cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4136cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
414caa4e7f2SJed Brown   if (!sdm->computejacobian) {
4156cab3a1bSJed Brown     Mat J,B;
4166cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4176cab3a1bSJed Brown     if (snes->mf_operator) {
4186cab3a1bSJed Brown       ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4196cab3a1bSJed Brown       ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4206cab3a1bSJed Brown       ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4216cab3a1bSJed Brown     } else {
4226cab3a1bSJed Brown       J = B;
4236cab3a1bSJed Brown       ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
4246cab3a1bSJed Brown     }
4256cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr);
4266cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
4276cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
4286cab3a1bSJed Brown   } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) {
4296cab3a1bSJed Brown     Mat J;
4306cab3a1bSJed Brown     void *functx;
4316cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4326cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4336cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4346cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
4356cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
4366cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
437caa4e7f2SJed Brown   } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
4386cab3a1bSJed Brown     Mat J,B;
4396cab3a1bSJed Brown     void *functx;
4406cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4416cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4426cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4436cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4446cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
4456cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,functx);CHKERRQ(ierr);
4466cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
4476cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
448caa4e7f2SJed Brown   } else if (!snes->jacobian_pre) {
4496cab3a1bSJed Brown     Mat J,B;
4506cab3a1bSJed Brown     J = snes->jacobian;
4516cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4526cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
4536cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
4546cab3a1bSJed Brown   }
455caa4e7f2SJed Brown   {
45660a3618bSJed Brown     PetscBool flg = PETSC_FALSE;
457caa4e7f2SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_kspcompute",&flg,PETSC_NULL);CHKERRQ(ierr);
458caa4e7f2SJed Brown     if (flg) {                  /* Plan to transition to this model */
459caa4e7f2SJed Brown       KSP ksp;
460caa4e7f2SJed Brown       ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
461caa4e7f2SJed Brown       ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr);
462dfe15315SJed Brown       ierr = DMCoarsenHookAdd(snes->dm,PETSC_NULL,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr);
463caa4e7f2SJed Brown     }
464caa4e7f2SJed Brown   }
4656cab3a1bSJed Brown   PetscFunctionReturn(0);
4666cab3a1bSJed Brown }
4676cab3a1bSJed Brown 
4686cab3a1bSJed Brown #undef __FUNCT__
4694a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions"
4709b94acceSBarry Smith /*@
47194b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
4729b94acceSBarry Smith 
473c7afd0dbSLois Curfman McInnes    Collective on SNES
474c7afd0dbSLois Curfman McInnes 
4759b94acceSBarry Smith    Input Parameter:
4769b94acceSBarry Smith .  snes - the SNES context
4779b94acceSBarry Smith 
47836851e7fSLois Curfman McInnes    Options Database Keys:
479ea630c6eSPeter Brune +  -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas
48082738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
48182738288SBarry Smith                 of the change in the solution between steps
48270441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
483b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
484b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
485b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
4864839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
487ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
488a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
489e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
490b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
4912492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
49282738288SBarry Smith                                solver; hence iterations will continue until max_it
4931fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
49482738288SBarry Smith                                of convergence test
495e8105e01SRichard Katz .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
496e8105e01SRichard Katz                                        filename given prints to stdout
497a6570f20SBarry Smith .  -snes_monitor_solution - plots solution at each iteration
498a6570f20SBarry Smith .  -snes_monitor_residual - plots residual (not its norm) at each iteration
499a6570f20SBarry Smith .  -snes_monitor_solution_update - plots update to solution at each iteration
500a6570f20SBarry Smith .  -snes_monitor_draw - plots residual norm at each iteration
501e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
5025968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
503fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
50482738288SBarry Smith 
50582738288SBarry Smith     Options Database for Eisenstat-Walker method:
506fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
5074b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
50836851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
50936851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
51036851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
51136851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
51236851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
51336851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
51482738288SBarry Smith 
51511ca99fdSLois Curfman McInnes    Notes:
51611ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
5170598bfebSBarry Smith    the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>.
51883e2fdc7SBarry Smith 
51936851e7fSLois Curfman McInnes    Level: beginner
52036851e7fSLois Curfman McInnes 
5219b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
5229b94acceSBarry Smith 
52369ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
5249b94acceSBarry Smith @*/
5257087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
5269b94acceSBarry Smith {
527872b6db9SPeter Brune   PetscBool               flg,mf,mf_operator,pcset;
528efd51863SBarry Smith   PetscInt                i,indx,lag,mf_version,grids;
529aa3661deSLisandro Dalcin   MatStructure            matflag;
53085385478SLisandro Dalcin   const char              *deft = SNESLS;
53185385478SLisandro Dalcin   const char              *convtests[] = {"default","skip"};
53285385478SLisandro Dalcin   SNESKSPEW               *kctx = NULL;
533e8105e01SRichard Katz   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
53451e86f29SPeter Brune   const char              *optionsprefix;
535649052a6SBarry Smith   PetscViewer             monviewer;
53685385478SLisandro Dalcin   PetscErrorCode          ierr;
5379b94acceSBarry Smith 
5383a40ed3dSBarry Smith   PetscFunctionBegin;
5390700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
540ca161407SBarry Smith 
541186905e3SBarry Smith   if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
5423194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
5437adad957SLisandro Dalcin     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
544b0a32e0cSBarry Smith     ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
545d64ed03dSBarry Smith     if (flg) {
546186905e3SBarry Smith       ierr = SNESSetType(snes,type);CHKERRQ(ierr);
5477adad957SLisandro Dalcin     } else if (!((PetscObject)snes)->type_name) {
548186905e3SBarry Smith       ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
549d64ed03dSBarry Smith     }
55090d69ab7SBarry Smith     /* not used here, but called so will go into help messaage */
551909c8a9fSBarry Smith     ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr);
55293c39befSBarry Smith 
553c60f73f4SPeter Brune     ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);CHKERRQ(ierr);
55457034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr);
555186905e3SBarry Smith 
55657034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr);
557b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr);
558b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr);
55924254dc1SJed Brown     ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr);
560ddf469c8SBarry Smith     ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr);
561acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr);
56285385478SLisandro Dalcin 
563a8054027SBarry Smith     ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
564a8054027SBarry Smith     if (flg) {
565a8054027SBarry Smith       ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
566a8054027SBarry Smith     }
567e35cf81dSBarry Smith     ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
568e35cf81dSBarry Smith     if (flg) {
569e35cf81dSBarry Smith       ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
570e35cf81dSBarry Smith     }
571efd51863SBarry Smith     ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
572efd51863SBarry Smith     if (flg) {
573efd51863SBarry Smith       ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
574efd51863SBarry Smith     }
575a8054027SBarry Smith 
57685385478SLisandro Dalcin     ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
57785385478SLisandro Dalcin     if (flg) {
57885385478SLisandro Dalcin       switch (indx) {
5797f7931b9SBarry Smith       case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break;
5807f7931b9SBarry Smith       case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);    break;
58185385478SLisandro Dalcin       }
58285385478SLisandro Dalcin     }
58385385478SLisandro Dalcin 
584acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr);
585186905e3SBarry Smith 
586fdacfa88SPeter Brune     ierr = PetscOptionsEList("-snes_norm_type","SNES Norm type","SNESSetNormType",SNESNormTypes,5,"function",&indx,&flg);CHKERRQ(ierr);
587fdacfa88SPeter Brune     if (flg) { ierr = SNESSetNormType(snes,(SNESNormType)indx);CHKERRQ(ierr); }
588fdacfa88SPeter Brune 
58985385478SLisandro Dalcin     kctx = (SNESKSPEW *)snes->kspconvctx;
59085385478SLisandro Dalcin 
591acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr);
592186905e3SBarry Smith 
593fa9f3622SBarry Smith     ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr);
594fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr);
595fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr);
596fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr);
597fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr);
598fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr);
599fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr);
600186905e3SBarry Smith 
60190d69ab7SBarry Smith     flg  = PETSC_FALSE;
602acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
603a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
604eabae89aSBarry Smith 
605a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
606e8105e01SRichard Katz     if (flg) {
607649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
608649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
609e8105e01SRichard Katz     }
610eabae89aSBarry Smith 
611b271bb04SBarry Smith     ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
612b271bb04SBarry Smith     if (flg) {
613b271bb04SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr);
614b271bb04SBarry Smith     }
615b271bb04SBarry Smith 
616a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
617eabae89aSBarry Smith     if (flg) {
618649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
619f1bef1bcSMatthew Knepley       ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr);
620e8105e01SRichard Katz     }
621eabae89aSBarry Smith 
622a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
623eabae89aSBarry Smith     if (flg) {
624649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
625649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
626eabae89aSBarry Smith     }
627eabae89aSBarry Smith 
6285180491cSLisandro Dalcin     ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
6295180491cSLisandro Dalcin     if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);}
6305180491cSLisandro Dalcin 
63190d69ab7SBarry Smith     flg  = PETSC_FALSE;
632acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
633a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
63490d69ab7SBarry Smith     flg  = PETSC_FALSE;
635acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
636a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
63790d69ab7SBarry Smith     flg  = PETSC_FALSE;
638acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
639a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
64090d69ab7SBarry Smith     flg  = PETSC_FALSE;
641acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
642a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
64390d69ab7SBarry Smith     flg  = PETSC_FALSE;
644acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
645b271bb04SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
646e24b481bSBarry Smith 
64790d69ab7SBarry Smith     flg  = PETSC_FALSE;
648acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
6494b27c08aSLois Curfman McInnes     if (flg) {
6506cab3a1bSJed Brown       void *functx;
6516cab3a1bSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
6526cab3a1bSJed Brown       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr);
653ae15b995SBarry Smith       ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
6549b94acceSBarry Smith     }
655639f9d9dSBarry Smith 
656aa3661deSLisandro Dalcin     mf = mf_operator = PETSC_FALSE;
657aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
658acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr);
659a8248277SBarry Smith     if (flg && mf_operator) {
660a8248277SBarry Smith       snes->mf_operator = PETSC_TRUE;
661a8248277SBarry Smith       mf = PETSC_TRUE;
662a8248277SBarry Smith     }
663aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
664acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr);
665aa3661deSLisandro Dalcin     if (!flg && mf_operator) mf = PETSC_TRUE;
666aa3661deSLisandro Dalcin     mf_version = 1;
667aa3661deSLisandro Dalcin     ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr);
668aa3661deSLisandro Dalcin 
669d28543b3SPeter Brune 
67089b92e6fSPeter Brune     /* GS Options */
67189b92e6fSPeter Brune     ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr);
67289b92e6fSPeter Brune 
67376b2cf59SMatthew Knepley     for(i = 0; i < numberofsetfromoptions; i++) {
67476b2cf59SMatthew Knepley       ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
67576b2cf59SMatthew Knepley     }
67676b2cf59SMatthew Knepley 
677e7788613SBarry Smith     if (snes->ops->setfromoptions) {
678e7788613SBarry Smith       ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr);
679639f9d9dSBarry Smith     }
6805d973c19SBarry Smith 
6815d973c19SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
6825d973c19SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr);
683b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
6844bbc92c1SBarry Smith 
685aa3661deSLisandro Dalcin   if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); }
6861cee3971SBarry Smith 
6871cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
688aa3661deSLisandro Dalcin   ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
689aa3661deSLisandro Dalcin   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr);
69085385478SLisandro Dalcin   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
69193993e2dSLois Curfman McInnes 
6929e764e56SPeter Brune   if (!snes->linesearch) {
693f1c6b773SPeter Brune     ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
6949e764e56SPeter Brune   }
695f1c6b773SPeter Brune   ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr);
6969e764e56SPeter Brune 
69751e86f29SPeter Brune   /* if someone has set the SNES PC type, create it. */
69851e86f29SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
69951e86f29SPeter Brune   ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr);
70051e86f29SPeter Brune   if (pcset && (!snes->pc)) {
70151e86f29SPeter Brune     ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr);
70251e86f29SPeter Brune   }
7034a0c5b0cSMatthew G Knepley   if (snes->pc) {
704fde0ff24SPeter Brune     ierr = SNESSetOptionsPrefix(snes->pc, optionsprefix);CHKERRQ(ierr);
705fde0ff24SPeter Brune     ierr = SNESAppendOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr);
7064a0c5b0cSMatthew G Knepley     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
70788976e71SPeter Brune     /* default to 1 iteration */
70888976e71SPeter Brune     ierr = SNESSetTolerances(snes->pc, snes->pc->abstol, snes->pc->rtol, snes->pc->stol, 1, snes->pc->max_funcs);CHKERRQ(ierr);
709534ebe21SPeter Brune     ierr = SNESSetNormType(snes->pc, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr);
7104a0c5b0cSMatthew G Knepley     ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr);
7114a0c5b0cSMatthew G Knepley   }
7123a40ed3dSBarry Smith   PetscFunctionReturn(0);
7139b94acceSBarry Smith }
7149b94acceSBarry Smith 
715d25893d9SBarry Smith #undef __FUNCT__
716d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext"
717d25893d9SBarry Smith /*@
718d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
719d25893d9SBarry Smith    the nonlinear solvers.
720d25893d9SBarry Smith 
721d25893d9SBarry Smith    Logically Collective on SNES
722d25893d9SBarry Smith 
723d25893d9SBarry Smith    Input Parameters:
724d25893d9SBarry Smith +  snes - the SNES context
725d25893d9SBarry Smith .  compute - function to compute the context
726d25893d9SBarry Smith -  destroy - function to destroy the context
727d25893d9SBarry Smith 
728d25893d9SBarry Smith    Level: intermediate
729d25893d9SBarry Smith 
730d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
731d25893d9SBarry Smith 
732d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
733d25893d9SBarry Smith @*/
734d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
735d25893d9SBarry Smith {
736d25893d9SBarry Smith   PetscFunctionBegin;
737d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
738d25893d9SBarry Smith   snes->ops->usercompute = compute;
739d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
740d25893d9SBarry Smith   PetscFunctionReturn(0);
741d25893d9SBarry Smith }
742a847f771SSatish Balay 
7434a2ae208SSatish Balay #undef __FUNCT__
7444a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
745b07ff414SBarry Smith /*@
7469b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
7479b94acceSBarry Smith    the nonlinear solvers.
7489b94acceSBarry Smith 
7493f9fe445SBarry Smith    Logically Collective on SNES
750fee21e36SBarry Smith 
751c7afd0dbSLois Curfman McInnes    Input Parameters:
752c7afd0dbSLois Curfman McInnes +  snes - the SNES context
753c7afd0dbSLois Curfman McInnes -  usrP - optional user context
754c7afd0dbSLois Curfman McInnes 
75536851e7fSLois Curfman McInnes    Level: intermediate
75636851e7fSLois Curfman McInnes 
7579b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
7589b94acceSBarry Smith 
759d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext()
7609b94acceSBarry Smith @*/
7617087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
7629b94acceSBarry Smith {
7631b2093e4SBarry Smith   PetscErrorCode ierr;
764b07ff414SBarry Smith   KSP            ksp;
7651b2093e4SBarry Smith 
7663a40ed3dSBarry Smith   PetscFunctionBegin;
7670700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
768b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
769b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
7709b94acceSBarry Smith   snes->user = usrP;
7713a40ed3dSBarry Smith   PetscFunctionReturn(0);
7729b94acceSBarry Smith }
77374679c65SBarry Smith 
7744a2ae208SSatish Balay #undef __FUNCT__
7754a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
776b07ff414SBarry Smith /*@
7779b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
7789b94acceSBarry Smith    nonlinear solvers.
7799b94acceSBarry Smith 
780c7afd0dbSLois Curfman McInnes    Not Collective
781c7afd0dbSLois Curfman McInnes 
7829b94acceSBarry Smith    Input Parameter:
7839b94acceSBarry Smith .  snes - SNES context
7849b94acceSBarry Smith 
7859b94acceSBarry Smith    Output Parameter:
7869b94acceSBarry Smith .  usrP - user context
7879b94acceSBarry Smith 
78836851e7fSLois Curfman McInnes    Level: intermediate
78936851e7fSLois Curfman McInnes 
7909b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
7919b94acceSBarry Smith 
7929b94acceSBarry Smith .seealso: SNESSetApplicationContext()
7939b94acceSBarry Smith @*/
794e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
7959b94acceSBarry Smith {
7963a40ed3dSBarry Smith   PetscFunctionBegin;
7970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
798e71120c6SJed Brown   *(void**)usrP = snes->user;
7993a40ed3dSBarry Smith   PetscFunctionReturn(0);
8009b94acceSBarry Smith }
80174679c65SBarry Smith 
8024a2ae208SSatish Balay #undef __FUNCT__
8034a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
8049b94acceSBarry Smith /*@
805c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
806c8228a4eSBarry Smith    at this time.
8079b94acceSBarry Smith 
808c7afd0dbSLois Curfman McInnes    Not Collective
809c7afd0dbSLois Curfman McInnes 
8109b94acceSBarry Smith    Input Parameter:
8119b94acceSBarry Smith .  snes - SNES context
8129b94acceSBarry Smith 
8139b94acceSBarry Smith    Output Parameter:
8149b94acceSBarry Smith .  iter - iteration number
8159b94acceSBarry Smith 
816c8228a4eSBarry Smith    Notes:
817c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
818c8228a4eSBarry Smith 
819c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
82008405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
82108405cd6SLois Curfman McInnes .vb
82208405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
82308405cd6SLois Curfman McInnes       if (!(it % 2)) {
82408405cd6SLois Curfman McInnes         [compute Jacobian here]
82508405cd6SLois Curfman McInnes       }
82608405cd6SLois Curfman McInnes .ve
827c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
82808405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
829c8228a4eSBarry Smith 
83036851e7fSLois Curfman McInnes    Level: intermediate
83136851e7fSLois Curfman McInnes 
8322b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
8332b668275SBarry Smith 
834b850b91aSLisandro Dalcin .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
8359b94acceSBarry Smith @*/
8367087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
8379b94acceSBarry Smith {
8383a40ed3dSBarry Smith   PetscFunctionBegin;
8390700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8404482741eSBarry Smith   PetscValidIntPointer(iter,2);
8419b94acceSBarry Smith   *iter = snes->iter;
8423a40ed3dSBarry Smith   PetscFunctionReturn(0);
8439b94acceSBarry Smith }
84474679c65SBarry Smith 
8454a2ae208SSatish Balay #undef __FUNCT__
846360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber"
847360c497dSPeter Brune /*@
848360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
849360c497dSPeter Brune 
850360c497dSPeter Brune    Not Collective
851360c497dSPeter Brune 
852360c497dSPeter Brune    Input Parameter:
853360c497dSPeter Brune .  snes - SNES context
854360c497dSPeter Brune .  iter - iteration number
855360c497dSPeter Brune 
856360c497dSPeter Brune    Level: developer
857360c497dSPeter Brune 
858360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number,
859360c497dSPeter Brune 
860360c497dSPeter Brune .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
861360c497dSPeter Brune @*/
862360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
863360c497dSPeter Brune {
864360c497dSPeter Brune   PetscErrorCode ierr;
865360c497dSPeter Brune 
866360c497dSPeter Brune   PetscFunctionBegin;
867360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
868360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
869360c497dSPeter Brune   snes->iter = iter;
870360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
871360c497dSPeter Brune   PetscFunctionReturn(0);
872360c497dSPeter Brune }
873360c497dSPeter Brune 
874360c497dSPeter Brune #undef __FUNCT__
8754a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm"
8769b94acceSBarry Smith /*@
8779b94acceSBarry Smith    SNESGetFunctionNorm - Gets the norm of the current function that was set
8789b94acceSBarry Smith    with SNESSSetFunction().
8799b94acceSBarry Smith 
880c7afd0dbSLois Curfman McInnes    Collective on SNES
881c7afd0dbSLois Curfman McInnes 
8829b94acceSBarry Smith    Input Parameter:
8839b94acceSBarry Smith .  snes - SNES context
8849b94acceSBarry Smith 
8859b94acceSBarry Smith    Output Parameter:
8869b94acceSBarry Smith .  fnorm - 2-norm of function
8879b94acceSBarry Smith 
88836851e7fSLois Curfman McInnes    Level: intermediate
88936851e7fSLois Curfman McInnes 
8909b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm
891a86d99e1SLois Curfman McInnes 
892b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
8939b94acceSBarry Smith @*/
8947087cfbeSBarry Smith PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
8959b94acceSBarry Smith {
8963a40ed3dSBarry Smith   PetscFunctionBegin;
8970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8984482741eSBarry Smith   PetscValidScalarPointer(fnorm,2);
8999b94acceSBarry Smith   *fnorm = snes->norm;
9003a40ed3dSBarry Smith   PetscFunctionReturn(0);
9019b94acceSBarry Smith }
90274679c65SBarry Smith 
903360c497dSPeter Brune 
904360c497dSPeter Brune #undef __FUNCT__
905360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm"
906360c497dSPeter Brune /*@
907360c497dSPeter Brune    SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm().
908360c497dSPeter Brune 
909360c497dSPeter Brune    Collective on SNES
910360c497dSPeter Brune 
911360c497dSPeter Brune    Input Parameter:
912360c497dSPeter Brune .  snes - SNES context
913360c497dSPeter Brune .  fnorm - 2-norm of function
914360c497dSPeter Brune 
915360c497dSPeter Brune    Level: developer
916360c497dSPeter Brune 
917360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm
918360c497dSPeter Brune 
919360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm().
920360c497dSPeter Brune @*/
921360c497dSPeter Brune PetscErrorCode  SNESSetFunctionNorm(SNES snes,PetscReal fnorm)
922360c497dSPeter Brune {
923360c497dSPeter Brune 
924360c497dSPeter Brune   PetscErrorCode ierr;
925360c497dSPeter Brune 
926360c497dSPeter Brune   PetscFunctionBegin;
927360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
928360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
929360c497dSPeter Brune   snes->norm = fnorm;
930360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
931360c497dSPeter Brune   PetscFunctionReturn(0);
932360c497dSPeter Brune }
933360c497dSPeter Brune 
9344a2ae208SSatish Balay #undef __FUNCT__
935b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
9369b94acceSBarry Smith /*@
937b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
9389b94acceSBarry Smith    attempted by the nonlinear solver.
9399b94acceSBarry Smith 
940c7afd0dbSLois Curfman McInnes    Not Collective
941c7afd0dbSLois Curfman McInnes 
9429b94acceSBarry Smith    Input Parameter:
9439b94acceSBarry Smith .  snes - SNES context
9449b94acceSBarry Smith 
9459b94acceSBarry Smith    Output Parameter:
9469b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
9479b94acceSBarry Smith 
948c96a6f78SLois Curfman McInnes    Notes:
949c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
950c96a6f78SLois Curfman McInnes 
95136851e7fSLois Curfman McInnes    Level: intermediate
95236851e7fSLois Curfman McInnes 
9539b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
95458ebbce7SBarry Smith 
955e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
95658ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
9579b94acceSBarry Smith @*/
9587087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
9599b94acceSBarry Smith {
9603a40ed3dSBarry Smith   PetscFunctionBegin;
9610700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9624482741eSBarry Smith   PetscValidIntPointer(nfails,2);
96350ffb88aSMatthew Knepley   *nfails = snes->numFailures;
96450ffb88aSMatthew Knepley   PetscFunctionReturn(0);
96550ffb88aSMatthew Knepley }
96650ffb88aSMatthew Knepley 
96750ffb88aSMatthew Knepley #undef __FUNCT__
968b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
96950ffb88aSMatthew Knepley /*@
970b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
97150ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
97250ffb88aSMatthew Knepley 
97350ffb88aSMatthew Knepley    Not Collective
97450ffb88aSMatthew Knepley 
97550ffb88aSMatthew Knepley    Input Parameters:
97650ffb88aSMatthew Knepley +  snes     - SNES context
97750ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
97850ffb88aSMatthew Knepley 
97950ffb88aSMatthew Knepley    Level: intermediate
98050ffb88aSMatthew Knepley 
98150ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
98258ebbce7SBarry Smith 
983e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
98458ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
98550ffb88aSMatthew Knepley @*/
9867087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
98750ffb88aSMatthew Knepley {
98850ffb88aSMatthew Knepley   PetscFunctionBegin;
9890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
99050ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
99150ffb88aSMatthew Knepley   PetscFunctionReturn(0);
99250ffb88aSMatthew Knepley }
99350ffb88aSMatthew Knepley 
99450ffb88aSMatthew Knepley #undef __FUNCT__
995b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
99650ffb88aSMatthew Knepley /*@
997b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
99850ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
99950ffb88aSMatthew Knepley 
100050ffb88aSMatthew Knepley    Not Collective
100150ffb88aSMatthew Knepley 
100250ffb88aSMatthew Knepley    Input Parameter:
100350ffb88aSMatthew Knepley .  snes     - SNES context
100450ffb88aSMatthew Knepley 
100550ffb88aSMatthew Knepley    Output Parameter:
100650ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
100750ffb88aSMatthew Knepley 
100850ffb88aSMatthew Knepley    Level: intermediate
100950ffb88aSMatthew Knepley 
101050ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
101158ebbce7SBarry Smith 
1012e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
101358ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
101458ebbce7SBarry Smith 
101550ffb88aSMatthew Knepley @*/
10167087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
101750ffb88aSMatthew Knepley {
101850ffb88aSMatthew Knepley   PetscFunctionBegin;
10190700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10204482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
102150ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
10223a40ed3dSBarry Smith   PetscFunctionReturn(0);
10239b94acceSBarry Smith }
1024a847f771SSatish Balay 
10254a2ae208SSatish Balay #undef __FUNCT__
10262541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
10272541af92SBarry Smith /*@
10282541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
10292541af92SBarry Smith      done by SNES.
10302541af92SBarry Smith 
10312541af92SBarry Smith    Not Collective
10322541af92SBarry Smith 
10332541af92SBarry Smith    Input Parameter:
10342541af92SBarry Smith .  snes     - SNES context
10352541af92SBarry Smith 
10362541af92SBarry Smith    Output Parameter:
10372541af92SBarry Smith .  nfuncs - number of evaluations
10382541af92SBarry Smith 
10392541af92SBarry Smith    Level: intermediate
10402541af92SBarry Smith 
10412541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
104258ebbce7SBarry Smith 
1043e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
10442541af92SBarry Smith @*/
10457087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
10462541af92SBarry Smith {
10472541af92SBarry Smith   PetscFunctionBegin;
10480700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10492541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
10502541af92SBarry Smith   *nfuncs = snes->nfuncs;
10512541af92SBarry Smith   PetscFunctionReturn(0);
10522541af92SBarry Smith }
10532541af92SBarry Smith 
10542541af92SBarry Smith #undef __FUNCT__
10553d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
10563d4c4710SBarry Smith /*@
10573d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
10583d4c4710SBarry Smith    linear solvers.
10593d4c4710SBarry Smith 
10603d4c4710SBarry Smith    Not Collective
10613d4c4710SBarry Smith 
10623d4c4710SBarry Smith    Input Parameter:
10633d4c4710SBarry Smith .  snes - SNES context
10643d4c4710SBarry Smith 
10653d4c4710SBarry Smith    Output Parameter:
10663d4c4710SBarry Smith .  nfails - number of failed solves
10673d4c4710SBarry Smith 
10683d4c4710SBarry Smith    Notes:
10693d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
10703d4c4710SBarry Smith 
10713d4c4710SBarry Smith    Level: intermediate
10723d4c4710SBarry Smith 
10733d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
107458ebbce7SBarry Smith 
1075e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
10763d4c4710SBarry Smith @*/
10777087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
10783d4c4710SBarry Smith {
10793d4c4710SBarry Smith   PetscFunctionBegin;
10800700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10813d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
10823d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
10833d4c4710SBarry Smith   PetscFunctionReturn(0);
10843d4c4710SBarry Smith }
10853d4c4710SBarry Smith 
10863d4c4710SBarry Smith #undef __FUNCT__
10873d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
10883d4c4710SBarry Smith /*@
10893d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
10903d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
10913d4c4710SBarry Smith 
10923f9fe445SBarry Smith    Logically Collective on SNES
10933d4c4710SBarry Smith 
10943d4c4710SBarry Smith    Input Parameters:
10953d4c4710SBarry Smith +  snes     - SNES context
10963d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
10973d4c4710SBarry Smith 
10983d4c4710SBarry Smith    Level: intermediate
10993d4c4710SBarry Smith 
1100a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
11013d4c4710SBarry Smith 
11023d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
11033d4c4710SBarry Smith 
110458ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
11053d4c4710SBarry Smith @*/
11067087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
11073d4c4710SBarry Smith {
11083d4c4710SBarry Smith   PetscFunctionBegin;
11090700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1110c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
11113d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
11123d4c4710SBarry Smith   PetscFunctionReturn(0);
11133d4c4710SBarry Smith }
11143d4c4710SBarry Smith 
11153d4c4710SBarry Smith #undef __FUNCT__
11163d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
11173d4c4710SBarry Smith /*@
11183d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
11193d4c4710SBarry Smith      are allowed before SNES terminates
11203d4c4710SBarry Smith 
11213d4c4710SBarry Smith    Not Collective
11223d4c4710SBarry Smith 
11233d4c4710SBarry Smith    Input Parameter:
11243d4c4710SBarry Smith .  snes     - SNES context
11253d4c4710SBarry Smith 
11263d4c4710SBarry Smith    Output Parameter:
11273d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
11283d4c4710SBarry Smith 
11293d4c4710SBarry Smith    Level: intermediate
11303d4c4710SBarry Smith 
11313d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
11323d4c4710SBarry Smith 
11333d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
11343d4c4710SBarry Smith 
1135e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
11363d4c4710SBarry Smith @*/
11377087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
11383d4c4710SBarry Smith {
11393d4c4710SBarry Smith   PetscFunctionBegin;
11400700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11413d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
11423d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
11433d4c4710SBarry Smith   PetscFunctionReturn(0);
11443d4c4710SBarry Smith }
11453d4c4710SBarry Smith 
11463d4c4710SBarry Smith #undef __FUNCT__
1147b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
1148c96a6f78SLois Curfman McInnes /*@
1149b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1150c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1151c96a6f78SLois Curfman McInnes 
1152c7afd0dbSLois Curfman McInnes    Not Collective
1153c7afd0dbSLois Curfman McInnes 
1154c96a6f78SLois Curfman McInnes    Input Parameter:
1155c96a6f78SLois Curfman McInnes .  snes - SNES context
1156c96a6f78SLois Curfman McInnes 
1157c96a6f78SLois Curfman McInnes    Output Parameter:
1158c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1159c96a6f78SLois Curfman McInnes 
1160c96a6f78SLois Curfman McInnes    Notes:
1161c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1162c96a6f78SLois Curfman McInnes 
116336851e7fSLois Curfman McInnes    Level: intermediate
116436851e7fSLois Curfman McInnes 
1165c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
11662b668275SBarry Smith 
11678c7482ecSBarry Smith .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
1168c96a6f78SLois Curfman McInnes @*/
11697087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
1170c96a6f78SLois Curfman McInnes {
11713a40ed3dSBarry Smith   PetscFunctionBegin;
11720700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11734482741eSBarry Smith   PetscValidIntPointer(lits,2);
1174c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
11753a40ed3dSBarry Smith   PetscFunctionReturn(0);
1176c96a6f78SLois Curfman McInnes }
1177c96a6f78SLois Curfman McInnes 
11784a2ae208SSatish Balay #undef __FUNCT__
117994b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP"
118052baeb72SSatish Balay /*@
118194b7f48cSBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
11829b94acceSBarry Smith 
118394b7f48cSBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
1184c7afd0dbSLois Curfman McInnes 
11859b94acceSBarry Smith    Input Parameter:
11869b94acceSBarry Smith .  snes - the SNES context
11879b94acceSBarry Smith 
11889b94acceSBarry Smith    Output Parameter:
118994b7f48cSBarry Smith .  ksp - the KSP context
11909b94acceSBarry Smith 
11919b94acceSBarry Smith    Notes:
119294b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
11939b94acceSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
11942999313aSBarry Smith    PC contexts as well.
11959b94acceSBarry Smith 
119636851e7fSLois Curfman McInnes    Level: beginner
119736851e7fSLois Curfman McInnes 
119894b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
11999b94acceSBarry Smith 
12002999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
12019b94acceSBarry Smith @*/
12027087cfbeSBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
12039b94acceSBarry Smith {
12041cee3971SBarry Smith   PetscErrorCode ierr;
12051cee3971SBarry Smith 
12063a40ed3dSBarry Smith   PetscFunctionBegin;
12070700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12084482741eSBarry Smith   PetscValidPointer(ksp,2);
12091cee3971SBarry Smith 
12101cee3971SBarry Smith   if (!snes->ksp) {
12111cee3971SBarry Smith     ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr);
12121cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
12131cee3971SBarry Smith     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
12141cee3971SBarry Smith   }
121594b7f48cSBarry Smith   *ksp = snes->ksp;
12163a40ed3dSBarry Smith   PetscFunctionReturn(0);
12179b94acceSBarry Smith }
121882bf6240SBarry Smith 
12194a2ae208SSatish Balay #undef __FUNCT__
12202999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
12212999313aSBarry Smith /*@
12222999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
12232999313aSBarry Smith 
12242999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
12252999313aSBarry Smith 
12262999313aSBarry Smith    Input Parameters:
12272999313aSBarry Smith +  snes - the SNES context
12282999313aSBarry Smith -  ksp - the KSP context
12292999313aSBarry Smith 
12302999313aSBarry Smith    Notes:
12312999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
12322999313aSBarry Smith    so this routine is rarely needed.
12332999313aSBarry Smith 
12342999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
12352999313aSBarry Smith    decreased by one.
12362999313aSBarry Smith 
12372999313aSBarry Smith    Level: developer
12382999313aSBarry Smith 
12392999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
12402999313aSBarry Smith 
12412999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
12422999313aSBarry Smith @*/
12437087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
12442999313aSBarry Smith {
12452999313aSBarry Smith   PetscErrorCode ierr;
12462999313aSBarry Smith 
12472999313aSBarry Smith   PetscFunctionBegin;
12480700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12490700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
12502999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
12517dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1252906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
12532999313aSBarry Smith   snes->ksp = ksp;
12542999313aSBarry Smith   PetscFunctionReturn(0);
12552999313aSBarry Smith }
12562999313aSBarry Smith 
12577adad957SLisandro Dalcin #if 0
12582999313aSBarry Smith #undef __FUNCT__
12594a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc"
12606849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
1261e24b481bSBarry Smith {
1262e24b481bSBarry Smith   PetscFunctionBegin;
1263e24b481bSBarry Smith   PetscFunctionReturn(0);
1264e24b481bSBarry Smith }
12657adad957SLisandro Dalcin #endif
1266e24b481bSBarry Smith 
12679b94acceSBarry Smith /* -----------------------------------------------------------*/
12684a2ae208SSatish Balay #undef __FUNCT__
12694a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
127052baeb72SSatish Balay /*@
12719b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
12729b94acceSBarry Smith 
1273c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1274c7afd0dbSLois Curfman McInnes 
1275c7afd0dbSLois Curfman McInnes    Input Parameters:
1276906ed7ccSBarry Smith .  comm - MPI communicator
12779b94acceSBarry Smith 
12789b94acceSBarry Smith    Output Parameter:
12799b94acceSBarry Smith .  outsnes - the new SNES context
12809b94acceSBarry Smith 
1281c7afd0dbSLois Curfman McInnes    Options Database Keys:
1282c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1283c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1284c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1285c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1286c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1287c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1288c1f60f51SBarry Smith 
128936851e7fSLois Curfman McInnes    Level: beginner
129036851e7fSLois Curfman McInnes 
12919b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
12929b94acceSBarry Smith 
1293a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1294a8054027SBarry Smith 
12959b94acceSBarry Smith @*/
12967087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
12979b94acceSBarry Smith {
1298dfbe8321SBarry Smith   PetscErrorCode      ierr;
12999b94acceSBarry Smith   SNES                snes;
1300fa9f3622SBarry Smith   SNESKSPEW           *kctx;
130137fcc0dbSBarry Smith 
13023a40ed3dSBarry Smith   PetscFunctionBegin;
1303ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
13048ba1e511SMatthew Knepley   *outsnes = PETSC_NULL;
13058ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
13068ba1e511SMatthew Knepley   ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr);
13078ba1e511SMatthew Knepley #endif
13088ba1e511SMatthew Knepley 
13093194b578SJed Brown   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
13107adad957SLisandro Dalcin 
131185385478SLisandro Dalcin   snes->ops->converged    = SNESDefaultConverged;
13122c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
131388976e71SPeter Brune   snes->tolerancesset     = PETSC_FALSE;
13149b94acceSBarry Smith   snes->max_its           = 50;
13159750a799SBarry Smith   snes->max_funcs         = 10000;
13169b94acceSBarry Smith   snes->norm              = 0.0;
1317fdacfa88SPeter Brune   snes->normtype          = SNES_NORM_FUNCTION;
1318b4874afaSBarry Smith   snes->rtol              = 1.e-8;
1319b4874afaSBarry Smith   snes->ttol              = 0.0;
132070441072SBarry Smith   snes->abstol            = 1.e-50;
1321c60f73f4SPeter Brune   snes->stol              = 1.e-8;
13224b27c08aSLois Curfman McInnes   snes->deltatol          = 1.e-12;
13239b94acceSBarry Smith   snes->nfuncs            = 0;
132450ffb88aSMatthew Knepley   snes->numFailures       = 0;
132550ffb88aSMatthew Knepley   snes->maxFailures       = 1;
13267a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1327e35cf81dSBarry Smith   snes->lagjacobian       = 1;
1328a8054027SBarry Smith   snes->lagpreconditioner = 1;
1329639f9d9dSBarry Smith   snes->numbermonitors    = 0;
13309b94acceSBarry Smith   snes->data              = 0;
13314dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1332186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
13336f24a144SLois Curfman McInnes   snes->nwork             = 0;
133458c9b817SLisandro Dalcin   snes->work              = 0;
133558c9b817SLisandro Dalcin   snes->nvwork            = 0;
133658c9b817SLisandro Dalcin   snes->vwork             = 0;
1337758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1338758f92a0SBarry Smith   snes->conv_hist_max     = 0;
1339758f92a0SBarry Smith   snes->conv_hist         = PETSC_NULL;
1340758f92a0SBarry Smith   snes->conv_hist_its     = PETSC_NULL;
1341758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1342e4ed7901SPeter Brune   snes->vec_func_init_set = PETSC_FALSE;
1343e4ed7901SPeter Brune   snes->norm_init         = 0.;
1344e4ed7901SPeter Brune   snes->norm_init_set     = PETSC_FALSE;
1345184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
134689b92e6fSPeter Brune   snes->gssweeps          = 1;
13479b94acceSBarry Smith 
13483d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
13493d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
13503d4c4710SBarry Smith 
13519b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
135238f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr);
13539b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
13549b94acceSBarry Smith   kctx->version     = 2;
13559b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
13569b94acceSBarry Smith                              this was too large for some test cases */
135775567043SBarry Smith   kctx->rtol_last   = 0.0;
13589b94acceSBarry Smith   kctx->rtol_max    = .9;
13599b94acceSBarry Smith   kctx->gamma       = 1.0;
136062d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
136171f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
13629b94acceSBarry Smith   kctx->threshold   = .1;
136375567043SBarry Smith   kctx->lresid_last = 0.0;
136475567043SBarry Smith   kctx->norm_last   = 0.0;
13659b94acceSBarry Smith 
13669b94acceSBarry Smith   *outsnes = snes;
13673a40ed3dSBarry Smith   PetscFunctionReturn(0);
13689b94acceSBarry Smith }
13699b94acceSBarry Smith 
13704a2ae208SSatish Balay #undef __FUNCT__
13714a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
13729b94acceSBarry Smith /*@C
13739b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
13749b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
13759b94acceSBarry Smith    equations.
13769b94acceSBarry Smith 
13773f9fe445SBarry Smith    Logically Collective on SNES
1378fee21e36SBarry Smith 
1379c7afd0dbSLois Curfman McInnes    Input Parameters:
1380c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1381c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1382de044059SHong Zhang .  func - function evaluation routine
1383c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1384c7afd0dbSLois Curfman McInnes          function evaluation routine (may be PETSC_NULL)
13859b94acceSBarry Smith 
1386c7afd0dbSLois Curfman McInnes    Calling sequence of func:
13878d76a1e5SLois Curfman McInnes $    func (SNES snes,Vec x,Vec f,void *ctx);
1388c7afd0dbSLois Curfman McInnes 
1389c586c404SJed Brown +  snes - the SNES context
1390c586c404SJed Brown .  x - state at which to evaluate residual
1391c586c404SJed Brown .  f - vector to put residual
1392c7afd0dbSLois Curfman McInnes -  ctx - optional user-defined function context
13939b94acceSBarry Smith 
13949b94acceSBarry Smith    Notes:
13959b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
13969b94acceSBarry Smith $      f'(x) x = -f(x),
1397c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
13989b94acceSBarry Smith 
139936851e7fSLois Curfman McInnes    Level: beginner
140036851e7fSLois Curfman McInnes 
14019b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
14029b94acceSBarry Smith 
14038b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard()
14049b94acceSBarry Smith @*/
14057087cfbeSBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
14069b94acceSBarry Smith {
140785385478SLisandro Dalcin   PetscErrorCode ierr;
14086cab3a1bSJed Brown   DM             dm;
14096cab3a1bSJed Brown 
14103a40ed3dSBarry Smith   PetscFunctionBegin;
14110700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1412d2a683ecSLisandro Dalcin   if (r) {
1413d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1414d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
141585385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
14166bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
141785385478SLisandro Dalcin     snes->vec_func = r;
1418d2a683ecSLisandro Dalcin   }
14196cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
14206cab3a1bSJed Brown   ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr);
14213a40ed3dSBarry Smith   PetscFunctionReturn(0);
14229b94acceSBarry Smith }
14239b94acceSBarry Smith 
1424646217ecSPeter Brune 
1425646217ecSPeter Brune #undef __FUNCT__
1426e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction"
1427e4ed7901SPeter Brune /*@C
1428e4ed7901SPeter Brune    SNESSetInitialFunction - Sets the function vector to be used as the
1429e4ed7901SPeter Brune    function norm at the initialization of the method.  In some
1430e4ed7901SPeter Brune    instances, the user has precomputed the function before calling
1431e4ed7901SPeter Brune    SNESSolve.  This function allows one to avoid a redundant call
1432e4ed7901SPeter Brune    to SNESComputeFunction in that case.
1433e4ed7901SPeter Brune 
1434e4ed7901SPeter Brune    Logically Collective on SNES
1435e4ed7901SPeter Brune 
1436e4ed7901SPeter Brune    Input Parameters:
1437e4ed7901SPeter Brune +  snes - the SNES context
1438e4ed7901SPeter Brune -  f - vector to store function value
1439e4ed7901SPeter Brune 
1440e4ed7901SPeter Brune    Notes:
1441e4ed7901SPeter Brune    This should not be modified during the solution procedure.
1442e4ed7901SPeter Brune 
1443e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1444e4ed7901SPeter Brune 
1445e4ed7901SPeter Brune    Level: developer
1446e4ed7901SPeter Brune 
1447e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function
1448e4ed7901SPeter Brune 
1449e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm()
1450e4ed7901SPeter Brune @*/
1451e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunction(SNES snes, Vec f)
1452e4ed7901SPeter Brune {
1453e4ed7901SPeter Brune   PetscErrorCode ierr;
1454e4ed7901SPeter Brune   Vec            vec_func;
1455e4ed7901SPeter Brune 
1456e4ed7901SPeter Brune   PetscFunctionBegin;
1457e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1458e4ed7901SPeter Brune   PetscValidHeaderSpecific(f,VEC_CLASSID,2);
1459e4ed7901SPeter Brune   PetscCheckSameComm(snes,1,f,2);
1460e4ed7901SPeter Brune   ierr = SNESGetFunction(snes,&vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
1461e4ed7901SPeter Brune   ierr = VecCopy(f, vec_func);CHKERRQ(ierr);
1462217b9c2eSPeter Brune   snes->vec_func_init_set = PETSC_TRUE;
1463e4ed7901SPeter Brune   PetscFunctionReturn(0);
1464e4ed7901SPeter Brune }
1465e4ed7901SPeter Brune 
1466e4ed7901SPeter Brune 
1467e4ed7901SPeter Brune #undef __FUNCT__
1468e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunctionNorm"
1469e4ed7901SPeter Brune /*@C
1470e4ed7901SPeter Brune    SNESSetInitialFunctionNorm - Sets the function norm to be used as the function norm
1471e4ed7901SPeter Brune    at the initialization of the  method.  In some instances, the user has precomputed
1472e4ed7901SPeter Brune    the function and its norm before calling SNESSolve.  This function allows one to
1473e4ed7901SPeter Brune    avoid a redundant call to SNESComputeFunction() and VecNorm() in that case.
1474e4ed7901SPeter Brune 
1475e4ed7901SPeter Brune    Logically Collective on SNES
1476e4ed7901SPeter Brune 
1477e4ed7901SPeter Brune    Input Parameters:
1478e4ed7901SPeter Brune +  snes - the SNES context
1479e4ed7901SPeter Brune -  fnorm - the norm of F as set by SNESSetInitialFunction()
1480e4ed7901SPeter Brune 
1481e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1482e4ed7901SPeter Brune 
1483e4ed7901SPeter Brune    Level: developer
1484e4ed7901SPeter Brune 
1485e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function, norm
1486e4ed7901SPeter Brune 
1487e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction()
1488e4ed7901SPeter Brune @*/
1489e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm)
1490e4ed7901SPeter Brune {
1491e4ed7901SPeter Brune   PetscFunctionBegin;
1492e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1493e4ed7901SPeter Brune   snes->norm_init = fnorm;
1494e4ed7901SPeter Brune   snes->norm_init_set = PETSC_TRUE;
1495e4ed7901SPeter Brune   PetscFunctionReturn(0);
1496e4ed7901SPeter Brune }
1497e4ed7901SPeter Brune 
1498e4ed7901SPeter Brune #undef __FUNCT__
1499534ebe21SPeter Brune #define __FUNCT__ "SNESSetNormType"
1500534ebe21SPeter Brune /*@
1501534ebe21SPeter Brune    SNESSetNormType - Sets the SNESNormType used in covergence and monitoring
1502534ebe21SPeter Brune    of the SNES method.
1503534ebe21SPeter Brune 
1504534ebe21SPeter Brune    Logically Collective on SNES
1505534ebe21SPeter Brune 
1506534ebe21SPeter Brune    Input Parameters:
1507534ebe21SPeter Brune +  snes - the SNES context
1508534ebe21SPeter Brune -  normtype - the type of the norm used
1509534ebe21SPeter Brune 
1510534ebe21SPeter Brune    Notes:
1511534ebe21SPeter Brune    Only certain SNES methods support certain SNESNormTypes.  Most require evaluation
1512534ebe21SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
1513534ebe21SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1514534ebe21SPeter Brune    (SNESGS) and the like do not require the norm of the function to be computed, and therfore
1515534ebe21SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
1516534ebe21SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
1517534ebe21SPeter Brune    their solution.
1518534ebe21SPeter Brune 
1519534ebe21SPeter Brune    Level: developer
1520534ebe21SPeter Brune 
1521534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1522534ebe21SPeter Brune 
1523534ebe21SPeter Brune .seealso: SNESGetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType
1524534ebe21SPeter Brune @*/
1525534ebe21SPeter Brune PetscErrorCode  SNESSetNormType(SNES snes, SNESNormType normtype)
1526534ebe21SPeter Brune {
1527534ebe21SPeter Brune   PetscFunctionBegin;
1528534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1529534ebe21SPeter Brune   snes->normtype = normtype;
1530534ebe21SPeter Brune   PetscFunctionReturn(0);
1531534ebe21SPeter Brune }
1532534ebe21SPeter Brune 
1533534ebe21SPeter Brune 
1534534ebe21SPeter Brune #undef __FUNCT__
1535534ebe21SPeter Brune #define __FUNCT__ "SNESGetNormType"
1536534ebe21SPeter Brune /*@
1537534ebe21SPeter Brune    SNESGetNormType - Gets the SNESNormType used in covergence and monitoring
1538534ebe21SPeter Brune    of the SNES method.
1539534ebe21SPeter Brune 
1540534ebe21SPeter Brune    Logically Collective on SNES
1541534ebe21SPeter Brune 
1542534ebe21SPeter Brune    Input Parameters:
1543534ebe21SPeter Brune +  snes - the SNES context
1544534ebe21SPeter Brune -  normtype - the type of the norm used
1545534ebe21SPeter Brune 
1546534ebe21SPeter Brune    Level: advanced
1547534ebe21SPeter Brune 
1548534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1549534ebe21SPeter Brune 
1550534ebe21SPeter Brune .seealso: SNESSetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType
1551534ebe21SPeter Brune @*/
1552534ebe21SPeter Brune PetscErrorCode  SNESGetNormType(SNES snes, SNESNormType *normtype)
1553534ebe21SPeter Brune {
1554534ebe21SPeter Brune   PetscFunctionBegin;
1555534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1556534ebe21SPeter Brune   *normtype = snes->normtype;
1557534ebe21SPeter Brune   PetscFunctionReturn(0);
1558534ebe21SPeter Brune }
1559534ebe21SPeter Brune 
1560534ebe21SPeter Brune #undef __FUNCT__
1561646217ecSPeter Brune #define __FUNCT__ "SNESSetGS"
1562c79ef259SPeter Brune /*@C
1563c79ef259SPeter Brune    SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for
1564c79ef259SPeter Brune    use with composed nonlinear solvers.
1565c79ef259SPeter Brune 
1566c79ef259SPeter Brune    Input Parameters:
1567c79ef259SPeter Brune +  snes   - the SNES context
1568c79ef259SPeter Brune .  gsfunc - function evaluation routine
1569c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
1570c79ef259SPeter Brune             smoother evaluation routine (may be PETSC_NULL)
1571c79ef259SPeter Brune 
1572c79ef259SPeter Brune    Calling sequence of func:
1573c79ef259SPeter Brune $    func (SNES snes,Vec x,Vec b,void *ctx);
1574c79ef259SPeter Brune 
1575c79ef259SPeter Brune +  X   - solution vector
1576c79ef259SPeter Brune .  B   - RHS vector
1577d28543b3SPeter Brune -  ctx - optional user-defined Gauss-Seidel context
1578c79ef259SPeter Brune 
1579c79ef259SPeter Brune    Notes:
1580c79ef259SPeter Brune    The GS routines are used by the composed nonlinear solver to generate
1581c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
1582c79ef259SPeter Brune 
1583d28543b3SPeter Brune    Level: intermediate
1584c79ef259SPeter Brune 
1585d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel
1586c79ef259SPeter Brune 
1587c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS()
1588c79ef259SPeter Brune @*/
15896cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx)
15906cab3a1bSJed Brown {
15916cab3a1bSJed Brown   PetscErrorCode ierr;
15926cab3a1bSJed Brown   DM dm;
15936cab3a1bSJed Brown 
1594646217ecSPeter Brune   PetscFunctionBegin;
15956cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15966cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
15976cab3a1bSJed Brown   ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr);
1598646217ecSPeter Brune   PetscFunctionReturn(0);
1599646217ecSPeter Brune }
1600646217ecSPeter Brune 
1601d25893d9SBarry Smith #undef __FUNCT__
160289b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps"
160389b92e6fSPeter Brune /*@
160489b92e6fSPeter Brune    SNESSetGSSweeps - Sets the number of sweeps of GS to use.
160589b92e6fSPeter Brune 
160689b92e6fSPeter Brune    Input Parameters:
160789b92e6fSPeter Brune +  snes   - the SNES context
160889b92e6fSPeter Brune -  sweeps  - the number of sweeps of GS to perform.
160989b92e6fSPeter Brune 
161089b92e6fSPeter Brune    Level: intermediate
161189b92e6fSPeter Brune 
161289b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
161389b92e6fSPeter Brune 
161489b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps()
161589b92e6fSPeter Brune @*/
161689b92e6fSPeter Brune 
161789b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) {
161889b92e6fSPeter Brune   PetscFunctionBegin;
161989b92e6fSPeter Brune   snes->gssweeps = sweeps;
162089b92e6fSPeter Brune   PetscFunctionReturn(0);
162189b92e6fSPeter Brune }
162289b92e6fSPeter Brune 
162389b92e6fSPeter Brune 
162489b92e6fSPeter Brune #undef __FUNCT__
162589b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps"
162689b92e6fSPeter Brune /*@
162789b92e6fSPeter Brune    SNESGetGSSweeps - Gets the number of sweeps GS will use.
162889b92e6fSPeter Brune 
162989b92e6fSPeter Brune    Input Parameters:
163089b92e6fSPeter Brune .  snes   - the SNES context
163189b92e6fSPeter Brune 
163289b92e6fSPeter Brune    Output Parameters:
163389b92e6fSPeter Brune .  sweeps  - the number of sweeps of GS to perform.
163489b92e6fSPeter Brune 
163589b92e6fSPeter Brune    Level: intermediate
163689b92e6fSPeter Brune 
163789b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
163889b92e6fSPeter Brune 
163989b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps()
164089b92e6fSPeter Brune @*/
164189b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) {
164289b92e6fSPeter Brune   PetscFunctionBegin;
164389b92e6fSPeter Brune   *sweeps = snes->gssweeps;
164489b92e6fSPeter Brune   PetscFunctionReturn(0);
164589b92e6fSPeter Brune }
164689b92e6fSPeter Brune 
164789b92e6fSPeter Brune #undef __FUNCT__
16488b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction"
16498b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
16508b0a5094SBarry Smith {
16518b0a5094SBarry Smith   PetscErrorCode ierr;
16526cab3a1bSJed Brown   void *functx,*jacctx;
16536cab3a1bSJed Brown 
16548b0a5094SBarry Smith   PetscFunctionBegin;
16556cab3a1bSJed Brown   ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
16566cab3a1bSJed Brown   ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr);
16578b0a5094SBarry Smith   /*  A(x)*x - b(x) */
16586cab3a1bSJed Brown   ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr);
16596cab3a1bSJed Brown   ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr);
16608b0a5094SBarry Smith   ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
16618b0a5094SBarry Smith   ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
16628b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
16638b0a5094SBarry Smith   ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr);
16648b0a5094SBarry Smith   PetscFunctionReturn(0);
16658b0a5094SBarry Smith }
16668b0a5094SBarry Smith 
16678b0a5094SBarry Smith #undef __FUNCT__
16688b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian"
16698b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
16708b0a5094SBarry Smith {
16718b0a5094SBarry Smith   PetscFunctionBegin;
16728b0a5094SBarry Smith   *flag = snes->matstruct;
16738b0a5094SBarry Smith   PetscFunctionReturn(0);
16748b0a5094SBarry Smith }
16758b0a5094SBarry Smith 
16768b0a5094SBarry Smith #undef __FUNCT__
16778b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard"
16788b0a5094SBarry Smith /*@C
16790d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
16808b0a5094SBarry Smith 
16818b0a5094SBarry Smith    Logically Collective on SNES
16828b0a5094SBarry Smith 
16838b0a5094SBarry Smith    Input Parameters:
16848b0a5094SBarry Smith +  snes - the SNES context
16858b0a5094SBarry Smith .  r - vector to store function value
16868b0a5094SBarry Smith .  func - function evaluation routine
16878b0a5094SBarry 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)
16888b0a5094SBarry Smith .  mat - matrix to store A
16898b0a5094SBarry Smith .  mfunc  - function to compute matrix value
16908b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
16918b0a5094SBarry Smith          function evaluation routine (may be PETSC_NULL)
16928b0a5094SBarry Smith 
16938b0a5094SBarry Smith    Calling sequence of func:
16948b0a5094SBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
16958b0a5094SBarry Smith 
16968b0a5094SBarry Smith +  f - function vector
16978b0a5094SBarry Smith -  ctx - optional user-defined function context
16988b0a5094SBarry Smith 
16998b0a5094SBarry Smith    Calling sequence of mfunc:
17008b0a5094SBarry Smith $     mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx);
17018b0a5094SBarry Smith 
17028b0a5094SBarry Smith +  x - input vector
17038b0a5094SBarry 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(),
17048b0a5094SBarry Smith           normally just pass mat in this location
17058b0a5094SBarry Smith .  mat - form A(x) matrix
17068b0a5094SBarry Smith .  flag - flag indicating information about the preconditioner matrix
17078b0a5094SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
17088b0a5094SBarry Smith -  ctx - [optional] user-defined Jacobian context
17098b0a5094SBarry Smith 
17108b0a5094SBarry Smith    Notes:
17118b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
17128b0a5094SBarry Smith 
17138b0a5094SBarry 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}
17148b0a5094SBarry 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.
17158b0a5094SBarry Smith 
17168b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
17178b0a5094SBarry Smith 
17180d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
17190d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
17208b0a5094SBarry Smith 
17218b0a5094SBarry 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
17228b0a5094SBarry 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
17238b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
17248b0a5094SBarry Smith 
17258b0a5094SBarry Smith    Level: beginner
17268b0a5094SBarry Smith 
17278b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function
17288b0a5094SBarry Smith 
17290d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard()
17308b0a5094SBarry Smith @*/
17318b0a5094SBarry 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)
17328b0a5094SBarry Smith {
17338b0a5094SBarry Smith   PetscErrorCode ierr;
17348b0a5094SBarry Smith   PetscFunctionBegin;
17358b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
17368b0a5094SBarry Smith   snes->ops->computepfunction = func;
17378b0a5094SBarry Smith   snes->ops->computepjacobian = mfunc;
17388b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
17398b0a5094SBarry Smith   ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
17408b0a5094SBarry Smith   PetscFunctionReturn(0);
17418b0a5094SBarry Smith }
17428b0a5094SBarry Smith 
17438b0a5094SBarry Smith #undef __FUNCT__
1744d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess"
1745d25893d9SBarry Smith /*@C
1746d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1747d25893d9SBarry Smith 
1748d25893d9SBarry Smith    Logically Collective on SNES
1749d25893d9SBarry Smith 
1750d25893d9SBarry Smith    Input Parameters:
1751d25893d9SBarry Smith +  snes - the SNES context
1752d25893d9SBarry Smith .  func - function evaluation routine
1753d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
1754d25893d9SBarry Smith          function evaluation routine (may be PETSC_NULL)
1755d25893d9SBarry Smith 
1756d25893d9SBarry Smith    Calling sequence of func:
1757d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
1758d25893d9SBarry Smith 
1759d25893d9SBarry Smith .  f - function vector
1760d25893d9SBarry Smith -  ctx - optional user-defined function context
1761d25893d9SBarry Smith 
1762d25893d9SBarry Smith    Level: intermediate
1763d25893d9SBarry Smith 
1764d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
1765d25893d9SBarry Smith 
1766d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1767d25893d9SBarry Smith @*/
1768d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1769d25893d9SBarry Smith {
1770d25893d9SBarry Smith   PetscFunctionBegin;
1771d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1772d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
1773d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
1774d25893d9SBarry Smith   PetscFunctionReturn(0);
1775d25893d9SBarry Smith }
1776d25893d9SBarry Smith 
17773ab0aad5SBarry Smith /* --------------------------------------------------------------- */
17783ab0aad5SBarry Smith #undef __FUNCT__
17791096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
17801096aae1SMatthew Knepley /*@C
17811096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
17821096aae1SMatthew Knepley    it assumes a zero right hand side.
17831096aae1SMatthew Knepley 
17843f9fe445SBarry Smith    Logically Collective on SNES
17851096aae1SMatthew Knepley 
17861096aae1SMatthew Knepley    Input Parameter:
17871096aae1SMatthew Knepley .  snes - the SNES context
17881096aae1SMatthew Knepley 
17891096aae1SMatthew Knepley    Output Parameter:
1790bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
17911096aae1SMatthew Knepley 
17921096aae1SMatthew Knepley    Level: intermediate
17931096aae1SMatthew Knepley 
17941096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
17951096aae1SMatthew Knepley 
179685385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
17971096aae1SMatthew Knepley @*/
17987087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
17991096aae1SMatthew Knepley {
18001096aae1SMatthew Knepley   PetscFunctionBegin;
18010700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
18021096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
180385385478SLisandro Dalcin   *rhs = snes->vec_rhs;
18041096aae1SMatthew Knepley   PetscFunctionReturn(0);
18051096aae1SMatthew Knepley }
18061096aae1SMatthew Knepley 
18071096aae1SMatthew Knepley #undef __FUNCT__
18084a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
18099b94acceSBarry Smith /*@
181036851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
18119b94acceSBarry Smith                          SNESSetFunction().
18129b94acceSBarry Smith 
1813c7afd0dbSLois Curfman McInnes    Collective on SNES
1814c7afd0dbSLois Curfman McInnes 
18159b94acceSBarry Smith    Input Parameters:
1816c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1817c7afd0dbSLois Curfman McInnes -  x - input vector
18189b94acceSBarry Smith 
18199b94acceSBarry Smith    Output Parameter:
18203638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
18219b94acceSBarry Smith 
18221bffabb2SLois Curfman McInnes    Notes:
182336851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
182436851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
182536851e7fSLois Curfman McInnes    themselves.
182636851e7fSLois Curfman McInnes 
182736851e7fSLois Curfman McInnes    Level: developer
182836851e7fSLois Curfman McInnes 
18299b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
18309b94acceSBarry Smith 
1831a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
18329b94acceSBarry Smith @*/
18337087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
18349b94acceSBarry Smith {
1835dfbe8321SBarry Smith   PetscErrorCode ierr;
18366cab3a1bSJed Brown   DM             dm;
18376cab3a1bSJed Brown   SNESDM         sdm;
18389b94acceSBarry Smith 
18393a40ed3dSBarry Smith   PetscFunctionBegin;
18400700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
18410700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
18420700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
1843c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
1844c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
18454ec14c9cSBarry Smith   VecValidValues(x,2,PETSC_TRUE);
1846184914b5SBarry Smith 
18476cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
18486cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
1849d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
18506cab3a1bSJed Brown   if (sdm->computefunction) {
1851d64ed03dSBarry Smith     PetscStackPush("SNES user function");
18526cab3a1bSJed Brown     ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
1853d64ed03dSBarry Smith     PetscStackPop;
185473250ac0SBarry Smith   } else if (snes->dm) {
1855644e2e5bSBarry Smith     ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr);
1856c90fad12SPeter Brune   } else if (snes->vec_rhs) {
1857c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
1858644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
185985385478SLisandro Dalcin   if (snes->vec_rhs) {
186085385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
18613ab0aad5SBarry Smith   }
1862ae3c334cSLois Curfman McInnes   snes->nfuncs++;
1863d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
18644ec14c9cSBarry Smith   VecValidValues(y,3,PETSC_FALSE);
18653a40ed3dSBarry Smith   PetscFunctionReturn(0);
18669b94acceSBarry Smith }
18679b94acceSBarry Smith 
18684a2ae208SSatish Balay #undef __FUNCT__
1869646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS"
1870c79ef259SPeter Brune /*@
1871c79ef259SPeter Brune    SNESComputeGS - Calls the Gauss-Seidel function that has been set with
1872c79ef259SPeter Brune                    SNESSetGS().
1873c79ef259SPeter Brune 
1874c79ef259SPeter Brune    Collective on SNES
1875c79ef259SPeter Brune 
1876c79ef259SPeter Brune    Input Parameters:
1877c79ef259SPeter Brune +  snes - the SNES context
1878c79ef259SPeter Brune .  x - input vector
1879c79ef259SPeter Brune -  b - rhs vector
1880c79ef259SPeter Brune 
1881c79ef259SPeter Brune    Output Parameter:
1882c79ef259SPeter Brune .  x - new solution vector
1883c79ef259SPeter Brune 
1884c79ef259SPeter Brune    Notes:
1885c79ef259SPeter Brune    SNESComputeGS() is typically used within composed nonlinear solver
1886c79ef259SPeter Brune    implementations, so most users would not generally call this routine
1887c79ef259SPeter Brune    themselves.
1888c79ef259SPeter Brune 
1889c79ef259SPeter Brune    Level: developer
1890c79ef259SPeter Brune 
1891c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function
1892c79ef259SPeter Brune 
1893c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction()
1894c79ef259SPeter Brune @*/
1895646217ecSPeter Brune PetscErrorCode  SNESComputeGS(SNES snes,Vec b,Vec x)
1896646217ecSPeter Brune {
1897646217ecSPeter Brune   PetscErrorCode ierr;
189889b92e6fSPeter Brune   PetscInt i;
18996cab3a1bSJed Brown   DM dm;
19006cab3a1bSJed Brown   SNESDM sdm;
1901646217ecSPeter Brune 
1902646217ecSPeter Brune   PetscFunctionBegin;
1903646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1904646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
1905646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
1906646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
1907646217ecSPeter Brune   if(b) PetscCheckSameComm(snes,1,b,3);
19084ec14c9cSBarry Smith   if (b) VecValidValues(b,2,PETSC_TRUE);
1909701cf23dSPeter Brune   ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
19106cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
19116cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
19126cab3a1bSJed Brown   if (sdm->computegs) {
191389b92e6fSPeter Brune     for (i = 0; i < snes->gssweeps; i++) {
1914646217ecSPeter Brune       PetscStackPush("SNES user GS");
19156cab3a1bSJed Brown       ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
1916646217ecSPeter Brune       PetscStackPop;
191789b92e6fSPeter Brune     }
1918646217ecSPeter Brune   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve().");
1919701cf23dSPeter Brune   ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
19204ec14c9cSBarry Smith   VecValidValues(x,3,PETSC_FALSE);
1921646217ecSPeter Brune   PetscFunctionReturn(0);
1922646217ecSPeter Brune }
1923646217ecSPeter Brune 
1924646217ecSPeter Brune 
1925646217ecSPeter Brune #undef __FUNCT__
19264a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
192762fef451SLois Curfman McInnes /*@
192862fef451SLois Curfman McInnes    SNESComputeJacobian - Computes the Jacobian matrix that has been
192962fef451SLois Curfman McInnes    set with SNESSetJacobian().
193062fef451SLois Curfman McInnes 
1931c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
1932c7afd0dbSLois Curfman McInnes 
193362fef451SLois Curfman McInnes    Input Parameters:
1934c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1935c7afd0dbSLois Curfman McInnes -  x - input vector
193662fef451SLois Curfman McInnes 
193762fef451SLois Curfman McInnes    Output Parameters:
1938c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
193962fef451SLois Curfman McInnes .  B - optional preconditioning matrix
19402b668275SBarry Smith -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1941fee21e36SBarry Smith 
1942e35cf81dSBarry Smith   Options Database Keys:
1943e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
1944693365a8SJed Brown .    -snes_lag_jacobian <lag>
1945693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
1946693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
1947693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
19484c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
1949c01495d3SJed Brown .    -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference
1950c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
1951c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
1952c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
1953c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
19544c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
1955c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
1956c01495d3SJed Brown 
1957e35cf81dSBarry Smith 
195862fef451SLois Curfman McInnes    Notes:
195962fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
196062fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
196162fef451SLois Curfman McInnes 
196294b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the
1963dc5a77f8SLois Curfman McInnes    flag parameter.
196462fef451SLois Curfman McInnes 
196536851e7fSLois Curfman McInnes    Level: developer
196636851e7fSLois Curfman McInnes 
196762fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
196862fef451SLois Curfman McInnes 
1969e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
197062fef451SLois Curfman McInnes @*/
19717087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
19729b94acceSBarry Smith {
1973dfbe8321SBarry Smith   PetscErrorCode ierr;
1974ace3abfcSBarry Smith   PetscBool      flag;
19756cab3a1bSJed Brown   DM             dm;
19766cab3a1bSJed Brown   SNESDM         sdm;
19773a40ed3dSBarry Smith 
19783a40ed3dSBarry Smith   PetscFunctionBegin;
19790700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
19800700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
19814482741eSBarry Smith   PetscValidPointer(flg,5);
1982c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
19834ec14c9cSBarry Smith   VecValidValues(X,2,PETSC_TRUE);
19846cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
19856cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
19866cab3a1bSJed Brown   if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
1987ebd3b9afSBarry Smith 
1988ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
1989ebd3b9afSBarry Smith 
1990fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
1991fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
1992fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
1993fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
1994e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1995e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
1996*251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1997ebd3b9afSBarry Smith     if (flag) {
1998ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1999ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2000ebd3b9afSBarry Smith     }
2001e35cf81dSBarry Smith     PetscFunctionReturn(0);
2002e35cf81dSBarry Smith   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
2003e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
2004e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
2005*251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
2006ebd3b9afSBarry Smith     if (flag) {
2007ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2008ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2009ebd3b9afSBarry Smith     }
2010e35cf81dSBarry Smith     PetscFunctionReturn(0);
2011e35cf81dSBarry Smith   }
2012e35cf81dSBarry Smith 
2013c4fc05e7SBarry Smith   *flg = DIFFERENT_NONZERO_PATTERN;
2014e35cf81dSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
2015d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
20166cab3a1bSJed Brown   ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr);
2017d64ed03dSBarry Smith   PetscStackPop;
2018d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
2019a8054027SBarry Smith 
20203b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
20213b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
20223b4f5425SBarry Smith     snes->lagpreconditioner = -1;
20233b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
2024a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
2025a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
2026a8054027SBarry Smith   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
2027a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
2028a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
2029a8054027SBarry Smith   }
2030a8054027SBarry Smith 
20316d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
20320700a824SBarry Smith   /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
20330700a824SBarry Smith     PetscValidHeaderSpecific(*B,MAT_CLASSID,4);   */
2034693365a8SJed Brown   {
2035693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
2036693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr);
2037693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
2038693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
2039693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr);
2040693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
2041693365a8SJed Brown       Mat Bexp_mine = PETSC_NULL,Bexp,FDexp;
2042693365a8SJed Brown       MatStructure mstruct;
2043693365a8SJed Brown       PetscViewer vdraw,vstdout;
20446b3a5b13SJed Brown       PetscBool flg;
2045693365a8SJed Brown       if (flag_operator) {
2046693365a8SJed Brown         ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr);
2047693365a8SJed Brown         Bexp = Bexp_mine;
2048693365a8SJed Brown       } else {
2049693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
2050*251f4c67SDmitry Karpeev         ierr = PetscObjectTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
2051693365a8SJed Brown         if (flg) Bexp = *B;
2052693365a8SJed Brown         else {
2053693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
2054693365a8SJed Brown           ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr);
2055693365a8SJed Brown           Bexp = Bexp_mine;
2056693365a8SJed Brown         }
2057693365a8SJed Brown       }
2058693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
2059693365a8SJed Brown       ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr);
2060693365a8SJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
2061693365a8SJed Brown       if (flag_draw || flag_contour) {
2062693365a8SJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
2063693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
2064693365a8SJed Brown       } else vdraw = PETSC_NULL;
2065693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr);
2066693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
2067693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
2068693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
2069693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2070693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
2071693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2072693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
2073693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2074693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
2075693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
2076693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
2077693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
2078693365a8SJed Brown       }
2079693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
2080693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
2081693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
2082693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
2083693365a8SJed Brown     }
2084693365a8SJed Brown   }
20854c30e9fbSJed Brown   {
20866719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
20876719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
20884c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr);
20896719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr);
20904c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
20914c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
20926719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr);
20936719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr);
20946719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr);
20956719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
20964c30e9fbSJed Brown       Mat Bfd;
20974c30e9fbSJed Brown       MatStructure mstruct;
20984c30e9fbSJed Brown       PetscViewer vdraw,vstdout;
20994c30e9fbSJed Brown       ISColoring iscoloring;
21004c30e9fbSJed Brown       MatFDColoring matfdcoloring;
21014c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
21024c30e9fbSJed Brown       void *funcctx;
21036719d8e4SJed Brown       PetscReal norm1,norm2,normmax;
21044c30e9fbSJed Brown 
21054c30e9fbSJed Brown       ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
21064c30e9fbSJed Brown       ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
21074c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
21084c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
21094c30e9fbSJed Brown 
21104c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
21114c30e9fbSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr);
21124c30e9fbSJed Brown       ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr);
21134c30e9fbSJed Brown       ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
21144c30e9fbSJed Brown       ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
21154c30e9fbSJed Brown       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
21164c30e9fbSJed Brown       ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr);
21174c30e9fbSJed Brown       ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
21184c30e9fbSJed Brown 
21194c30e9fbSJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
21204c30e9fbSJed Brown       if (flag_draw || flag_contour) {
21214c30e9fbSJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
21224c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
21234c30e9fbSJed Brown       } else vdraw = PETSC_NULL;
21244c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
21256719d8e4SJed Brown       if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);}
21264c30e9fbSJed Brown       if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);}
21274c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
21286719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
21294c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
21304c30e9fbSJed Brown       ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
21314c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
21326719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
21334c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
21346719d8e4SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr);
21356719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
21364c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
21374c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
21384c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
21394c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
21404c30e9fbSJed Brown       }
21414c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
21426719d8e4SJed Brown 
21436719d8e4SJed Brown       if (flag_threshold) {
21446719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
21456719d8e4SJed Brown         ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr);
21466719d8e4SJed Brown         ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr);
21476719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
21486719d8e4SJed Brown           const PetscScalar *ba,*ca;
21496719d8e4SJed Brown           const PetscInt *bj,*cj;
21506719d8e4SJed Brown           PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
21516719d8e4SJed Brown           PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0;
21526719d8e4SJed Brown           ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
21536719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
21546719d8e4SJed Brown           if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
21556719d8e4SJed Brown           for (j=0; j<bn; j++) {
21566719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
21576719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
21586719d8e4SJed Brown               maxentrycol = bj[j];
21596719d8e4SJed Brown               maxentry = PetscRealPart(ba[j]);
21606719d8e4SJed Brown             }
21616719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
21626719d8e4SJed Brown               maxdiffcol = bj[j];
21636719d8e4SJed Brown               maxdiff = PetscRealPart(ca[j]);
21646719d8e4SJed Brown             }
21656719d8e4SJed Brown             if (rdiff > maxrdiff) {
21666719d8e4SJed Brown               maxrdiffcol = bj[j];
21676719d8e4SJed Brown               maxrdiff = rdiff;
21686719d8e4SJed Brown             }
21696719d8e4SJed Brown           }
21706719d8e4SJed Brown           if (maxrdiff > 1) {
21716719d8e4SJed 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);
21726719d8e4SJed Brown             for (j=0; j<bn; j++) {
21736719d8e4SJed Brown               PetscReal rdiff;
21746719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
21756719d8e4SJed Brown               if (rdiff > 1) {
21766719d8e4SJed Brown                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr);
21776719d8e4SJed Brown               }
21786719d8e4SJed Brown             }
21796719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
21806719d8e4SJed Brown           }
21816719d8e4SJed Brown           ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
21826719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
21836719d8e4SJed Brown         }
21846719d8e4SJed Brown       }
21854c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
21864c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
21874c30e9fbSJed Brown     }
21884c30e9fbSJed Brown   }
21893a40ed3dSBarry Smith   PetscFunctionReturn(0);
21909b94acceSBarry Smith }
21919b94acceSBarry Smith 
21924a2ae208SSatish Balay #undef __FUNCT__
21934a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
21949b94acceSBarry Smith /*@C
21959b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2196044dda88SLois Curfman McInnes    location to store the matrix.
21979b94acceSBarry Smith 
21983f9fe445SBarry Smith    Logically Collective on SNES and Mat
2199c7afd0dbSLois Curfman McInnes 
22009b94acceSBarry Smith    Input Parameters:
2201c7afd0dbSLois Curfman McInnes +  snes - the SNES context
22029b94acceSBarry Smith .  A - Jacobian matrix
22039b94acceSBarry Smith .  B - preconditioner matrix (usually same as the Jacobian)
2204efd51863SBarry Smith .  func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value)
2205c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
2206efd51863SBarry Smith          Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value)
22079b94acceSBarry Smith 
22089b94acceSBarry Smith    Calling sequence of func:
22098d76a1e5SLois Curfman McInnes $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
22109b94acceSBarry Smith 
2211c7afd0dbSLois Curfman McInnes +  x - input vector
22129b94acceSBarry Smith .  A - Jacobian matrix
22139b94acceSBarry Smith .  B - preconditioner matrix, usually the same as A
2214ac21db08SLois Curfman McInnes .  flag - flag indicating information about the preconditioner matrix
22152b668275SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
2216c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined Jacobian context
22179b94acceSBarry Smith 
22189b94acceSBarry Smith    Notes:
221994b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the flag
22202cd2dfdcSLois Curfman McInnes    output parameter in the routine func().  Be sure to read this information!
2221ac21db08SLois Curfman McInnes 
2222ac21db08SLois Curfman McInnes    The routine func() takes Mat * as the matrix arguments rather than Mat.
22239b94acceSBarry Smith    This allows the Jacobian evaluation routine to replace A and/or B with a
22249b94acceSBarry Smith    completely new new matrix structure (not just different matrix elements)
22259b94acceSBarry Smith    when appropriate, for instance, if the nonzero structure is changing
22269b94acceSBarry Smith    throughout the global iterations.
22279b94acceSBarry Smith 
222816913363SBarry Smith    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
222916913363SBarry Smith    each matrix.
223016913363SBarry Smith 
2231a8a26c1eSJed Brown    If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument
2232a8a26c1eSJed Brown    must be a MatFDColoring.
2233a8a26c1eSJed Brown 
2234c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2235c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2236c3cc8fd1SJed Brown 
223736851e7fSLois Curfman McInnes    Level: beginner
223836851e7fSLois Curfman McInnes 
22399b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
22409b94acceSBarry Smith 
22413ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
22429b94acceSBarry Smith @*/
22437087cfbeSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
22449b94acceSBarry Smith {
2245dfbe8321SBarry Smith   PetscErrorCode ierr;
22466cab3a1bSJed Brown   DM             dm;
22473a7fca6bSBarry Smith 
22483a40ed3dSBarry Smith   PetscFunctionBegin;
22490700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
22500700a824SBarry Smith   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
22510700a824SBarry Smith   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
2252c9780b6fSBarry Smith   if (A) PetscCheckSameComm(snes,1,A,2);
225306975374SJed Brown   if (B) PetscCheckSameComm(snes,1,B,3);
22546cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
22556cab3a1bSJed Brown   ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr);
22563a7fca6bSBarry Smith   if (A) {
22577dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
22586bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
22599b94acceSBarry Smith     snes->jacobian = A;
22603a7fca6bSBarry Smith   }
22613a7fca6bSBarry Smith   if (B) {
22627dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
22636bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
22649b94acceSBarry Smith     snes->jacobian_pre = B;
22653a7fca6bSBarry Smith   }
22663a40ed3dSBarry Smith   PetscFunctionReturn(0);
22679b94acceSBarry Smith }
226862fef451SLois Curfman McInnes 
22694a2ae208SSatish Balay #undef __FUNCT__
22704a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
2271c2aafc4cSSatish Balay /*@C
2272b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2273b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2274b4fd4287SBarry Smith 
2275c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2276c7afd0dbSLois Curfman McInnes 
2277b4fd4287SBarry Smith    Input Parameter:
2278b4fd4287SBarry Smith .  snes - the nonlinear solver context
2279b4fd4287SBarry Smith 
2280b4fd4287SBarry Smith    Output Parameters:
2281c7afd0dbSLois Curfman McInnes +  A - location to stash Jacobian matrix (or PETSC_NULL)
2282b4fd4287SBarry Smith .  B - location to stash preconditioner matrix (or PETSC_NULL)
228370e92668SMatthew Knepley .  func - location to put Jacobian function (or PETSC_NULL)
228470e92668SMatthew Knepley -  ctx - location to stash Jacobian ctx (or PETSC_NULL)
2285fee21e36SBarry Smith 
228636851e7fSLois Curfman McInnes    Level: advanced
228736851e7fSLois Curfman McInnes 
2288b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian()
2289b4fd4287SBarry Smith @*/
22907087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
2291b4fd4287SBarry Smith {
22926cab3a1bSJed Brown   PetscErrorCode ierr;
22936cab3a1bSJed Brown   DM             dm;
22946cab3a1bSJed Brown   SNESDM         sdm;
22956cab3a1bSJed Brown 
22963a40ed3dSBarry Smith   PetscFunctionBegin;
22970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2298b4fd4287SBarry Smith   if (A)    *A    = snes->jacobian;
2299b4fd4287SBarry Smith   if (B)    *B    = snes->jacobian_pre;
23006cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
23016cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
23026cab3a1bSJed Brown   if (func) *func = sdm->computejacobian;
23036cab3a1bSJed Brown   if (ctx)  *ctx  = sdm->jacobianctx;
23043a40ed3dSBarry Smith   PetscFunctionReturn(0);
2305b4fd4287SBarry Smith }
2306b4fd4287SBarry Smith 
23079b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
23089b94acceSBarry Smith 
23094a2ae208SSatish Balay #undef __FUNCT__
23104a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
23119b94acceSBarry Smith /*@
23129b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
2313272ac6f2SLois Curfman McInnes    of a nonlinear solver.
23149b94acceSBarry Smith 
2315fee21e36SBarry Smith    Collective on SNES
2316fee21e36SBarry Smith 
2317c7afd0dbSLois Curfman McInnes    Input Parameters:
231870e92668SMatthew Knepley .  snes - the SNES context
2319c7afd0dbSLois Curfman McInnes 
2320272ac6f2SLois Curfman McInnes    Notes:
2321272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
2322272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
2323272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
2324272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
2325272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
2326272ac6f2SLois Curfman McInnes 
232736851e7fSLois Curfman McInnes    Level: advanced
232836851e7fSLois Curfman McInnes 
23299b94acceSBarry Smith .keywords: SNES, nonlinear, setup
23309b94acceSBarry Smith 
23319b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
23329b94acceSBarry Smith @*/
23337087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
23349b94acceSBarry Smith {
2335dfbe8321SBarry Smith   PetscErrorCode ierr;
23366cab3a1bSJed Brown   DM             dm;
23376cab3a1bSJed Brown   SNESDM         sdm;
23383a40ed3dSBarry Smith 
23393a40ed3dSBarry Smith   PetscFunctionBegin;
23400700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
23414dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
23429b94acceSBarry Smith 
23437adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
234485385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
234585385478SLisandro Dalcin   }
234685385478SLisandro Dalcin 
2347a63bb30eSJed Brown   ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
234817186662SBarry Smith   if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
234958c9b817SLisandro Dalcin   if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
235058c9b817SLisandro Dalcin 
235158c9b817SLisandro Dalcin   if (!snes->vec_sol_update /* && snes->vec_sol */) {
235258c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
235358c9b817SLisandro Dalcin     ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr);
235458c9b817SLisandro Dalcin   }
235558c9b817SLisandro Dalcin 
23566cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
23576cab3a1bSJed Brown   ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */
23586cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
23596cab3a1bSJed Brown   if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc");
23606cab3a1bSJed Brown   if (!snes->vec_func) {
23616cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2362214df951SJed Brown   }
2363efd51863SBarry Smith 
2364b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
2365b710008aSBarry Smith 
2366f1c6b773SPeter Brune   if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);}
23679e764e56SPeter Brune 
2368d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
2369d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
2370d25893d9SBarry Smith   }
2371d25893d9SBarry Smith 
2372410397dcSLisandro Dalcin   if (snes->ops->setup) {
2373410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2374410397dcSLisandro Dalcin   }
237558c9b817SLisandro Dalcin 
23767aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
23773a40ed3dSBarry Smith   PetscFunctionReturn(0);
23789b94acceSBarry Smith }
23799b94acceSBarry Smith 
23804a2ae208SSatish Balay #undef __FUNCT__
238137596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
238237596af1SLisandro Dalcin /*@
238337596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
238437596af1SLisandro Dalcin 
238537596af1SLisandro Dalcin    Collective on SNES
238637596af1SLisandro Dalcin 
238737596af1SLisandro Dalcin    Input Parameter:
238837596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
238937596af1SLisandro Dalcin 
2390d25893d9SBarry Smith    Level: intermediate
2391d25893d9SBarry Smith 
2392d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
239337596af1SLisandro Dalcin 
239437596af1SLisandro Dalcin .keywords: SNES, destroy
239537596af1SLisandro Dalcin 
239637596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
239737596af1SLisandro Dalcin @*/
239837596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
239937596af1SLisandro Dalcin {
240037596af1SLisandro Dalcin   PetscErrorCode ierr;
240137596af1SLisandro Dalcin 
240237596af1SLisandro Dalcin   PetscFunctionBegin;
240337596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2404d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
2405d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
2406d25893d9SBarry Smith     snes->user = PETSC_NULL;
2407d25893d9SBarry Smith   }
24088a23116dSBarry Smith   if (snes->pc) {
24098a23116dSBarry Smith     ierr = SNESReset(snes->pc);CHKERRQ(ierr);
24108a23116dSBarry Smith   }
24118a23116dSBarry Smith 
241237596af1SLisandro Dalcin   if (snes->ops->reset) {
241337596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
241437596af1SLisandro Dalcin   }
24159e764e56SPeter Brune   if (snes->ksp) {
24169e764e56SPeter Brune     ierr = KSPReset(snes->ksp);CHKERRQ(ierr);
24179e764e56SPeter Brune   }
24189e764e56SPeter Brune 
24199e764e56SPeter Brune   if (snes->linesearch) {
2420f1c6b773SPeter Brune     ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr);
24219e764e56SPeter Brune   }
24229e764e56SPeter Brune 
24236bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
24246bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
24256bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
24266bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
24276bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
24286bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2429c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
2430c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
243137596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
243237596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
243337596af1SLisandro Dalcin   PetscFunctionReturn(0);
243437596af1SLisandro Dalcin }
243537596af1SLisandro Dalcin 
243637596af1SLisandro Dalcin #undef __FUNCT__
24374a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
243852baeb72SSatish Balay /*@
24399b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
24409b94acceSBarry Smith    with SNESCreate().
24419b94acceSBarry Smith 
2442c7afd0dbSLois Curfman McInnes    Collective on SNES
2443c7afd0dbSLois Curfman McInnes 
24449b94acceSBarry Smith    Input Parameter:
24459b94acceSBarry Smith .  snes - the SNES context
24469b94acceSBarry Smith 
244736851e7fSLois Curfman McInnes    Level: beginner
244836851e7fSLois Curfman McInnes 
24499b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
24509b94acceSBarry Smith 
245163a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
24529b94acceSBarry Smith @*/
24536bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
24549b94acceSBarry Smith {
24556849ba73SBarry Smith   PetscErrorCode ierr;
24563a40ed3dSBarry Smith 
24573a40ed3dSBarry Smith   PetscFunctionBegin;
24586bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
24596bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
24606bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2461d4bb536fSBarry Smith 
24626bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
24638a23116dSBarry Smith   ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr);
24646b8b9a38SLisandro Dalcin 
2465be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
24666bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
24676bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
24686d4c513bSLisandro Dalcin 
24696bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
24706bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
2471f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr);
24726b8b9a38SLisandro Dalcin 
24736bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
24746bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
24756bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
24766b8b9a38SLisandro Dalcin   }
24776bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
24786bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
24796bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
248058c9b817SLisandro Dalcin   }
24816bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2482a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
24833a40ed3dSBarry Smith  PetscFunctionReturn(0);
24849b94acceSBarry Smith }
24859b94acceSBarry Smith 
24869b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
24879b94acceSBarry Smith 
24884a2ae208SSatish Balay #undef __FUNCT__
2489a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
2490a8054027SBarry Smith /*@
2491a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2492a8054027SBarry Smith 
24933f9fe445SBarry Smith    Logically Collective on SNES
2494a8054027SBarry Smith 
2495a8054027SBarry Smith    Input Parameters:
2496a8054027SBarry Smith +  snes - the SNES context
2497a8054027SBarry 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
24983b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2499a8054027SBarry Smith 
2500a8054027SBarry Smith    Options Database Keys:
2501a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2502a8054027SBarry Smith 
2503a8054027SBarry Smith    Notes:
2504a8054027SBarry Smith    The default is 1
2505a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2506a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2507a8054027SBarry Smith 
2508a8054027SBarry Smith    Level: intermediate
2509a8054027SBarry Smith 
2510a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2511a8054027SBarry Smith 
2512e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2513a8054027SBarry Smith 
2514a8054027SBarry Smith @*/
25157087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2516a8054027SBarry Smith {
2517a8054027SBarry Smith   PetscFunctionBegin;
25180700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2519e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2520e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2521c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2522a8054027SBarry Smith   snes->lagpreconditioner = lag;
2523a8054027SBarry Smith   PetscFunctionReturn(0);
2524a8054027SBarry Smith }
2525a8054027SBarry Smith 
2526a8054027SBarry Smith #undef __FUNCT__
2527efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
2528efd51863SBarry Smith /*@
2529efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2530efd51863SBarry Smith 
2531efd51863SBarry Smith    Logically Collective on SNES
2532efd51863SBarry Smith 
2533efd51863SBarry Smith    Input Parameters:
2534efd51863SBarry Smith +  snes - the SNES context
2535efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
2536efd51863SBarry Smith 
2537efd51863SBarry Smith    Options Database Keys:
2538efd51863SBarry Smith .    -snes_grid_sequence <steps>
2539efd51863SBarry Smith 
2540efd51863SBarry Smith    Level: intermediate
2541efd51863SBarry Smith 
2542c0df2a02SJed Brown    Notes:
2543c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2544c0df2a02SJed Brown 
2545efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2546efd51863SBarry Smith 
2547efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2548efd51863SBarry Smith 
2549efd51863SBarry Smith @*/
2550efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2551efd51863SBarry Smith {
2552efd51863SBarry Smith   PetscFunctionBegin;
2553efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2554efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
2555efd51863SBarry Smith   snes->gridsequence = steps;
2556efd51863SBarry Smith   PetscFunctionReturn(0);
2557efd51863SBarry Smith }
2558efd51863SBarry Smith 
2559efd51863SBarry Smith #undef __FUNCT__
2560a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
2561a8054027SBarry Smith /*@
2562a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
2563a8054027SBarry Smith 
25643f9fe445SBarry Smith    Not Collective
2565a8054027SBarry Smith 
2566a8054027SBarry Smith    Input Parameter:
2567a8054027SBarry Smith .  snes - the SNES context
2568a8054027SBarry Smith 
2569a8054027SBarry Smith    Output Parameter:
2570a8054027SBarry 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
25713b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2572a8054027SBarry Smith 
2573a8054027SBarry Smith    Options Database Keys:
2574a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2575a8054027SBarry Smith 
2576a8054027SBarry Smith    Notes:
2577a8054027SBarry Smith    The default is 1
2578a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2579a8054027SBarry Smith 
2580a8054027SBarry Smith    Level: intermediate
2581a8054027SBarry Smith 
2582a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2583a8054027SBarry Smith 
2584a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
2585a8054027SBarry Smith 
2586a8054027SBarry Smith @*/
25877087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
2588a8054027SBarry Smith {
2589a8054027SBarry Smith   PetscFunctionBegin;
25900700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2591a8054027SBarry Smith   *lag = snes->lagpreconditioner;
2592a8054027SBarry Smith   PetscFunctionReturn(0);
2593a8054027SBarry Smith }
2594a8054027SBarry Smith 
2595a8054027SBarry Smith #undef __FUNCT__
2596e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
2597e35cf81dSBarry Smith /*@
2598e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
2599e35cf81dSBarry Smith      often the preconditioner is rebuilt.
2600e35cf81dSBarry Smith 
26013f9fe445SBarry Smith    Logically Collective on SNES
2602e35cf81dSBarry Smith 
2603e35cf81dSBarry Smith    Input Parameters:
2604e35cf81dSBarry Smith +  snes - the SNES context
2605e35cf81dSBarry 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
2606fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
2607e35cf81dSBarry Smith 
2608e35cf81dSBarry Smith    Options Database Keys:
2609e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2610e35cf81dSBarry Smith 
2611e35cf81dSBarry Smith    Notes:
2612e35cf81dSBarry Smith    The default is 1
2613e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2614fe3ffe1eSBarry 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
2615fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
2616e35cf81dSBarry Smith 
2617e35cf81dSBarry Smith    Level: intermediate
2618e35cf81dSBarry Smith 
2619e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2620e35cf81dSBarry Smith 
2621e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
2622e35cf81dSBarry Smith 
2623e35cf81dSBarry Smith @*/
26247087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
2625e35cf81dSBarry Smith {
2626e35cf81dSBarry Smith   PetscFunctionBegin;
26270700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2628e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2629e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2630c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2631e35cf81dSBarry Smith   snes->lagjacobian = lag;
2632e35cf81dSBarry Smith   PetscFunctionReturn(0);
2633e35cf81dSBarry Smith }
2634e35cf81dSBarry Smith 
2635e35cf81dSBarry Smith #undef __FUNCT__
2636e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
2637e35cf81dSBarry Smith /*@
2638e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
2639e35cf81dSBarry Smith 
26403f9fe445SBarry Smith    Not Collective
2641e35cf81dSBarry Smith 
2642e35cf81dSBarry Smith    Input Parameter:
2643e35cf81dSBarry Smith .  snes - the SNES context
2644e35cf81dSBarry Smith 
2645e35cf81dSBarry Smith    Output Parameter:
2646e35cf81dSBarry 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
2647e35cf81dSBarry Smith          the Jacobian is built etc.
2648e35cf81dSBarry Smith 
2649e35cf81dSBarry Smith    Options Database Keys:
2650e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2651e35cf81dSBarry Smith 
2652e35cf81dSBarry Smith    Notes:
2653e35cf81dSBarry Smith    The default is 1
2654e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2655e35cf81dSBarry Smith 
2656e35cf81dSBarry Smith    Level: intermediate
2657e35cf81dSBarry Smith 
2658e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2659e35cf81dSBarry Smith 
2660e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
2661e35cf81dSBarry Smith 
2662e35cf81dSBarry Smith @*/
26637087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
2664e35cf81dSBarry Smith {
2665e35cf81dSBarry Smith   PetscFunctionBegin;
26660700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2667e35cf81dSBarry Smith   *lag = snes->lagjacobian;
2668e35cf81dSBarry Smith   PetscFunctionReturn(0);
2669e35cf81dSBarry Smith }
2670e35cf81dSBarry Smith 
2671e35cf81dSBarry Smith #undef __FUNCT__
26724a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
26739b94acceSBarry Smith /*@
2674d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
26759b94acceSBarry Smith 
26763f9fe445SBarry Smith    Logically Collective on SNES
2677c7afd0dbSLois Curfman McInnes 
26789b94acceSBarry Smith    Input Parameters:
2679c7afd0dbSLois Curfman McInnes +  snes - the SNES context
268070441072SBarry Smith .  abstol - absolute convergence tolerance
268133174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
268233174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
268333174efeSLois Curfman McInnes            of the change in the solution between steps
268433174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2685c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2686fee21e36SBarry Smith 
268733174efeSLois Curfman McInnes    Options Database Keys:
268870441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
2689c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
2690c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
2691c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
2692c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
26939b94acceSBarry Smith 
2694d7a720efSLois Curfman McInnes    Notes:
26959b94acceSBarry Smith    The default maximum number of iterations is 50.
26969b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
26979b94acceSBarry Smith 
269836851e7fSLois Curfman McInnes    Level: intermediate
269936851e7fSLois Curfman McInnes 
270033174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
27019b94acceSBarry Smith 
27022492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
27039b94acceSBarry Smith @*/
27047087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
27059b94acceSBarry Smith {
27063a40ed3dSBarry Smith   PetscFunctionBegin;
27070700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2708c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
2709c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
2710c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
2711c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
2712c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
2713c5eb9154SBarry Smith 
2714ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
2715ab54825eSJed Brown     if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol);
2716ab54825eSJed Brown     snes->abstol = abstol;
2717ab54825eSJed Brown   }
2718ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
2719ab54825eSJed 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);
2720ab54825eSJed Brown     snes->rtol = rtol;
2721ab54825eSJed Brown   }
2722ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
2723ab54825eSJed Brown     if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol);
2724c60f73f4SPeter Brune     snes->stol = stol;
2725ab54825eSJed Brown   }
2726ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
2727ab54825eSJed Brown     if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
2728ab54825eSJed Brown     snes->max_its = maxit;
2729ab54825eSJed Brown   }
2730ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
2731ab54825eSJed Brown     if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
2732ab54825eSJed Brown     snes->max_funcs = maxf;
2733ab54825eSJed Brown   }
273488976e71SPeter Brune   snes->tolerancesset = PETSC_TRUE;
27353a40ed3dSBarry Smith   PetscFunctionReturn(0);
27369b94acceSBarry Smith }
27379b94acceSBarry Smith 
27384a2ae208SSatish Balay #undef __FUNCT__
27394a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
27409b94acceSBarry Smith /*@
274133174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
274233174efeSLois Curfman McInnes 
2743c7afd0dbSLois Curfman McInnes    Not Collective
2744c7afd0dbSLois Curfman McInnes 
274533174efeSLois Curfman McInnes    Input Parameters:
2746c7afd0dbSLois Curfman McInnes +  snes - the SNES context
274785385478SLisandro Dalcin .  atol - absolute convergence tolerance
274833174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
274933174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
275033174efeSLois Curfman McInnes            of the change in the solution between steps
275133174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2752c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2753fee21e36SBarry Smith 
275433174efeSLois Curfman McInnes    Notes:
275533174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
275633174efeSLois Curfman McInnes 
275736851e7fSLois Curfman McInnes    Level: intermediate
275836851e7fSLois Curfman McInnes 
275933174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
276033174efeSLois Curfman McInnes 
276133174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
276233174efeSLois Curfman McInnes @*/
27637087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
276433174efeSLois Curfman McInnes {
27653a40ed3dSBarry Smith   PetscFunctionBegin;
27660700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
276785385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
276833174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
2769c60f73f4SPeter Brune   if (stol)  *stol  = snes->stol;
277033174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
277133174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
27723a40ed3dSBarry Smith   PetscFunctionReturn(0);
277333174efeSLois Curfman McInnes }
277433174efeSLois Curfman McInnes 
27754a2ae208SSatish Balay #undef __FUNCT__
27764a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
277733174efeSLois Curfman McInnes /*@
27789b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
27799b94acceSBarry Smith 
27803f9fe445SBarry Smith    Logically Collective on SNES
2781fee21e36SBarry Smith 
2782c7afd0dbSLois Curfman McInnes    Input Parameters:
2783c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2784c7afd0dbSLois Curfman McInnes -  tol - tolerance
2785c7afd0dbSLois Curfman McInnes 
27869b94acceSBarry Smith    Options Database Key:
2787c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
27889b94acceSBarry Smith 
278936851e7fSLois Curfman McInnes    Level: intermediate
279036851e7fSLois Curfman McInnes 
27919b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
27929b94acceSBarry Smith 
27932492ecdbSBarry Smith .seealso: SNESSetTolerances()
27949b94acceSBarry Smith @*/
27957087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
27969b94acceSBarry Smith {
27973a40ed3dSBarry Smith   PetscFunctionBegin;
27980700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2799c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
28009b94acceSBarry Smith   snes->deltatol = tol;
28013a40ed3dSBarry Smith   PetscFunctionReturn(0);
28029b94acceSBarry Smith }
28039b94acceSBarry Smith 
2804df9fa365SBarry Smith /*
2805df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
2806df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
2807df9fa365SBarry Smith    macros instead of functions
2808df9fa365SBarry Smith */
28094a2ae208SSatish Balay #undef __FUNCT__
2810a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
28117087cfbeSBarry Smith PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2812ce1608b8SBarry Smith {
2813dfbe8321SBarry Smith   PetscErrorCode ierr;
2814ce1608b8SBarry Smith 
2815ce1608b8SBarry Smith   PetscFunctionBegin;
28160700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2817a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
2818ce1608b8SBarry Smith   PetscFunctionReturn(0);
2819ce1608b8SBarry Smith }
2820ce1608b8SBarry Smith 
28214a2ae208SSatish Balay #undef __FUNCT__
2822a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
28237087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2824df9fa365SBarry Smith {
2825dfbe8321SBarry Smith   PetscErrorCode ierr;
2826df9fa365SBarry Smith 
2827df9fa365SBarry Smith   PetscFunctionBegin;
2828a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2829df9fa365SBarry Smith   PetscFunctionReturn(0);
2830df9fa365SBarry Smith }
2831df9fa365SBarry Smith 
28324a2ae208SSatish Balay #undef __FUNCT__
2833a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
28346bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
2835df9fa365SBarry Smith {
2836dfbe8321SBarry Smith   PetscErrorCode ierr;
2837df9fa365SBarry Smith 
2838df9fa365SBarry Smith   PetscFunctionBegin;
2839a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2840df9fa365SBarry Smith   PetscFunctionReturn(0);
2841df9fa365SBarry Smith }
2842df9fa365SBarry Smith 
28437087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
2844b271bb04SBarry Smith #undef __FUNCT__
2845b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
28467087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2847b271bb04SBarry Smith {
2848b271bb04SBarry Smith   PetscDrawLG      lg;
2849b271bb04SBarry Smith   PetscErrorCode   ierr;
2850b271bb04SBarry Smith   PetscReal        x,y,per;
2851b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
2852b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
2853b271bb04SBarry Smith   PetscDraw        draw;
2854b271bb04SBarry Smith   PetscFunctionBegin;
2855b271bb04SBarry Smith   if (!monctx) {
2856b271bb04SBarry Smith     MPI_Comm    comm;
2857b271bb04SBarry Smith 
2858b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2859b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
2860b271bb04SBarry Smith   }
2861b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
2862b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2863b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2864b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
2865b271bb04SBarry Smith   x = (PetscReal) n;
2866b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
2867b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2868b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2869b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2870b271bb04SBarry Smith   }
2871b271bb04SBarry Smith 
2872b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
2873b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2874b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2875b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
2876b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
2877b271bb04SBarry Smith   x = (PetscReal) n;
2878b271bb04SBarry Smith   y = 100.0*per;
2879b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2880b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2881b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2882b271bb04SBarry Smith   }
2883b271bb04SBarry Smith 
2884b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
2885b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2886b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2887b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
2888b271bb04SBarry Smith   x = (PetscReal) n;
2889b271bb04SBarry Smith   y = (prev - rnorm)/prev;
2890b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2891b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2892b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2893b271bb04SBarry Smith   }
2894b271bb04SBarry Smith 
2895b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
2896b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2897b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2898b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
2899b271bb04SBarry Smith   x = (PetscReal) n;
2900b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
2901b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
2902b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2903b271bb04SBarry Smith   }
2904b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2905b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2906b271bb04SBarry Smith   }
2907b271bb04SBarry Smith   prev = rnorm;
2908b271bb04SBarry Smith   PetscFunctionReturn(0);
2909b271bb04SBarry Smith }
2910b271bb04SBarry Smith 
2911b271bb04SBarry Smith #undef __FUNCT__
2912b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
29137087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2914b271bb04SBarry Smith {
2915b271bb04SBarry Smith   PetscErrorCode ierr;
2916b271bb04SBarry Smith 
2917b271bb04SBarry Smith   PetscFunctionBegin;
2918b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2919b271bb04SBarry Smith   PetscFunctionReturn(0);
2920b271bb04SBarry Smith }
2921b271bb04SBarry Smith 
2922b271bb04SBarry Smith #undef __FUNCT__
2923b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
29246bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG *draw)
2925b271bb04SBarry Smith {
2926b271bb04SBarry Smith   PetscErrorCode ierr;
2927b271bb04SBarry Smith 
2928b271bb04SBarry Smith   PetscFunctionBegin;
2929b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2930b271bb04SBarry Smith   PetscFunctionReturn(0);
2931b271bb04SBarry Smith }
2932b271bb04SBarry Smith 
29337a03ce2fSLisandro Dalcin #undef __FUNCT__
29347a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
2935228d79bcSJed Brown /*@
2936228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
2937228d79bcSJed Brown 
2938228d79bcSJed Brown    Collective on SNES
2939228d79bcSJed Brown 
2940228d79bcSJed Brown    Input Parameters:
2941228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
2942228d79bcSJed Brown .  iter - iteration number
2943228d79bcSJed Brown -  rnorm - relative norm of the residual
2944228d79bcSJed Brown 
2945228d79bcSJed Brown    Notes:
2946228d79bcSJed Brown    This routine is called by the SNES implementations.
2947228d79bcSJed Brown    It does not typically need to be called by the user.
2948228d79bcSJed Brown 
2949228d79bcSJed Brown    Level: developer
2950228d79bcSJed Brown 
2951228d79bcSJed Brown .seealso: SNESMonitorSet()
2952228d79bcSJed Brown @*/
29537a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
29547a03ce2fSLisandro Dalcin {
29557a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
29567a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
29577a03ce2fSLisandro Dalcin 
29587a03ce2fSLisandro Dalcin   PetscFunctionBegin;
29597a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
29607a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
29617a03ce2fSLisandro Dalcin   }
29627a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
29637a03ce2fSLisandro Dalcin }
29647a03ce2fSLisandro Dalcin 
29659b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
29669b94acceSBarry Smith 
29674a2ae208SSatish Balay #undef __FUNCT__
2968a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
29699b94acceSBarry Smith /*@C
2970a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
29719b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
29729b94acceSBarry Smith    progress.
29739b94acceSBarry Smith 
29743f9fe445SBarry Smith    Logically Collective on SNES
2975fee21e36SBarry Smith 
2976c7afd0dbSLois Curfman McInnes    Input Parameters:
2977c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2978c7afd0dbSLois Curfman McInnes .  func - monitoring routine
2979b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
2980e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
2981b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
2982b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
29839b94acceSBarry Smith 
2984c7afd0dbSLois Curfman McInnes    Calling sequence of func:
2985a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
2986c7afd0dbSLois Curfman McInnes 
2987c7afd0dbSLois Curfman McInnes +    snes - the SNES context
2988c7afd0dbSLois Curfman McInnes .    its - iteration number
2989c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
299040a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
29919b94acceSBarry Smith 
29929665c990SLois Curfman McInnes    Options Database Keys:
2993a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
2994a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
2995a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
2996cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
2997c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
2998a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
2999c7afd0dbSLois Curfman McInnes                             does not cancel those set via
3000c7afd0dbSLois Curfman McInnes                             the options database.
30019665c990SLois Curfman McInnes 
3002639f9d9dSBarry Smith    Notes:
30036bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
3004a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
30056bc08f3fSLois Curfman McInnes    order in which they were set.
3006639f9d9dSBarry Smith 
3007025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
3008025f1a04SBarry Smith 
300936851e7fSLois Curfman McInnes    Level: intermediate
301036851e7fSLois Curfman McInnes 
30119b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
30129b94acceSBarry Smith 
3013a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
30149b94acceSBarry Smith @*/
3015c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
30169b94acceSBarry Smith {
3017b90d0a6eSBarry Smith   PetscInt       i;
3018649052a6SBarry Smith   PetscErrorCode ierr;
3019b90d0a6eSBarry Smith 
30203a40ed3dSBarry Smith   PetscFunctionBegin;
30210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
302217186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
3023b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
3024649052a6SBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
3025649052a6SBarry Smith       if (monitordestroy) {
3026c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
3027649052a6SBarry Smith       }
3028b90d0a6eSBarry Smith       PetscFunctionReturn(0);
3029b90d0a6eSBarry Smith     }
3030b90d0a6eSBarry Smith   }
3031b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
3032b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
3033639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
30343a40ed3dSBarry Smith   PetscFunctionReturn(0);
30359b94acceSBarry Smith }
30369b94acceSBarry Smith 
30374a2ae208SSatish Balay #undef __FUNCT__
3038a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
30395cd90555SBarry Smith /*@C
3040a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
30415cd90555SBarry Smith 
30423f9fe445SBarry Smith    Logically Collective on SNES
3043c7afd0dbSLois Curfman McInnes 
30445cd90555SBarry Smith    Input Parameters:
30455cd90555SBarry Smith .  snes - the SNES context
30465cd90555SBarry Smith 
30471a480d89SAdministrator    Options Database Key:
3048a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
3049a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
3050c7afd0dbSLois Curfman McInnes     set via the options database
30515cd90555SBarry Smith 
30525cd90555SBarry Smith    Notes:
30535cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
30545cd90555SBarry Smith 
305536851e7fSLois Curfman McInnes    Level: intermediate
305636851e7fSLois Curfman McInnes 
30575cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
30585cd90555SBarry Smith 
3059a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
30605cd90555SBarry Smith @*/
30617087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
30625cd90555SBarry Smith {
3063d952e501SBarry Smith   PetscErrorCode ierr;
3064d952e501SBarry Smith   PetscInt       i;
3065d952e501SBarry Smith 
30665cd90555SBarry Smith   PetscFunctionBegin;
30670700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3068d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
3069d952e501SBarry Smith     if (snes->monitordestroy[i]) {
30703c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
3071d952e501SBarry Smith     }
3072d952e501SBarry Smith   }
30735cd90555SBarry Smith   snes->numbermonitors = 0;
30745cd90555SBarry Smith   PetscFunctionReturn(0);
30755cd90555SBarry Smith }
30765cd90555SBarry Smith 
30774a2ae208SSatish Balay #undef __FUNCT__
30784a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
30799b94acceSBarry Smith /*@C
30809b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
30819b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
30829b94acceSBarry Smith 
30833f9fe445SBarry Smith    Logically Collective on SNES
3084fee21e36SBarry Smith 
3085c7afd0dbSLois Curfman McInnes    Input Parameters:
3086c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3087c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
30887f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
30897f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
30909b94acceSBarry Smith 
3091c7afd0dbSLois Curfman McInnes    Calling sequence of func:
309206ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
3093c7afd0dbSLois Curfman McInnes 
3094c7afd0dbSLois Curfman McInnes +    snes - the SNES context
309506ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
3096c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
3097184914b5SBarry Smith .    reason - reason for convergence/divergence
3098c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
30994b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
31004b27c08aSLois Curfman McInnes -    f - 2-norm of function
31019b94acceSBarry Smith 
310236851e7fSLois Curfman McInnes    Level: advanced
310336851e7fSLois Curfman McInnes 
31049b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
31059b94acceSBarry Smith 
310685385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
31079b94acceSBarry Smith @*/
31087087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
31099b94acceSBarry Smith {
31107f7931b9SBarry Smith   PetscErrorCode ierr;
31117f7931b9SBarry Smith 
31123a40ed3dSBarry Smith   PetscFunctionBegin;
31130700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
311485385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
31157f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
31167f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
31177f7931b9SBarry Smith   }
311885385478SLisandro Dalcin   snes->ops->converged        = func;
31197f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
312085385478SLisandro Dalcin   snes->cnvP                  = cctx;
31213a40ed3dSBarry Smith   PetscFunctionReturn(0);
31229b94acceSBarry Smith }
31239b94acceSBarry Smith 
31244a2ae208SSatish Balay #undef __FUNCT__
31254a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
312652baeb72SSatish Balay /*@
3127184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
3128184914b5SBarry Smith 
3129184914b5SBarry Smith    Not Collective
3130184914b5SBarry Smith 
3131184914b5SBarry Smith    Input Parameter:
3132184914b5SBarry Smith .  snes - the SNES context
3133184914b5SBarry Smith 
3134184914b5SBarry Smith    Output Parameter:
31354d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
3136184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
3137184914b5SBarry Smith 
3138184914b5SBarry Smith    Level: intermediate
3139184914b5SBarry Smith 
3140184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
3141184914b5SBarry Smith 
3142184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
3143184914b5SBarry Smith 
314485385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
3145184914b5SBarry Smith @*/
31467087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
3147184914b5SBarry Smith {
3148184914b5SBarry Smith   PetscFunctionBegin;
31490700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
31504482741eSBarry Smith   PetscValidPointer(reason,2);
3151184914b5SBarry Smith   *reason = snes->reason;
3152184914b5SBarry Smith   PetscFunctionReturn(0);
3153184914b5SBarry Smith }
3154184914b5SBarry Smith 
31554a2ae208SSatish Balay #undef __FUNCT__
31564a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
3157c9005455SLois Curfman McInnes /*@
3158c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
3159c9005455SLois Curfman McInnes 
31603f9fe445SBarry Smith    Logically Collective on SNES
3161fee21e36SBarry Smith 
3162c7afd0dbSLois Curfman McInnes    Input Parameters:
3163c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
31648c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
3165cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
3166758f92a0SBarry Smith .  na  - size of a and its
316764731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
3168758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
3169c7afd0dbSLois Curfman McInnes 
3170308dcc3eSBarry Smith    Notes:
3171308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
3172308dcc3eSBarry Smith    default array of length 10000 is allocated.
3173308dcc3eSBarry Smith 
3174c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
3175c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
3176c9005455SLois Curfman McInnes    during the section of code that is being timed.
3177c9005455SLois Curfman McInnes 
317836851e7fSLois Curfman McInnes    Level: intermediate
317936851e7fSLois Curfman McInnes 
3180c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
3181758f92a0SBarry Smith 
318208405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
3183758f92a0SBarry Smith 
3184c9005455SLois Curfman McInnes @*/
31857087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
3186c9005455SLois Curfman McInnes {
3187308dcc3eSBarry Smith   PetscErrorCode ierr;
3188308dcc3eSBarry Smith 
31893a40ed3dSBarry Smith   PetscFunctionBegin;
31900700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
31914482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
3192a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
3193308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
3194308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
3195308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
3196308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
3197308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
3198308dcc3eSBarry Smith   }
3199c9005455SLois Curfman McInnes   snes->conv_hist       = a;
3200758f92a0SBarry Smith   snes->conv_hist_its   = its;
3201758f92a0SBarry Smith   snes->conv_hist_max   = na;
3202a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
3203758f92a0SBarry Smith   snes->conv_hist_reset = reset;
3204758f92a0SBarry Smith   PetscFunctionReturn(0);
3205758f92a0SBarry Smith }
3206758f92a0SBarry Smith 
3207308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3208c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
3209c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
3210308dcc3eSBarry Smith EXTERN_C_BEGIN
3211308dcc3eSBarry Smith #undef __FUNCT__
3212308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
3213308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
3214308dcc3eSBarry Smith {
3215308dcc3eSBarry Smith   mxArray        *mat;
3216308dcc3eSBarry Smith   PetscInt       i;
3217308dcc3eSBarry Smith   PetscReal      *ar;
3218308dcc3eSBarry Smith 
3219308dcc3eSBarry Smith   PetscFunctionBegin;
3220308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
3221308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
3222308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
3223308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
3224308dcc3eSBarry Smith   }
3225308dcc3eSBarry Smith   PetscFunctionReturn(mat);
3226308dcc3eSBarry Smith }
3227308dcc3eSBarry Smith EXTERN_C_END
3228308dcc3eSBarry Smith #endif
3229308dcc3eSBarry Smith 
3230308dcc3eSBarry Smith 
32314a2ae208SSatish Balay #undef __FUNCT__
32324a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
32330c4c9dddSBarry Smith /*@C
3234758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
3235758f92a0SBarry Smith 
32363f9fe445SBarry Smith    Not Collective
3237758f92a0SBarry Smith 
3238758f92a0SBarry Smith    Input Parameter:
3239758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
3240758f92a0SBarry Smith 
3241758f92a0SBarry Smith    Output Parameters:
3242758f92a0SBarry Smith .  a   - array to hold history
3243758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
3244758f92a0SBarry Smith          negative if not converged) for each solve.
3245758f92a0SBarry Smith -  na  - size of a and its
3246758f92a0SBarry Smith 
3247758f92a0SBarry Smith    Notes:
3248758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
3249758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
3250758f92a0SBarry Smith 
3251758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
3252758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
3253758f92a0SBarry Smith    during the section of code that is being timed.
3254758f92a0SBarry Smith 
3255758f92a0SBarry Smith    Level: intermediate
3256758f92a0SBarry Smith 
3257758f92a0SBarry Smith .keywords: SNES, get, convergence, history
3258758f92a0SBarry Smith 
3259758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
3260758f92a0SBarry Smith 
3261758f92a0SBarry Smith @*/
32627087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3263758f92a0SBarry Smith {
3264758f92a0SBarry Smith   PetscFunctionBegin;
32650700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3266758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
3267758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
3268758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
32693a40ed3dSBarry Smith   PetscFunctionReturn(0);
3270c9005455SLois Curfman McInnes }
3271c9005455SLois Curfman McInnes 
3272e74ef692SMatthew Knepley #undef __FUNCT__
3273e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
3274ac226902SBarry Smith /*@C
327576b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
3276eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
32777e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
327876b2cf59SMatthew Knepley 
32793f9fe445SBarry Smith   Logically Collective on SNES
328076b2cf59SMatthew Knepley 
328176b2cf59SMatthew Knepley   Input Parameters:
328276b2cf59SMatthew Knepley . snes - The nonlinear solver context
328376b2cf59SMatthew Knepley . func - The function
328476b2cf59SMatthew Knepley 
328576b2cf59SMatthew Knepley   Calling sequence of func:
3286b5d30489SBarry Smith . func (SNES snes, PetscInt step);
328776b2cf59SMatthew Knepley 
328876b2cf59SMatthew Knepley . step - The current step of the iteration
328976b2cf59SMatthew Knepley 
3290fe97e370SBarry Smith   Level: advanced
3291fe97e370SBarry Smith 
3292fe97e370SBarry 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()
3293fe97e370SBarry Smith         This is not used by most users.
329476b2cf59SMatthew Knepley 
329576b2cf59SMatthew Knepley .keywords: SNES, update
3296b5d30489SBarry Smith 
329785385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
329876b2cf59SMatthew Knepley @*/
32997087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
330076b2cf59SMatthew Knepley {
330176b2cf59SMatthew Knepley   PetscFunctionBegin;
33020700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
3303e7788613SBarry Smith   snes->ops->update = func;
330476b2cf59SMatthew Knepley   PetscFunctionReturn(0);
330576b2cf59SMatthew Knepley }
330676b2cf59SMatthew Knepley 
3307e74ef692SMatthew Knepley #undef __FUNCT__
3308e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
330976b2cf59SMatthew Knepley /*@
331076b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
331176b2cf59SMatthew Knepley 
331276b2cf59SMatthew Knepley   Not collective
331376b2cf59SMatthew Knepley 
331476b2cf59SMatthew Knepley   Input Parameters:
331576b2cf59SMatthew Knepley . snes - The nonlinear solver context
331676b2cf59SMatthew Knepley . step - The current step of the iteration
331776b2cf59SMatthew Knepley 
3318205452f4SMatthew Knepley   Level: intermediate
3319205452f4SMatthew Knepley 
332076b2cf59SMatthew Knepley .keywords: SNES, update
3321a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
332276b2cf59SMatthew Knepley @*/
33237087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
332476b2cf59SMatthew Knepley {
332576b2cf59SMatthew Knepley   PetscFunctionBegin;
332676b2cf59SMatthew Knepley   PetscFunctionReturn(0);
332776b2cf59SMatthew Knepley }
332876b2cf59SMatthew Knepley 
33294a2ae208SSatish Balay #undef __FUNCT__
33304a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
33319b94acceSBarry Smith /*
33329b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
33339b94acceSBarry Smith    positive parameter delta.
33349b94acceSBarry Smith 
33359b94acceSBarry Smith     Input Parameters:
3336c7afd0dbSLois Curfman McInnes +   snes - the SNES context
33379b94acceSBarry Smith .   y - approximate solution of linear system
33389b94acceSBarry Smith .   fnorm - 2-norm of current function
3339c7afd0dbSLois Curfman McInnes -   delta - trust region size
33409b94acceSBarry Smith 
33419b94acceSBarry Smith     Output Parameters:
3342c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
33439b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
33449b94acceSBarry Smith     region, and exceeds zero otherwise.
3345c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
33469b94acceSBarry Smith 
33479b94acceSBarry Smith     Note:
33484b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
33499b94acceSBarry Smith     is set to be the maximum allowable step size.
33509b94acceSBarry Smith 
33519b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
33529b94acceSBarry Smith */
3353dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
33549b94acceSBarry Smith {
3355064f8208SBarry Smith   PetscReal      nrm;
3356ea709b57SSatish Balay   PetscScalar    cnorm;
3357dfbe8321SBarry Smith   PetscErrorCode ierr;
33583a40ed3dSBarry Smith 
33593a40ed3dSBarry Smith   PetscFunctionBegin;
33600700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
33610700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3362c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
3363184914b5SBarry Smith 
3364064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
3365064f8208SBarry Smith   if (nrm > *delta) {
3366064f8208SBarry Smith      nrm = *delta/nrm;
3367064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
3368064f8208SBarry Smith      cnorm = nrm;
33692dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
33709b94acceSBarry Smith      *ynorm = *delta;
33719b94acceSBarry Smith   } else {
33729b94acceSBarry Smith      *gpnorm = 0.0;
3373064f8208SBarry Smith      *ynorm = nrm;
33749b94acceSBarry Smith   }
33753a40ed3dSBarry Smith   PetscFunctionReturn(0);
33769b94acceSBarry Smith }
33779b94acceSBarry Smith 
33784a2ae208SSatish Balay #undef __FUNCT__
33794a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
33806ce558aeSBarry Smith /*@C
3381f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
3382f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
33839b94acceSBarry Smith 
3384c7afd0dbSLois Curfman McInnes    Collective on SNES
3385c7afd0dbSLois Curfman McInnes 
3386b2002411SLois Curfman McInnes    Input Parameters:
3387c7afd0dbSLois Curfman McInnes +  snes - the SNES context
33883cebf274SJed Brown .  b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero.
338985385478SLisandro Dalcin -  x - the solution vector.
33909b94acceSBarry Smith 
3391b2002411SLois Curfman McInnes    Notes:
33928ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
33938ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
33948ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
33958ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
33968ddd3da0SLois Curfman McInnes 
339736851e7fSLois Curfman McInnes    Level: beginner
339836851e7fSLois Curfman McInnes 
33999b94acceSBarry Smith .keywords: SNES, nonlinear, solve
34009b94acceSBarry Smith 
3401c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
34029b94acceSBarry Smith @*/
34037087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
34049b94acceSBarry Smith {
3405dfbe8321SBarry Smith   PetscErrorCode ierr;
3406ace3abfcSBarry Smith   PetscBool      flg;
3407eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
3408eabae89aSBarry Smith   PetscViewer    viewer;
3409efd51863SBarry Smith   PetscInt       grid;
3410a69afd8bSBarry Smith   Vec            xcreated = PETSC_NULL;
3411caa4e7f2SJed Brown   DM             dm;
3412052efed2SBarry Smith 
34133a40ed3dSBarry Smith   PetscFunctionBegin;
34140700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3415a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3416a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
34170700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
341885385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
341985385478SLisandro Dalcin 
3420caa4e7f2SJed Brown   if (!x) {
3421caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3422caa4e7f2SJed Brown     ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr);
3423a69afd8bSBarry Smith     x    = xcreated;
3424a69afd8bSBarry Smith   }
3425a69afd8bSBarry Smith 
3426a8248277SBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);}
3427efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
3428efd51863SBarry Smith 
342985385478SLisandro Dalcin     /* set solution vector */
3430efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
34316bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
343285385478SLisandro Dalcin     snes->vec_sol = x;
3433caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3434caa4e7f2SJed Brown 
3435caa4e7f2SJed Brown     /* set affine vector if provided */
343685385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
34376bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
343885385478SLisandro Dalcin     snes->vec_rhs = b;
343985385478SLisandro Dalcin 
344070e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
34413f149594SLisandro Dalcin 
34427eee914bSBarry Smith     if (!grid) {
34437eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
3444d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
3445dd568438SSatish Balay       } else if (snes->dm) {
3446dd568438SSatish Balay         PetscBool ig;
3447dd568438SSatish Balay         ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr);
3448dd568438SSatish Balay         if (ig) {
34497eee914bSBarry Smith           ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr);
34507eee914bSBarry Smith         }
3451d25893d9SBarry Smith       }
3452dd568438SSatish Balay     }
3453d25893d9SBarry Smith 
3454abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
345550ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
3456d5e45103SBarry Smith 
34573f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
34584936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
345985385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
34604936397dSBarry Smith     if (snes->domainerror){
34614936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
34624936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
34634936397dSBarry Smith     }
346417186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
34653f149594SLisandro Dalcin 
34667adad957SLisandro Dalcin     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
3467eabae89aSBarry Smith     if (flg && !PetscPreLoadingOn) {
34687adad957SLisandro Dalcin       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
3469eabae89aSBarry Smith       ierr = SNESView(snes,viewer);CHKERRQ(ierr);
34706bf464f9SBarry Smith       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3471eabae89aSBarry Smith     }
3472eabae89aSBarry Smith 
347390d69ab7SBarry Smith     flg  = PETSC_FALSE;
3474acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
3475da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
34765968eb51SBarry Smith     if (snes->printreason) {
3477a8248277SBarry Smith       ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
34785968eb51SBarry Smith       if (snes->reason > 0) {
3479c7e7b494SJed 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);
34805968eb51SBarry Smith       } else {
3481c7e7b494SJed 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);
34825968eb51SBarry Smith       }
3483a8248277SBarry Smith       ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
34845968eb51SBarry Smith     }
34855968eb51SBarry Smith 
34868501fc72SJed Brown     flg = PETSC_FALSE;
34878501fc72SJed Brown     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
34888501fc72SJed Brown     if (flg) {
34898501fc72SJed Brown       PetscViewer viewer;
34908501fc72SJed Brown       ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
34918501fc72SJed Brown       ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr);
34928501fc72SJed Brown       ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr);
34938501fc72SJed Brown       ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr);
34948501fc72SJed Brown       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
34958501fc72SJed Brown     }
34968501fc72SJed Brown 
3497e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
3498efd51863SBarry Smith     if (grid <  snes->gridsequence) {
3499efd51863SBarry Smith       DM  fine;
3500efd51863SBarry Smith       Vec xnew;
3501efd51863SBarry Smith       Mat interp;
3502efd51863SBarry Smith 
3503efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
3504c5c77316SJed Brown       if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
3505e727c939SJed Brown       ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
3506efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
3507efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
3508efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
3509efd51863SBarry Smith       x    = xnew;
3510efd51863SBarry Smith 
3511efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
3512efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
3513efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
3514a8248277SBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);
3515efd51863SBarry Smith     }
3516efd51863SBarry Smith   }
3517a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
35183a40ed3dSBarry Smith   PetscFunctionReturn(0);
35199b94acceSBarry Smith }
35209b94acceSBarry Smith 
35219b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
35229b94acceSBarry Smith 
35234a2ae208SSatish Balay #undef __FUNCT__
35244a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
352582bf6240SBarry Smith /*@C
35264b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
35279b94acceSBarry Smith 
3528fee21e36SBarry Smith    Collective on SNES
3529fee21e36SBarry Smith 
3530c7afd0dbSLois Curfman McInnes    Input Parameters:
3531c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3532454a90a3SBarry Smith -  type - a known method
3533c7afd0dbSLois Curfman McInnes 
3534c7afd0dbSLois Curfman McInnes    Options Database Key:
3535454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
3536c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
3537ae12b187SLois Curfman McInnes 
35389b94acceSBarry Smith    Notes:
3539e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
35404b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
3541c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
35424b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
3543c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
35449b94acceSBarry Smith 
3545ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
3546ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
3547ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
3548ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
3549ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
3550ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
3551ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
3552ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
3553ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
3554b0a32e0cSBarry Smith   appropriate method.
355536851e7fSLois Curfman McInnes 
355636851e7fSLois Curfman McInnes   Level: intermediate
3557a703fe33SLois Curfman McInnes 
3558454a90a3SBarry Smith .keywords: SNES, set, type
3559435da068SBarry Smith 
3560435da068SBarry Smith .seealso: SNESType, SNESCreate()
3561435da068SBarry Smith 
35629b94acceSBarry Smith @*/
35637087cfbeSBarry Smith PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
35649b94acceSBarry Smith {
3565dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
3566ace3abfcSBarry Smith   PetscBool      match;
35673a40ed3dSBarry Smith 
35683a40ed3dSBarry Smith   PetscFunctionBegin;
35690700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35704482741eSBarry Smith   PetscValidCharPointer(type,2);
357182bf6240SBarry Smith 
3572*251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
35730f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
357492ff6ae8SBarry Smith 
35754b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
3576e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
357775396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
3578b5c23020SJed Brown   if (snes->ops->destroy) {
3579b5c23020SJed Brown     ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
3580b5c23020SJed Brown     snes->ops->destroy = PETSC_NULL;
3581b5c23020SJed Brown   }
358275396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
358375396ef9SLisandro Dalcin   snes->ops->setup          = 0;
358475396ef9SLisandro Dalcin   snes->ops->solve          = 0;
358575396ef9SLisandro Dalcin   snes->ops->view           = 0;
358675396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
358775396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
358875396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
358975396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
3590454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
359103bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
35929fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
35939fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
35949fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
35959fb22e1aSBarry Smith   }
35969fb22e1aSBarry Smith #endif
35973a40ed3dSBarry Smith   PetscFunctionReturn(0);
35989b94acceSBarry Smith }
35999b94acceSBarry Smith 
3600a847f771SSatish Balay 
36019b94acceSBarry Smith /* --------------------------------------------------------------------- */
36024a2ae208SSatish Balay #undef __FUNCT__
36034a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
360452baeb72SSatish Balay /*@
36059b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
3606f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
36079b94acceSBarry Smith 
3608fee21e36SBarry Smith    Not Collective
3609fee21e36SBarry Smith 
361036851e7fSLois Curfman McInnes    Level: advanced
361136851e7fSLois Curfman McInnes 
36129b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
36139b94acceSBarry Smith 
36149b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
36159b94acceSBarry Smith @*/
36167087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
36179b94acceSBarry Smith {
3618dfbe8321SBarry Smith   PetscErrorCode ierr;
361982bf6240SBarry Smith 
36203a40ed3dSBarry Smith   PetscFunctionBegin;
36211441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
36224c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
36233a40ed3dSBarry Smith   PetscFunctionReturn(0);
36249b94acceSBarry Smith }
36259b94acceSBarry Smith 
36264a2ae208SSatish Balay #undef __FUNCT__
36274a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
36289b94acceSBarry Smith /*@C
36299a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
36309b94acceSBarry Smith 
3631c7afd0dbSLois Curfman McInnes    Not Collective
3632c7afd0dbSLois Curfman McInnes 
36339b94acceSBarry Smith    Input Parameter:
36344b0e389bSBarry Smith .  snes - nonlinear solver context
36359b94acceSBarry Smith 
36369b94acceSBarry Smith    Output Parameter:
36373a7fca6bSBarry Smith .  type - SNES method (a character string)
36389b94acceSBarry Smith 
363936851e7fSLois Curfman McInnes    Level: intermediate
364036851e7fSLois Curfman McInnes 
3641454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
36429b94acceSBarry Smith @*/
36437087cfbeSBarry Smith PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
36449b94acceSBarry Smith {
36453a40ed3dSBarry Smith   PetscFunctionBegin;
36460700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36474482741eSBarry Smith   PetscValidPointer(type,2);
36487adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
36493a40ed3dSBarry Smith   PetscFunctionReturn(0);
36509b94acceSBarry Smith }
36519b94acceSBarry Smith 
36524a2ae208SSatish Balay #undef __FUNCT__
36534a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
365452baeb72SSatish Balay /*@
36559b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
3656c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
36579b94acceSBarry Smith 
3658c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3659c7afd0dbSLois Curfman McInnes 
36609b94acceSBarry Smith    Input Parameter:
36619b94acceSBarry Smith .  snes - the SNES context
36629b94acceSBarry Smith 
36639b94acceSBarry Smith    Output Parameter:
36649b94acceSBarry Smith .  x - the solution
36659b94acceSBarry Smith 
366670e92668SMatthew Knepley    Level: intermediate
366736851e7fSLois Curfman McInnes 
36689b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
36699b94acceSBarry Smith 
367085385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
36719b94acceSBarry Smith @*/
36727087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
36739b94acceSBarry Smith {
36743a40ed3dSBarry Smith   PetscFunctionBegin;
36750700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36764482741eSBarry Smith   PetscValidPointer(x,2);
367785385478SLisandro Dalcin   *x = snes->vec_sol;
367870e92668SMatthew Knepley   PetscFunctionReturn(0);
367970e92668SMatthew Knepley }
368070e92668SMatthew Knepley 
368170e92668SMatthew Knepley #undef __FUNCT__
36824a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
368352baeb72SSatish Balay /*@
36849b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
36859b94acceSBarry Smith    stored.
36869b94acceSBarry Smith 
3687c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3688c7afd0dbSLois Curfman McInnes 
36899b94acceSBarry Smith    Input Parameter:
36909b94acceSBarry Smith .  snes - the SNES context
36919b94acceSBarry Smith 
36929b94acceSBarry Smith    Output Parameter:
36939b94acceSBarry Smith .  x - the solution update
36949b94acceSBarry Smith 
369536851e7fSLois Curfman McInnes    Level: advanced
369636851e7fSLois Curfman McInnes 
36979b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
36989b94acceSBarry Smith 
369985385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
37009b94acceSBarry Smith @*/
37017087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
37029b94acceSBarry Smith {
37033a40ed3dSBarry Smith   PetscFunctionBegin;
37040700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37054482741eSBarry Smith   PetscValidPointer(x,2);
370685385478SLisandro Dalcin   *x = snes->vec_sol_update;
37073a40ed3dSBarry Smith   PetscFunctionReturn(0);
37089b94acceSBarry Smith }
37099b94acceSBarry Smith 
37104a2ae208SSatish Balay #undef __FUNCT__
37114a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
37129b94acceSBarry Smith /*@C
37133638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
37149b94acceSBarry Smith 
3715a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
3716c7afd0dbSLois Curfman McInnes 
37179b94acceSBarry Smith    Input Parameter:
37189b94acceSBarry Smith .  snes - the SNES context
37199b94acceSBarry Smith 
37209b94acceSBarry Smith    Output Parameter:
37217bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
372270e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
372370e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
37249b94acceSBarry Smith 
372536851e7fSLois Curfman McInnes    Level: advanced
372636851e7fSLois Curfman McInnes 
3727a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
37289b94acceSBarry Smith 
37294b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
37309b94acceSBarry Smith @*/
37317087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
37329b94acceSBarry Smith {
3733a63bb30eSJed Brown   PetscErrorCode ierr;
37346cab3a1bSJed Brown   DM             dm;
3735a63bb30eSJed Brown 
37363a40ed3dSBarry Smith   PetscFunctionBegin;
37370700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3738a63bb30eSJed Brown   if (r) {
3739a63bb30eSJed Brown     if (!snes->vec_func) {
3740a63bb30eSJed Brown       if (snes->vec_rhs) {
3741a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
3742a63bb30eSJed Brown       } else if (snes->vec_sol) {
3743a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
3744a63bb30eSJed Brown       } else if (snes->dm) {
3745a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
3746a63bb30eSJed Brown       }
3747a63bb30eSJed Brown     }
3748a63bb30eSJed Brown     *r = snes->vec_func;
3749a63bb30eSJed Brown   }
37506cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
37516cab3a1bSJed Brown   ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr);
37523a40ed3dSBarry Smith   PetscFunctionReturn(0);
37539b94acceSBarry Smith }
37549b94acceSBarry Smith 
3755c79ef259SPeter Brune /*@C
3756c79ef259SPeter Brune    SNESGetGS - Returns the GS function and context.
3757c79ef259SPeter Brune 
3758c79ef259SPeter Brune    Input Parameter:
3759c79ef259SPeter Brune .  snes - the SNES context
3760c79ef259SPeter Brune 
3761c79ef259SPeter Brune    Output Parameter:
3762c79ef259SPeter Brune +  gsfunc - the function (or PETSC_NULL)
3763c79ef259SPeter Brune -  ctx    - the function context (or PETSC_NULL)
3764c79ef259SPeter Brune 
3765c79ef259SPeter Brune    Level: advanced
3766c79ef259SPeter Brune 
3767c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
3768c79ef259SPeter Brune 
3769c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction()
3770c79ef259SPeter Brune @*/
3771c79ef259SPeter Brune 
37724a2ae208SSatish Balay #undef __FUNCT__
3773646217ecSPeter Brune #define __FUNCT__ "SNESGetGS"
3774646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx)
3775646217ecSPeter Brune {
37766cab3a1bSJed Brown   PetscErrorCode ierr;
37776cab3a1bSJed Brown   DM             dm;
37786cab3a1bSJed Brown 
3779646217ecSPeter Brune   PetscFunctionBegin;
3780646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37816cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
37826cab3a1bSJed Brown   ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr);
3783646217ecSPeter Brune   PetscFunctionReturn(0);
3784646217ecSPeter Brune }
3785646217ecSPeter Brune 
37864a2ae208SSatish Balay #undef __FUNCT__
37874a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
37883c7409f5SSatish Balay /*@C
37893c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
3790d850072dSLois Curfman McInnes    SNES options in the database.
37913c7409f5SSatish Balay 
37923f9fe445SBarry Smith    Logically Collective on SNES
3793fee21e36SBarry Smith 
3794c7afd0dbSLois Curfman McInnes    Input Parameter:
3795c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3796c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3797c7afd0dbSLois Curfman McInnes 
3798d850072dSLois Curfman McInnes    Notes:
3799a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3800c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3801d850072dSLois Curfman McInnes 
380236851e7fSLois Curfman McInnes    Level: advanced
380336851e7fSLois Curfman McInnes 
38043c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
3805a86d99e1SLois Curfman McInnes 
3806a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
38073c7409f5SSatish Balay @*/
38087087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
38093c7409f5SSatish Balay {
3810dfbe8321SBarry Smith   PetscErrorCode ierr;
38113c7409f5SSatish Balay 
38123a40ed3dSBarry Smith   PetscFunctionBegin;
38130700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3814639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
38151cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
381694b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
38173a40ed3dSBarry Smith   PetscFunctionReturn(0);
38183c7409f5SSatish Balay }
38193c7409f5SSatish Balay 
38204a2ae208SSatish Balay #undef __FUNCT__
38214a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
38223c7409f5SSatish Balay /*@C
3823f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
3824d850072dSLois Curfman McInnes    SNES options in the database.
38253c7409f5SSatish Balay 
38263f9fe445SBarry Smith    Logically Collective on SNES
3827fee21e36SBarry Smith 
3828c7afd0dbSLois Curfman McInnes    Input Parameters:
3829c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3830c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3831c7afd0dbSLois Curfman McInnes 
3832d850072dSLois Curfman McInnes    Notes:
3833a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3834c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3835d850072dSLois Curfman McInnes 
383636851e7fSLois Curfman McInnes    Level: advanced
383736851e7fSLois Curfman McInnes 
38383c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
3839a86d99e1SLois Curfman McInnes 
3840a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
38413c7409f5SSatish Balay @*/
38427087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
38433c7409f5SSatish Balay {
3844dfbe8321SBarry Smith   PetscErrorCode ierr;
38453c7409f5SSatish Balay 
38463a40ed3dSBarry Smith   PetscFunctionBegin;
38470700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3848639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
38491cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
385094b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
38513a40ed3dSBarry Smith   PetscFunctionReturn(0);
38523c7409f5SSatish Balay }
38533c7409f5SSatish Balay 
38544a2ae208SSatish Balay #undef __FUNCT__
38554a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
38569ab63eb5SSatish Balay /*@C
38573c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
38583c7409f5SSatish Balay    SNES options in the database.
38593c7409f5SSatish Balay 
3860c7afd0dbSLois Curfman McInnes    Not Collective
3861c7afd0dbSLois Curfman McInnes 
38623c7409f5SSatish Balay    Input Parameter:
38633c7409f5SSatish Balay .  snes - the SNES context
38643c7409f5SSatish Balay 
38653c7409f5SSatish Balay    Output Parameter:
38663c7409f5SSatish Balay .  prefix - pointer to the prefix string used
38673c7409f5SSatish Balay 
38684ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
38699ab63eb5SSatish Balay    sufficient length to hold the prefix.
38709ab63eb5SSatish Balay 
387136851e7fSLois Curfman McInnes    Level: advanced
387236851e7fSLois Curfman McInnes 
38733c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
3874a86d99e1SLois Curfman McInnes 
3875a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
38763c7409f5SSatish Balay @*/
38777087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
38783c7409f5SSatish Balay {
3879dfbe8321SBarry Smith   PetscErrorCode ierr;
38803c7409f5SSatish Balay 
38813a40ed3dSBarry Smith   PetscFunctionBegin;
38820700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3883639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
38843a40ed3dSBarry Smith   PetscFunctionReturn(0);
38853c7409f5SSatish Balay }
38863c7409f5SSatish Balay 
3887b2002411SLois Curfman McInnes 
38884a2ae208SSatish Balay #undef __FUNCT__
38894a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
38903cea93caSBarry Smith /*@C
38913cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
38923cea93caSBarry Smith 
38937f6c08e0SMatthew Knepley   Level: advanced
38943cea93caSBarry Smith @*/
38957087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
3896b2002411SLois Curfman McInnes {
3897e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
3898dfbe8321SBarry Smith   PetscErrorCode ierr;
3899b2002411SLois Curfman McInnes 
3900b2002411SLois Curfman McInnes   PetscFunctionBegin;
3901b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3902c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3903b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
3904b2002411SLois Curfman McInnes }
3905da9b6338SBarry Smith 
3906da9b6338SBarry Smith #undef __FUNCT__
3907da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
39087087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
3909da9b6338SBarry Smith {
3910dfbe8321SBarry Smith   PetscErrorCode ierr;
391177431f27SBarry Smith   PetscInt       N,i,j;
3912da9b6338SBarry Smith   Vec            u,uh,fh;
3913da9b6338SBarry Smith   PetscScalar    value;
3914da9b6338SBarry Smith   PetscReal      norm;
3915da9b6338SBarry Smith 
3916da9b6338SBarry Smith   PetscFunctionBegin;
3917da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
3918da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
3919da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
3920da9b6338SBarry Smith 
3921da9b6338SBarry Smith   /* currently only works for sequential */
3922da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
3923da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
3924da9b6338SBarry Smith   for (i=0; i<N; i++) {
3925da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
392677431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
3927da9b6338SBarry Smith     for (j=-10; j<11; j++) {
3928ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
3929da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
39303ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
3931da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
393277431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
3933da9b6338SBarry Smith       value = -value;
3934da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
3935da9b6338SBarry Smith     }
3936da9b6338SBarry Smith   }
39376bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
39386bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
3939da9b6338SBarry Smith   PetscFunctionReturn(0);
3940da9b6338SBarry Smith }
394171f87433Sdalcinl 
394271f87433Sdalcinl #undef __FUNCT__
3943fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
394471f87433Sdalcinl /*@
3945fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
394671f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
394771f87433Sdalcinl    Newton method.
394871f87433Sdalcinl 
39493f9fe445SBarry Smith    Logically Collective on SNES
395071f87433Sdalcinl 
395171f87433Sdalcinl    Input Parameters:
395271f87433Sdalcinl +  snes - SNES context
395371f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
395471f87433Sdalcinl 
395564ba62caSBarry Smith     Options Database:
395664ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
395764ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
395864ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
395964ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
396064ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
396164ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
396264ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
396364ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
396464ba62caSBarry Smith 
396571f87433Sdalcinl    Notes:
396671f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
396771f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
396871f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
396971f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
397071f87433Sdalcinl    solver.
397171f87433Sdalcinl 
397271f87433Sdalcinl    Level: advanced
397371f87433Sdalcinl 
397471f87433Sdalcinl    Reference:
397571f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
397671f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
397771f87433Sdalcinl 
397871f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
397971f87433Sdalcinl 
3980fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
398171f87433Sdalcinl @*/
39827087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
398371f87433Sdalcinl {
398471f87433Sdalcinl   PetscFunctionBegin;
39850700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3986acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
398771f87433Sdalcinl   snes->ksp_ewconv = flag;
398871f87433Sdalcinl   PetscFunctionReturn(0);
398971f87433Sdalcinl }
399071f87433Sdalcinl 
399171f87433Sdalcinl #undef __FUNCT__
3992fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
399371f87433Sdalcinl /*@
3994fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
399571f87433Sdalcinl    for computing relative tolerance for linear solvers within an
399671f87433Sdalcinl    inexact Newton method.
399771f87433Sdalcinl 
399871f87433Sdalcinl    Not Collective
399971f87433Sdalcinl 
400071f87433Sdalcinl    Input Parameter:
400171f87433Sdalcinl .  snes - SNES context
400271f87433Sdalcinl 
400371f87433Sdalcinl    Output Parameter:
400471f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
400571f87433Sdalcinl 
400671f87433Sdalcinl    Notes:
400771f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
400871f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
400971f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
401071f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
401171f87433Sdalcinl    solver.
401271f87433Sdalcinl 
401371f87433Sdalcinl    Level: advanced
401471f87433Sdalcinl 
401571f87433Sdalcinl    Reference:
401671f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
401771f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
401871f87433Sdalcinl 
401971f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
402071f87433Sdalcinl 
4021fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
402271f87433Sdalcinl @*/
40237087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
402471f87433Sdalcinl {
402571f87433Sdalcinl   PetscFunctionBegin;
40260700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
402771f87433Sdalcinl   PetscValidPointer(flag,2);
402871f87433Sdalcinl   *flag = snes->ksp_ewconv;
402971f87433Sdalcinl   PetscFunctionReturn(0);
403071f87433Sdalcinl }
403171f87433Sdalcinl 
403271f87433Sdalcinl #undef __FUNCT__
4033fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
403471f87433Sdalcinl /*@
4035fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
403671f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
403771f87433Sdalcinl    Newton method.
403871f87433Sdalcinl 
40393f9fe445SBarry Smith    Logically Collective on SNES
404071f87433Sdalcinl 
404171f87433Sdalcinl    Input Parameters:
404271f87433Sdalcinl +    snes - SNES context
404371f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
404471f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
404571f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
404671f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
404771f87433Sdalcinl              (0 <= gamma2 <= 1)
404871f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
404971f87433Sdalcinl .    alpha2 - power for safeguard
405071f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
405171f87433Sdalcinl 
405271f87433Sdalcinl    Note:
405371f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
405471f87433Sdalcinl 
405571f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
405671f87433Sdalcinl 
405771f87433Sdalcinl    Level: advanced
405871f87433Sdalcinl 
405971f87433Sdalcinl    Reference:
406071f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
406171f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
406271f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
406371f87433Sdalcinl 
406471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
406571f87433Sdalcinl 
4066fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
406771f87433Sdalcinl @*/
40687087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
406971f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
407071f87433Sdalcinl {
4071fa9f3622SBarry Smith   SNESKSPEW *kctx;
407271f87433Sdalcinl   PetscFunctionBegin;
40730700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4074fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4075e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
4076c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
4077c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
4078c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
4079c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
4080c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
4081c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
4082c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
408371f87433Sdalcinl 
408471f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
408571f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
408671f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
408771f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
408871f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
408971f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
409071f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
409171f87433Sdalcinl 
409271f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
4093e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
409471f87433Sdalcinl   }
409571f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
4096e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
409771f87433Sdalcinl   }
409871f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
4099e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
410071f87433Sdalcinl   }
410171f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
4102e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
410371f87433Sdalcinl   }
410471f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
4105e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
410671f87433Sdalcinl   }
410771f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
4108e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
410971f87433Sdalcinl   }
411071f87433Sdalcinl   PetscFunctionReturn(0);
411171f87433Sdalcinl }
411271f87433Sdalcinl 
411371f87433Sdalcinl #undef __FUNCT__
4114fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
411571f87433Sdalcinl /*@
4116fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
411771f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
411871f87433Sdalcinl    Newton method.
411971f87433Sdalcinl 
412071f87433Sdalcinl    Not Collective
412171f87433Sdalcinl 
412271f87433Sdalcinl    Input Parameters:
412371f87433Sdalcinl      snes - SNES context
412471f87433Sdalcinl 
412571f87433Sdalcinl    Output Parameters:
412671f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
412771f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
412871f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
412971f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
413071f87433Sdalcinl              (0 <= gamma2 <= 1)
413171f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
413271f87433Sdalcinl .    alpha2 - power for safeguard
413371f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
413471f87433Sdalcinl 
413571f87433Sdalcinl    Level: advanced
413671f87433Sdalcinl 
413771f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
413871f87433Sdalcinl 
4139fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
414071f87433Sdalcinl @*/
41417087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
414271f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
414371f87433Sdalcinl {
4144fa9f3622SBarry Smith   SNESKSPEW *kctx;
414571f87433Sdalcinl   PetscFunctionBegin;
41460700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4147fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4148e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
414971f87433Sdalcinl   if(version)   *version   = kctx->version;
415071f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
415171f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
415271f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
415371f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
415471f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
415571f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
415671f87433Sdalcinl   PetscFunctionReturn(0);
415771f87433Sdalcinl }
415871f87433Sdalcinl 
415971f87433Sdalcinl #undef __FUNCT__
4160fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
4161fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
416271f87433Sdalcinl {
416371f87433Sdalcinl   PetscErrorCode ierr;
4164fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
416571f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
416671f87433Sdalcinl 
416771f87433Sdalcinl   PetscFunctionBegin;
4168e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
416971f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
417071f87433Sdalcinl     rtol = kctx->rtol_0;
417171f87433Sdalcinl   } else {
417271f87433Sdalcinl     if (kctx->version == 1) {
417371f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
417471f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
417571f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
417671f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
417771f87433Sdalcinl     } else if (kctx->version == 2) {
417871f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
417971f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
418071f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
418171f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
418271f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
418371f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
418471f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
418571f87433Sdalcinl       stol = PetscMax(rtol,stol);
418671f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
418771f87433Sdalcinl       /* safeguard: avoid oversolving */
418871f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
418971f87433Sdalcinl       stol = PetscMax(rtol,stol);
419071f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
4191e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
419271f87433Sdalcinl   }
419371f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
419471f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
419571f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
419671f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
419771f87433Sdalcinl   PetscFunctionReturn(0);
419871f87433Sdalcinl }
419971f87433Sdalcinl 
420071f87433Sdalcinl #undef __FUNCT__
4201fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
4202fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
420371f87433Sdalcinl {
420471f87433Sdalcinl   PetscErrorCode ierr;
4205fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
420671f87433Sdalcinl   PCSide         pcside;
420771f87433Sdalcinl   Vec            lres;
420871f87433Sdalcinl 
420971f87433Sdalcinl   PetscFunctionBegin;
4210e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
421171f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
421271f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
421371f87433Sdalcinl   if (kctx->version == 1) {
4214b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
421571f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
421671f87433Sdalcinl       /* KSP residual is true linear residual */
421771f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
421871f87433Sdalcinl     } else {
421971f87433Sdalcinl       /* KSP residual is preconditioned residual */
422071f87433Sdalcinl       /* compute true linear residual norm */
422171f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
422271f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
422371f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
422471f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
42256bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
422671f87433Sdalcinl     }
422771f87433Sdalcinl   }
422871f87433Sdalcinl   PetscFunctionReturn(0);
422971f87433Sdalcinl }
423071f87433Sdalcinl 
423171f87433Sdalcinl #undef __FUNCT__
423271f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
423371f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
423471f87433Sdalcinl {
423571f87433Sdalcinl   PetscErrorCode ierr;
423671f87433Sdalcinl 
423771f87433Sdalcinl   PetscFunctionBegin;
4238fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
423971f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
4240fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
424171f87433Sdalcinl   PetscFunctionReturn(0);
424271f87433Sdalcinl }
42436c699258SBarry Smith 
42446c699258SBarry Smith #undef __FUNCT__
42456c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
42466c699258SBarry Smith /*@
42476c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
42486c699258SBarry Smith 
42493f9fe445SBarry Smith    Logically Collective on SNES
42506c699258SBarry Smith 
42516c699258SBarry Smith    Input Parameters:
42526c699258SBarry Smith +  snes - the preconditioner context
42536c699258SBarry Smith -  dm - the dm
42546c699258SBarry Smith 
42556c699258SBarry Smith    Level: intermediate
42566c699258SBarry Smith 
42576c699258SBarry Smith 
42586c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
42596c699258SBarry Smith @*/
42607087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
42616c699258SBarry Smith {
42626c699258SBarry Smith   PetscErrorCode ierr;
4263345fed2cSBarry Smith   KSP            ksp;
42646cab3a1bSJed Brown   SNESDM         sdm;
42656c699258SBarry Smith 
42666c699258SBarry Smith   PetscFunctionBegin;
42670700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4268d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
42696cab3a1bSJed Brown   if (snes->dm) {               /* Move the SNESDM context over to the new DM unless the new DM already has one */
42706cab3a1bSJed Brown     PetscContainer oldcontainer,container;
42716cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr);
42726cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr);
42736cab3a1bSJed Brown     if (oldcontainer && !container) {
42746cab3a1bSJed Brown       ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr);
42756cab3a1bSJed Brown       ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr);
42766cab3a1bSJed Brown       if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */
42776cab3a1bSJed Brown         sdm->originaldm = dm;
42786cab3a1bSJed Brown       }
42796cab3a1bSJed Brown     }
42806bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
42816cab3a1bSJed Brown   }
42826c699258SBarry Smith   snes->dm = dm;
4283345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4284345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4285f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
42862c155ee1SBarry Smith   if (snes->pc) {
42872c155ee1SBarry Smith     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
42882c155ee1SBarry Smith   }
42896c699258SBarry Smith   PetscFunctionReturn(0);
42906c699258SBarry Smith }
42916c699258SBarry Smith 
42926c699258SBarry Smith #undef __FUNCT__
42936c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
42946c699258SBarry Smith /*@
42956c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
42966c699258SBarry Smith 
42973f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
42986c699258SBarry Smith 
42996c699258SBarry Smith    Input Parameter:
43006c699258SBarry Smith . snes - the preconditioner context
43016c699258SBarry Smith 
43026c699258SBarry Smith    Output Parameter:
43036c699258SBarry Smith .  dm - the dm
43046c699258SBarry Smith 
43056c699258SBarry Smith    Level: intermediate
43066c699258SBarry Smith 
43076c699258SBarry Smith 
43086c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
43096c699258SBarry Smith @*/
43107087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
43116c699258SBarry Smith {
43126cab3a1bSJed Brown   PetscErrorCode ierr;
43136cab3a1bSJed Brown 
43146c699258SBarry Smith   PetscFunctionBegin;
43150700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
43166cab3a1bSJed Brown   if (!snes->dm) {
43176cab3a1bSJed Brown     ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr);
43186cab3a1bSJed Brown   }
43196c699258SBarry Smith   *dm = snes->dm;
43206c699258SBarry Smith   PetscFunctionReturn(0);
43216c699258SBarry Smith }
43220807856dSBarry Smith 
432331823bd8SMatthew G Knepley #undef __FUNCT__
432431823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
432531823bd8SMatthew G Knepley /*@
4326fd4b34e9SJed Brown   SNESSetPC - Sets the nonlinear preconditioner to be used.
432731823bd8SMatthew G Knepley 
432831823bd8SMatthew G Knepley   Collective on SNES
432931823bd8SMatthew G Knepley 
433031823bd8SMatthew G Knepley   Input Parameters:
433131823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
433231823bd8SMatthew G Knepley - pc   - the preconditioner object
433331823bd8SMatthew G Knepley 
433431823bd8SMatthew G Knepley   Notes:
433531823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
433631823bd8SMatthew G Knepley   to configure it using the API).
433731823bd8SMatthew G Knepley 
433831823bd8SMatthew G Knepley   Level: developer
433931823bd8SMatthew G Knepley 
434031823bd8SMatthew G Knepley .keywords: SNES, set, precondition
434131823bd8SMatthew G Knepley .seealso: SNESGetPC()
434231823bd8SMatthew G Knepley @*/
434331823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
434431823bd8SMatthew G Knepley {
434531823bd8SMatthew G Knepley   PetscErrorCode ierr;
434631823bd8SMatthew G Knepley 
434731823bd8SMatthew G Knepley   PetscFunctionBegin;
434831823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
434931823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
435031823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
435131823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4352bf11d3b6SBarry Smith   ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr);
435331823bd8SMatthew G Knepley   snes->pc = pc;
435431823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
435531823bd8SMatthew G Knepley   PetscFunctionReturn(0);
435631823bd8SMatthew G Knepley }
435731823bd8SMatthew G Knepley 
435831823bd8SMatthew G Knepley #undef __FUNCT__
435931823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
436031823bd8SMatthew G Knepley /*@
4361fd4b34e9SJed Brown   SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().
436231823bd8SMatthew G Knepley 
436331823bd8SMatthew G Knepley   Not Collective
436431823bd8SMatthew G Knepley 
436531823bd8SMatthew G Knepley   Input Parameter:
436631823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
436731823bd8SMatthew G Knepley 
436831823bd8SMatthew G Knepley   Output Parameter:
436931823bd8SMatthew G Knepley . pc - preconditioner context
437031823bd8SMatthew G Knepley 
437131823bd8SMatthew G Knepley   Level: developer
437231823bd8SMatthew G Knepley 
437331823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
437431823bd8SMatthew G Knepley .seealso: SNESSetPC()
437531823bd8SMatthew G Knepley @*/
437631823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
437731823bd8SMatthew G Knepley {
437831823bd8SMatthew G Knepley   PetscErrorCode ierr;
437931823bd8SMatthew G Knepley 
438031823bd8SMatthew G Knepley   PetscFunctionBegin;
438131823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
438231823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
438331823bd8SMatthew G Knepley   if (!snes->pc) {
438431823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr);
43854a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr);
438631823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
438731823bd8SMatthew G Knepley   }
438831823bd8SMatthew G Knepley   *pc = snes->pc;
438931823bd8SMatthew G Knepley   PetscFunctionReturn(0);
439031823bd8SMatthew G Knepley }
439131823bd8SMatthew G Knepley 
43929e764e56SPeter Brune #undef __FUNCT__
4393f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch"
43949e764e56SPeter Brune /*@
43958141a3b9SPeter Brune   SNESSetSNESLineSearch - Sets the linesearch on the SNES instance.
43969e764e56SPeter Brune 
43979e764e56SPeter Brune   Collective on SNES
43989e764e56SPeter Brune 
43999e764e56SPeter Brune   Input Parameters:
44009e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
44019e764e56SPeter Brune - linesearch   - the linesearch object
44029e764e56SPeter Brune 
44039e764e56SPeter Brune   Notes:
4404f1c6b773SPeter Brune   Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example,
44059e764e56SPeter Brune   to configure it using the API).
44069e764e56SPeter Brune 
44079e764e56SPeter Brune   Level: developer
44089e764e56SPeter Brune 
44099e764e56SPeter Brune .keywords: SNES, set, linesearch
4410f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch()
44119e764e56SPeter Brune @*/
4412f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch)
44139e764e56SPeter Brune {
44149e764e56SPeter Brune   PetscErrorCode ierr;
44159e764e56SPeter Brune 
44169e764e56SPeter Brune   PetscFunctionBegin;
44179e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4418f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
44199e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
44209e764e56SPeter Brune   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
4421f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
44229e764e56SPeter Brune   snes->linesearch = linesearch;
44239e764e56SPeter Brune   ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
44249e764e56SPeter Brune   PetscFunctionReturn(0);
44259e764e56SPeter Brune }
44269e764e56SPeter Brune 
44279e764e56SPeter Brune #undef __FUNCT__
4428f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch"
4429ea5d4fccSPeter Brune /*@C
44308141a3b9SPeter Brune   SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch()
44318141a3b9SPeter Brune   or creates a default line search instance associated with the SNES and returns it.
44329e764e56SPeter Brune 
44339e764e56SPeter Brune   Not Collective
44349e764e56SPeter Brune 
44359e764e56SPeter Brune   Input Parameter:
44369e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
44379e764e56SPeter Brune 
44389e764e56SPeter Brune   Output Parameter:
44399e764e56SPeter Brune . linesearch - linesearch context
44409e764e56SPeter Brune 
44419e764e56SPeter Brune   Level: developer
44429e764e56SPeter Brune 
44439e764e56SPeter Brune .keywords: SNES, get, linesearch
4444f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch()
44459e764e56SPeter Brune @*/
4446f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch)
44479e764e56SPeter Brune {
44489e764e56SPeter Brune   PetscErrorCode ierr;
44499e764e56SPeter Brune   const char     *optionsprefix;
44509e764e56SPeter Brune 
44519e764e56SPeter Brune   PetscFunctionBegin;
44529e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
44539e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
44549e764e56SPeter Brune   if (!snes->linesearch) {
44559e764e56SPeter Brune     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
4456f1c6b773SPeter Brune     ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr);
4457f1c6b773SPeter Brune     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
4458b1dca40bSPeter Brune     ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr);
44599e764e56SPeter Brune     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
44609e764e56SPeter Brune     ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
44619e764e56SPeter Brune   }
44629e764e56SPeter Brune   *linesearch = snes->linesearch;
44639e764e56SPeter Brune   PetscFunctionReturn(0);
44649e764e56SPeter Brune }
44659e764e56SPeter Brune 
446669b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4467c6db04a5SJed Brown #include <mex.h>
446869b4f73cSBarry Smith 
44698f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
44708f6e6473SBarry Smith 
44710807856dSBarry Smith #undef __FUNCT__
44720807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
44730807856dSBarry Smith /*
44740807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
44750807856dSBarry Smith                          SNESSetFunctionMatlab().
44760807856dSBarry Smith 
44770807856dSBarry Smith    Collective on SNES
44780807856dSBarry Smith 
44790807856dSBarry Smith    Input Parameters:
44800807856dSBarry Smith +  snes - the SNES context
44810807856dSBarry Smith -  x - input vector
44820807856dSBarry Smith 
44830807856dSBarry Smith    Output Parameter:
44840807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
44850807856dSBarry Smith 
44860807856dSBarry Smith    Notes:
44870807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
44880807856dSBarry Smith    implementations, so most users would not generally call this routine
44890807856dSBarry Smith    themselves.
44900807856dSBarry Smith 
44910807856dSBarry Smith    Level: developer
44920807856dSBarry Smith 
44930807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
44940807856dSBarry Smith 
44950807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
449661b2408cSBarry Smith */
44977087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
44980807856dSBarry Smith {
4499e650e774SBarry Smith   PetscErrorCode    ierr;
45008f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
45018f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
45028f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
450391621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
4504e650e774SBarry Smith 
45050807856dSBarry Smith   PetscFunctionBegin;
45060807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
45070807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
45080807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
45090807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
45100807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
45110807856dSBarry Smith 
45120807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
4513e650e774SBarry Smith 
451491621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4515e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4516e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
451791621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
451891621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
451991621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
45208f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
45218f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
4522b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
4523e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4524e650e774SBarry Smith   mxDestroyArray(prhs[0]);
4525e650e774SBarry Smith   mxDestroyArray(prhs[1]);
4526e650e774SBarry Smith   mxDestroyArray(prhs[2]);
45278f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
4528e650e774SBarry Smith   mxDestroyArray(plhs[0]);
45290807856dSBarry Smith   PetscFunctionReturn(0);
45300807856dSBarry Smith }
45310807856dSBarry Smith 
45320807856dSBarry Smith 
45330807856dSBarry Smith #undef __FUNCT__
45340807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
453561b2408cSBarry Smith /*
45360807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
45370807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4538e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
45390807856dSBarry Smith 
45400807856dSBarry Smith    Logically Collective on SNES
45410807856dSBarry Smith 
45420807856dSBarry Smith    Input Parameters:
45430807856dSBarry Smith +  snes - the SNES context
45440807856dSBarry Smith .  r - vector to store function value
45450807856dSBarry Smith -  func - function evaluation routine
45460807856dSBarry Smith 
45470807856dSBarry Smith    Calling sequence of func:
454861b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
45490807856dSBarry Smith 
45500807856dSBarry Smith 
45510807856dSBarry Smith    Notes:
45520807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
45530807856dSBarry Smith $      f'(x) x = -f(x),
45540807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
45550807856dSBarry Smith 
45560807856dSBarry Smith    Level: beginner
45570807856dSBarry Smith 
45580807856dSBarry Smith .keywords: SNES, nonlinear, set, function
45590807856dSBarry Smith 
45600807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
456161b2408cSBarry Smith */
45627087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
45630807856dSBarry Smith {
45640807856dSBarry Smith   PetscErrorCode    ierr;
45658f6e6473SBarry Smith   SNESMatlabContext *sctx;
45660807856dSBarry Smith 
45670807856dSBarry Smith   PetscFunctionBegin;
45688f6e6473SBarry Smith   /* currently sctx is memory bleed */
45698f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
45708f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
45718f6e6473SBarry Smith   /*
45728f6e6473SBarry Smith      This should work, but it doesn't
45738f6e6473SBarry Smith   sctx->ctx = ctx;
45748f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
45758f6e6473SBarry Smith   */
45768f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
45778f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
45780807856dSBarry Smith   PetscFunctionReturn(0);
45790807856dSBarry Smith }
458069b4f73cSBarry Smith 
458161b2408cSBarry Smith #undef __FUNCT__
458261b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
458361b2408cSBarry Smith /*
458461b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
458561b2408cSBarry Smith                          SNESSetJacobianMatlab().
458661b2408cSBarry Smith 
458761b2408cSBarry Smith    Collective on SNES
458861b2408cSBarry Smith 
458961b2408cSBarry Smith    Input Parameters:
459061b2408cSBarry Smith +  snes - the SNES context
459161b2408cSBarry Smith .  x - input vector
459261b2408cSBarry Smith .  A, B - the matrices
459361b2408cSBarry Smith -  ctx - user context
459461b2408cSBarry Smith 
459561b2408cSBarry Smith    Output Parameter:
459661b2408cSBarry Smith .  flag - structure of the matrix
459761b2408cSBarry Smith 
459861b2408cSBarry Smith    Level: developer
459961b2408cSBarry Smith 
460061b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
460161b2408cSBarry Smith 
460261b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
460361b2408cSBarry Smith @*/
46047087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
460561b2408cSBarry Smith {
460661b2408cSBarry Smith   PetscErrorCode    ierr;
460761b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
460861b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
460961b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
461061b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
461161b2408cSBarry Smith 
461261b2408cSBarry Smith   PetscFunctionBegin;
461361b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
461461b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
461561b2408cSBarry Smith 
461661b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
461761b2408cSBarry Smith 
461861b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
461961b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
462061b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
462161b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
462261b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
462361b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
462461b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
462561b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
462661b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
462761b2408cSBarry Smith   prhs[5] =  sctx->ctx;
4628b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
462961b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
463061b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
463161b2408cSBarry Smith   mxDestroyArray(prhs[0]);
463261b2408cSBarry Smith   mxDestroyArray(prhs[1]);
463361b2408cSBarry Smith   mxDestroyArray(prhs[2]);
463461b2408cSBarry Smith   mxDestroyArray(prhs[3]);
463561b2408cSBarry Smith   mxDestroyArray(prhs[4]);
463661b2408cSBarry Smith   mxDestroyArray(plhs[0]);
463761b2408cSBarry Smith   mxDestroyArray(plhs[1]);
463861b2408cSBarry Smith   PetscFunctionReturn(0);
463961b2408cSBarry Smith }
464061b2408cSBarry Smith 
464161b2408cSBarry Smith 
464261b2408cSBarry Smith #undef __FUNCT__
464361b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
464461b2408cSBarry Smith /*
464561b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
464661b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4647e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
464861b2408cSBarry Smith 
464961b2408cSBarry Smith    Logically Collective on SNES
465061b2408cSBarry Smith 
465161b2408cSBarry Smith    Input Parameters:
465261b2408cSBarry Smith +  snes - the SNES context
465361b2408cSBarry Smith .  A,B - Jacobian matrices
465461b2408cSBarry Smith .  func - function evaluation routine
465561b2408cSBarry Smith -  ctx - user context
465661b2408cSBarry Smith 
465761b2408cSBarry Smith    Calling sequence of func:
465861b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
465961b2408cSBarry Smith 
466061b2408cSBarry Smith 
466161b2408cSBarry Smith    Level: developer
466261b2408cSBarry Smith 
466361b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
466461b2408cSBarry Smith 
466561b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
466661b2408cSBarry Smith */
46677087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
466861b2408cSBarry Smith {
466961b2408cSBarry Smith   PetscErrorCode    ierr;
467061b2408cSBarry Smith   SNESMatlabContext *sctx;
467161b2408cSBarry Smith 
467261b2408cSBarry Smith   PetscFunctionBegin;
467361b2408cSBarry Smith   /* currently sctx is memory bleed */
467461b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
467561b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
467661b2408cSBarry Smith   /*
467761b2408cSBarry Smith      This should work, but it doesn't
467861b2408cSBarry Smith   sctx->ctx = ctx;
467961b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
468061b2408cSBarry Smith   */
468161b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
468261b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
468361b2408cSBarry Smith   PetscFunctionReturn(0);
468461b2408cSBarry Smith }
468569b4f73cSBarry Smith 
4686f9eb7ae2SShri Abhyankar #undef __FUNCT__
4687f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
4688f9eb7ae2SShri Abhyankar /*
4689f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
4690f9eb7ae2SShri Abhyankar 
4691f9eb7ae2SShri Abhyankar    Collective on SNES
4692f9eb7ae2SShri Abhyankar 
4693f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
4694f9eb7ae2SShri Abhyankar @*/
46957087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
4696f9eb7ae2SShri Abhyankar {
4697f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
469848f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
4699f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
4700f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
4701f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
4702f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
4703f9eb7ae2SShri Abhyankar 
4704f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4705f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4706f9eb7ae2SShri Abhyankar 
4707f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4708f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4709f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
4710f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
4711f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
4712f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
4713f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
4714f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
4715f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
4716f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4717f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
4718f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
4719f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
4720f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
4721f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
4722f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
4723f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4724f9eb7ae2SShri Abhyankar }
4725f9eb7ae2SShri Abhyankar 
4726f9eb7ae2SShri Abhyankar 
4727f9eb7ae2SShri Abhyankar #undef __FUNCT__
4728f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
4729f9eb7ae2SShri Abhyankar /*
4730e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
4731f9eb7ae2SShri Abhyankar 
4732f9eb7ae2SShri Abhyankar    Level: developer
4733f9eb7ae2SShri Abhyankar 
4734f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
4735f9eb7ae2SShri Abhyankar 
4736f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
4737f9eb7ae2SShri Abhyankar */
47387087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
4739f9eb7ae2SShri Abhyankar {
4740f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
4741f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
4742f9eb7ae2SShri Abhyankar 
4743f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4744f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
4745f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
4746f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4747f9eb7ae2SShri Abhyankar   /*
4748f9eb7ae2SShri Abhyankar      This should work, but it doesn't
4749f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
4750f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
4751f9eb7ae2SShri Abhyankar   */
4752f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
4753f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4754f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4755f9eb7ae2SShri Abhyankar }
4756f9eb7ae2SShri Abhyankar 
475769b4f73cSBarry Smith #endif
4758