xref: /petsc/src/snes/interface/snes.c (revision 534ebe21143b28d6375c549c032c2822f1bc913f)
19b94acceSBarry Smith 
2b45d2f2cSJed Brown #include <petsc-private/snesimpl.h>      /*I "petscsnes.h"  I*/
36cab3a1bSJed Brown #include <petscdmshell.h>          /*I "petscdmshell.h" I*/
49b94acceSBarry Smith 
5ace3abfcSBarry Smith PetscBool  SNESRegisterAllCalled = PETSC_FALSE;
68ba1e511SMatthew Knepley PetscFList SNESList              = PETSC_NULL;
78ba1e511SMatthew Knepley 
88ba1e511SMatthew Knepley /* Logging support */
97087cfbeSBarry Smith PetscClassId  SNES_CLASSID;
10f1c6b773SPeter Brune PetscLogEvent  SNES_Solve, SNES_FunctionEval, SNES_JacobianEval, SNES_GSEval;
11a09944afSBarry Smith 
12a09944afSBarry Smith #undef __FUNCT__
13cab2e9ccSBarry Smith #define __FUNCT__ "SNESDMComputeJacobian"
14cab2e9ccSBarry Smith /*
15cab2e9ccSBarry Smith     Translates from a SNES call to a DM call in computing a Jacobian
16caa4e7f2SJed Brown 
17caa4e7f2SJed Brown     This is a legacy calling sequence, should transition to dispatching through the SNESDM.
18cab2e9ccSBarry Smith */
19cab2e9ccSBarry Smith PetscErrorCode SNESDMComputeJacobian(SNES snes,Vec X,Mat *J,Mat *B,MatStructure *flag,void *ptr)
20cab2e9ccSBarry Smith {
21cab2e9ccSBarry Smith   PetscErrorCode ierr;
22cab2e9ccSBarry Smith   DM             dm;
23cab2e9ccSBarry Smith 
24cab2e9ccSBarry Smith   PetscFunctionBegin;
25cab2e9ccSBarry Smith   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
26cab2e9ccSBarry Smith   ierr = DMComputeJacobian(dm,X,*J,*B,flag);CHKERRQ(ierr);
27cab2e9ccSBarry Smith   PetscFunctionReturn(0);
28cab2e9ccSBarry Smith }
29cab2e9ccSBarry Smith 
30cab2e9ccSBarry Smith #undef __FUNCT__
31e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged"
32e113a28aSBarry Smith /*@
33e113a28aSBarry Smith    SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged.
34e113a28aSBarry Smith 
353f9fe445SBarry Smith    Logically Collective on SNES
36e113a28aSBarry Smith 
37e113a28aSBarry Smith    Input Parameters:
38e113a28aSBarry Smith +  snes - iterative context obtained from SNESCreate()
39e113a28aSBarry Smith -  flg - PETSC_TRUE indicates you want the error generated
40e113a28aSBarry Smith 
41e113a28aSBarry Smith    Options database keys:
42e113a28aSBarry Smith .  -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false)
43e113a28aSBarry Smith 
44e113a28aSBarry Smith    Level: intermediate
45e113a28aSBarry Smith 
46e113a28aSBarry Smith    Notes:
47e113a28aSBarry Smith     Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve()
48e113a28aSBarry Smith     to determine if it has converged.
49e113a28aSBarry Smith 
50e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
51e113a28aSBarry Smith 
52e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
53e113a28aSBarry Smith @*/
547087cfbeSBarry Smith PetscErrorCode  SNESSetErrorIfNotConverged(SNES snes,PetscBool  flg)
55e113a28aSBarry Smith {
56e113a28aSBarry Smith   PetscFunctionBegin;
57e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
58acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flg,2);
59e113a28aSBarry Smith   snes->errorifnotconverged = flg;
60dd568438SSatish Balay 
61e113a28aSBarry Smith   PetscFunctionReturn(0);
62e113a28aSBarry Smith }
63e113a28aSBarry Smith 
64e113a28aSBarry Smith #undef __FUNCT__
65e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged"
66e113a28aSBarry Smith /*@
67e113a28aSBarry Smith    SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge?
68e113a28aSBarry Smith 
69e113a28aSBarry Smith    Not Collective
70e113a28aSBarry Smith 
71e113a28aSBarry Smith    Input Parameter:
72e113a28aSBarry Smith .  snes - iterative context obtained from SNESCreate()
73e113a28aSBarry Smith 
74e113a28aSBarry Smith    Output Parameter:
75e113a28aSBarry Smith .  flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE
76e113a28aSBarry Smith 
77e113a28aSBarry Smith    Level: intermediate
78e113a28aSBarry Smith 
79e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
80e113a28aSBarry Smith 
81e113a28aSBarry Smith .seealso:  SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
82e113a28aSBarry Smith @*/
837087cfbeSBarry Smith PetscErrorCode  SNESGetErrorIfNotConverged(SNES snes,PetscBool  *flag)
84e113a28aSBarry Smith {
85e113a28aSBarry Smith   PetscFunctionBegin;
86e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
87e113a28aSBarry Smith   PetscValidPointer(flag,2);
88e113a28aSBarry Smith   *flag = snes->errorifnotconverged;
89e113a28aSBarry Smith   PetscFunctionReturn(0);
90e113a28aSBarry Smith }
91e113a28aSBarry Smith 
92e113a28aSBarry Smith #undef __FUNCT__
934936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError"
94e725d27bSBarry Smith /*@
954936397dSBarry Smith    SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not
964936397dSBarry Smith      in the functions domain. For example, negative pressure.
974936397dSBarry Smith 
983f9fe445SBarry Smith    Logically Collective on SNES
994936397dSBarry Smith 
1004936397dSBarry Smith    Input Parameters:
1016a388c36SPeter Brune .  snes - the SNES context
1024936397dSBarry Smith 
10328529972SSatish Balay    Level: advanced
1044936397dSBarry Smith 
1054936397dSBarry Smith .keywords: SNES, view
1064936397dSBarry Smith 
1074936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction()
1084936397dSBarry Smith @*/
1097087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionDomainError(SNES snes)
1104936397dSBarry Smith {
1114936397dSBarry Smith   PetscFunctionBegin;
1120700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1134936397dSBarry Smith   snes->domainerror = PETSC_TRUE;
1144936397dSBarry Smith   PetscFunctionReturn(0);
1154936397dSBarry Smith }
1164936397dSBarry Smith 
1176a388c36SPeter Brune 
1186a388c36SPeter Brune #undef __FUNCT__
1196a388c36SPeter Brune #define __FUNCT__ "SNESGetFunctionDomainError"
1206a388c36SPeter Brune /*@
121c77b2880SPeter Brune    SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction;
1226a388c36SPeter Brune 
1236a388c36SPeter Brune    Logically Collective on SNES
1246a388c36SPeter Brune 
1256a388c36SPeter Brune    Input Parameters:
1266a388c36SPeter Brune .  snes - the SNES context
1276a388c36SPeter Brune 
1286a388c36SPeter Brune    Output Parameters:
1296a388c36SPeter Brune .  domainerror Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise.
1306a388c36SPeter Brune 
1316a388c36SPeter Brune    Level: advanced
1326a388c36SPeter Brune 
1336a388c36SPeter Brune .keywords: SNES, view
1346a388c36SPeter Brune 
1356a388c36SPeter Brune .seealso: SNESSetFunctionDomainError, SNESComputeFunction()
1366a388c36SPeter Brune @*/
1376a388c36SPeter Brune PetscErrorCode  SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror)
1386a388c36SPeter Brune {
1396a388c36SPeter Brune   PetscFunctionBegin;
1406a388c36SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1416a388c36SPeter Brune   PetscValidPointer(domainerror, 2);
1426a388c36SPeter Brune   *domainerror = snes->domainerror;
1436a388c36SPeter Brune   PetscFunctionReturn(0);
1446a388c36SPeter Brune }
1456a388c36SPeter Brune 
1466a388c36SPeter Brune 
1474936397dSBarry Smith #undef __FUNCT__
1484a2ae208SSatish Balay #define __FUNCT__ "SNESView"
1497e2c5f70SBarry Smith /*@C
1509b94acceSBarry Smith    SNESView - Prints the SNES data structure.
1519b94acceSBarry Smith 
1524c49b128SBarry Smith    Collective on SNES
153fee21e36SBarry Smith 
154c7afd0dbSLois Curfman McInnes    Input Parameters:
155c7afd0dbSLois Curfman McInnes +  SNES - the SNES context
156c7afd0dbSLois Curfman McInnes -  viewer - visualization context
157c7afd0dbSLois Curfman McInnes 
1589b94acceSBarry Smith    Options Database Key:
159c8a8ba5cSLois Curfman McInnes .  -snes_view - Calls SNESView() at end of SNESSolve()
1609b94acceSBarry Smith 
1619b94acceSBarry Smith    Notes:
1629b94acceSBarry Smith    The available visualization contexts include
163b0a32e0cSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
164b0a32e0cSBarry Smith -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
165c8a8ba5cSLois Curfman McInnes          output where only the first processor opens
166c8a8ba5cSLois Curfman McInnes          the file.  All other processors send their
167c8a8ba5cSLois Curfman McInnes          data to the first processor to print.
1689b94acceSBarry Smith 
1693e081fefSLois Curfman McInnes    The user can open an alternative visualization context with
170b0a32e0cSBarry Smith    PetscViewerASCIIOpen() - output to a specified file.
1719b94acceSBarry Smith 
17236851e7fSLois Curfman McInnes    Level: beginner
17336851e7fSLois Curfman McInnes 
1749b94acceSBarry Smith .keywords: SNES, view
1759b94acceSBarry Smith 
176b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen()
1779b94acceSBarry Smith @*/
1787087cfbeSBarry Smith PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
1799b94acceSBarry Smith {
180fa9f3622SBarry Smith   SNESKSPEW           *kctx;
181dfbe8321SBarry Smith   PetscErrorCode      ierr;
18294b7f48cSBarry Smith   KSP                 ksp;
1837f1410a3SPeter Brune   SNESLineSearch      linesearch;
184ace3abfcSBarry Smith   PetscBool           iascii,isstring;
1859b94acceSBarry Smith 
1863a40ed3dSBarry Smith   PetscFunctionBegin;
1870700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1883050cee2SBarry Smith   if (!viewer) {
1897adad957SLisandro Dalcin     ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
1903050cee2SBarry Smith   }
1910700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
192c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,viewer,2);
19374679c65SBarry Smith 
1942692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1952692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
19632077d6dSBarry Smith   if (iascii) {
197317d6ea6SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr);
198e7788613SBarry Smith     if (snes->ops->view) {
199b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
200e7788613SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
201b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2020ef38995SBarry Smith     }
20377431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr);
204a83599f4SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%G, absolute=%G, solution=%G\n",
205c60f73f4SPeter Brune                  snes->rtol,snes->abstol,snes->stol);CHKERRQ(ierr);
20677431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr);
20777431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr);
2089b94acceSBarry Smith     if (snes->ksp_ewconv) {
209fa9f3622SBarry Smith       kctx = (SNESKSPEW *)snes->kspconvctx;
2109b94acceSBarry Smith       if (kctx) {
21177431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr);
212a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr);
213a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr);
2149b94acceSBarry Smith       }
2159b94acceSBarry Smith     }
216eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
217eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");CHKERRQ(ierr);
218eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
219eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr);
220eb1f6c34SBarry Smith     }
221eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
222eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");CHKERRQ(ierr);
223eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
22442f4f86dSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr);
225eb1f6c34SBarry Smith     }
2260f5bd95cSBarry Smith   } else if (isstring) {
227317d6ea6SBarry Smith     const char *type;
228454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
229b0a32e0cSBarry Smith     ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr);
23019bcc07fSBarry Smith   }
23142f4f86dSBarry Smith   if (snes->pc && snes->usespc) {
2324a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2334a0c5b0cSMatthew G Knepley     ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr);
2344a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2354a0c5b0cSMatthew G Knepley   }
2362c155ee1SBarry Smith   if (snes->usesksp) {
2372c155ee1SBarry Smith     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
238b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
23994b7f48cSBarry Smith     ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
240b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2412c155ee1SBarry Smith   }
2427f1410a3SPeter Brune   if (snes->linesearch) {
2437f1410a3SPeter Brune     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2447f1410a3SPeter Brune     ierr = SNESGetSNESLineSearch(snes, &linesearch);CHKERRQ(ierr);
2457f1410a3SPeter Brune     ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr);
2467f1410a3SPeter Brune     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2477f1410a3SPeter Brune   }
2483a40ed3dSBarry Smith   PetscFunctionReturn(0);
2499b94acceSBarry Smith }
2509b94acceSBarry Smith 
25176b2cf59SMatthew Knepley /*
25276b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
25376b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
25476b2cf59SMatthew Knepley */
25576b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
256a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
2576849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
25876b2cf59SMatthew Knepley 
259e74ef692SMatthew Knepley #undef __FUNCT__
260e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker"
261ac226902SBarry Smith /*@C
26276b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
26376b2cf59SMatthew Knepley 
26476b2cf59SMatthew Knepley   Not Collective
26576b2cf59SMatthew Knepley 
26676b2cf59SMatthew Knepley   Input Parameter:
26776b2cf59SMatthew Knepley . snescheck - function that checks for options
26876b2cf59SMatthew Knepley 
26976b2cf59SMatthew Knepley   Level: developer
27076b2cf59SMatthew Knepley 
27176b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
27276b2cf59SMatthew Knepley @*/
2737087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
27476b2cf59SMatthew Knepley {
27576b2cf59SMatthew Knepley   PetscFunctionBegin;
27676b2cf59SMatthew Knepley   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
277e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
27876b2cf59SMatthew Knepley   }
27976b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
28076b2cf59SMatthew Knepley   PetscFunctionReturn(0);
28176b2cf59SMatthew Knepley }
28276b2cf59SMatthew Knepley 
2837087cfbeSBarry Smith extern PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
284aa3661deSLisandro Dalcin 
285aa3661deSLisandro Dalcin #undef __FUNCT__
286aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private"
287ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool  hasOperator, PetscInt version)
288aa3661deSLisandro Dalcin {
289aa3661deSLisandro Dalcin   Mat            J;
290aa3661deSLisandro Dalcin   KSP            ksp;
291aa3661deSLisandro Dalcin   PC             pc;
292ace3abfcSBarry Smith   PetscBool      match;
293aa3661deSLisandro Dalcin   PetscErrorCode ierr;
294aa3661deSLisandro Dalcin 
295aa3661deSLisandro Dalcin   PetscFunctionBegin;
2960700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
297aa3661deSLisandro Dalcin 
29898613b67SLisandro Dalcin   if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
29998613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
30098613b67SLisandro Dalcin     ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr);
30198613b67SLisandro Dalcin   }
30298613b67SLisandro Dalcin 
303aa3661deSLisandro Dalcin   if (version == 1) {
304aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
30598613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
3069c6ac3b3SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
307aa3661deSLisandro Dalcin   } else if (version == 2) {
308e32f2f54SBarry Smith     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
30982a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
310aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
311aa3661deSLisandro Dalcin #else
312e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
313aa3661deSLisandro Dalcin #endif
314a8248277SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
315aa3661deSLisandro Dalcin 
316aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
317d3462f78SMatthew Knepley   if (hasOperator) {
318aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
319aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
320aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
321aa3661deSLisandro Dalcin   } else {
322aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
323aa3661deSLisandro Dalcin        provided preconditioner matrix with the default matrix free version. */
3246cab3a1bSJed Brown     void *functx;
3256cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
3266cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
327aa3661deSLisandro Dalcin     /* Force no preconditioner */
328aa3661deSLisandro Dalcin     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
329aa3661deSLisandro Dalcin     ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
330aa3661deSLisandro Dalcin     ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
331aa3661deSLisandro Dalcin     if (!match) {
332aa3661deSLisandro Dalcin       ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
333aa3661deSLisandro Dalcin       ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
334aa3661deSLisandro Dalcin     }
335aa3661deSLisandro Dalcin   }
3366bf464f9SBarry Smith   ierr = MatDestroy(&J);CHKERRQ(ierr);
337aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
338aa3661deSLisandro Dalcin }
339aa3661deSLisandro Dalcin 
3404a2ae208SSatish Balay #undef __FUNCT__
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"
364caa4e7f2SJed Brown static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,MatStructure *mstruct,void *ctx)
365caa4e7f2SJed Brown {
366caa4e7f2SJed Brown   SNES snes = (SNES)ctx;
367caa4e7f2SJed Brown   PetscErrorCode ierr;
368caa4e7f2SJed Brown   Mat Asave = A,Bsave = B;
369dfe15315SJed Brown   Vec X,Xnamed = PETSC_NULL;
370dfe15315SJed Brown   DM dmsave;
371caa4e7f2SJed Brown 
372caa4e7f2SJed Brown   PetscFunctionBegin;
373dfe15315SJed Brown   dmsave = snes->dm;
374dfe15315SJed Brown   ierr = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr);
375dfe15315SJed Brown   if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */
376dfe15315SJed Brown   else {                                     /* We are on a coarser level, this vec was initialized using a DM restrict hook */
377dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
378dfe15315SJed Brown     X = Xnamed;
379dfe15315SJed Brown   }
380dfe15315SJed Brown   ierr = SNESComputeJacobian(snes,X,&A,&B,mstruct);CHKERRQ(ierr);
381caa4e7f2SJed Brown   if (A != Asave || B != Bsave) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_SUP,"No support for changing matrices at this time");
382dfe15315SJed Brown   if (Xnamed) {
383dfe15315SJed Brown     ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
384dfe15315SJed Brown   }
385dfe15315SJed Brown   snes->dm = dmsave;
386caa4e7f2SJed Brown   PetscFunctionReturn(0);
387caa4e7f2SJed Brown }
388caa4e7f2SJed Brown 
389caa4e7f2SJed Brown #undef __FUNCT__
3906cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices"
3916cab3a1bSJed Brown /*@
3926cab3a1bSJed Brown    SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX()
3936cab3a1bSJed Brown 
3946cab3a1bSJed Brown    Collective
3956cab3a1bSJed Brown 
3966cab3a1bSJed Brown    Input Arguments:
3976cab3a1bSJed Brown .  snes - snes to configure
3986cab3a1bSJed Brown 
3996cab3a1bSJed Brown    Level: developer
4006cab3a1bSJed Brown 
4016cab3a1bSJed Brown .seealso: SNESSetUp()
4026cab3a1bSJed Brown @*/
4036cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes)
4046cab3a1bSJed Brown {
4056cab3a1bSJed Brown   PetscErrorCode ierr;
4066cab3a1bSJed Brown   DM             dm;
4076cab3a1bSJed Brown   SNESDM         sdm;
4086cab3a1bSJed Brown 
4096cab3a1bSJed Brown   PetscFunctionBegin;
4106cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4116cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
412caa4e7f2SJed Brown   if (!sdm->computejacobian) {
4136cab3a1bSJed Brown     Mat J,B;
4146cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4156cab3a1bSJed Brown     if (snes->mf_operator) {
4166cab3a1bSJed Brown       ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4176cab3a1bSJed Brown       ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4186cab3a1bSJed Brown       ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4196cab3a1bSJed Brown     } else {
4206cab3a1bSJed Brown       J = B;
4216cab3a1bSJed Brown       ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
4226cab3a1bSJed Brown     }
4236cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr);
4246cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
4256cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
4266cab3a1bSJed Brown   } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) {
4276cab3a1bSJed Brown     Mat J;
4286cab3a1bSJed Brown     void *functx;
4296cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4306cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4316cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4326cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
4336cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
4346cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
435caa4e7f2SJed Brown   } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
4366cab3a1bSJed Brown     Mat J,B;
4376cab3a1bSJed Brown     void *functx;
4386cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4396cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4406cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4416cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4426cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
4436cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,functx);CHKERRQ(ierr);
4446cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
4456cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
446caa4e7f2SJed Brown   } else if (!snes->jacobian_pre) {
4476cab3a1bSJed Brown     Mat J,B;
4486cab3a1bSJed Brown     J = snes->jacobian;
4496cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4506cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
4516cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
4526cab3a1bSJed Brown   }
453caa4e7f2SJed Brown   {
454caa4e7f2SJed Brown     PetscBool flg = PETSC_FALSE;
455caa4e7f2SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_kspcompute",&flg,PETSC_NULL);CHKERRQ(ierr);
456caa4e7f2SJed Brown     if (flg) {                  /* Plan to transition to this model */
457caa4e7f2SJed Brown       KSP ksp;
458caa4e7f2SJed Brown       ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
459caa4e7f2SJed Brown       ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr);
460dfe15315SJed Brown       ierr = DMCoarsenHookAdd(snes->dm,PETSC_NULL,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr);
461caa4e7f2SJed Brown     }
462caa4e7f2SJed Brown   }
4636cab3a1bSJed Brown   PetscFunctionReturn(0);
4646cab3a1bSJed Brown }
4656cab3a1bSJed Brown 
4666cab3a1bSJed Brown #undef __FUNCT__
4674a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions"
4689b94acceSBarry Smith /*@
46994b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
4709b94acceSBarry Smith 
471c7afd0dbSLois Curfman McInnes    Collective on SNES
472c7afd0dbSLois Curfman McInnes 
4739b94acceSBarry Smith    Input Parameter:
4749b94acceSBarry Smith .  snes - the SNES context
4759b94acceSBarry Smith 
47636851e7fSLois Curfman McInnes    Options Database Keys:
477ea630c6eSPeter Brune +  -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas
47882738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
47982738288SBarry Smith                 of the change in the solution between steps
48070441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
481b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
482b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
483b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
4844839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
485ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
486a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
487e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
488b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
4892492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
49082738288SBarry Smith                                solver; hence iterations will continue until max_it
4911fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
49282738288SBarry Smith                                of convergence test
493e8105e01SRichard Katz .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
494e8105e01SRichard Katz                                        filename given prints to stdout
495a6570f20SBarry Smith .  -snes_monitor_solution - plots solution at each iteration
496a6570f20SBarry Smith .  -snes_monitor_residual - plots residual (not its norm) at each iteration
497a6570f20SBarry Smith .  -snes_monitor_solution_update - plots update to solution at each iteration
498a6570f20SBarry Smith .  -snes_monitor_draw - plots residual norm at each iteration
499e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
5005968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
501fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
50282738288SBarry Smith 
50382738288SBarry Smith     Options Database for Eisenstat-Walker method:
504fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
5054b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
50636851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
50736851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
50836851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
50936851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
51036851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
51136851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
51282738288SBarry Smith 
51311ca99fdSLois Curfman McInnes    Notes:
51411ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
5150598bfebSBarry Smith    the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>.
51683e2fdc7SBarry Smith 
51736851e7fSLois Curfman McInnes    Level: beginner
51836851e7fSLois Curfman McInnes 
5199b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
5209b94acceSBarry Smith 
52169ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
5229b94acceSBarry Smith @*/
5237087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
5249b94acceSBarry Smith {
525872b6db9SPeter Brune   PetscBool               flg,mf,mf_operator,pcset;
526efd51863SBarry Smith   PetscInt                i,indx,lag,mf_version,grids;
527aa3661deSLisandro Dalcin   MatStructure            matflag;
52885385478SLisandro Dalcin   const char              *deft = SNESLS;
52985385478SLisandro Dalcin   const char              *convtests[] = {"default","skip"};
53085385478SLisandro Dalcin   SNESKSPEW               *kctx = NULL;
531e8105e01SRichard Katz   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
53251e86f29SPeter Brune   const char              *optionsprefix;
533649052a6SBarry Smith   PetscViewer             monviewer;
53485385478SLisandro Dalcin   PetscErrorCode          ierr;
5359b94acceSBarry Smith 
5363a40ed3dSBarry Smith   PetscFunctionBegin;
5370700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
538ca161407SBarry Smith 
539186905e3SBarry Smith   if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
5403194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
5417adad957SLisandro Dalcin     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
542b0a32e0cSBarry Smith     ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
543d64ed03dSBarry Smith     if (flg) {
544186905e3SBarry Smith       ierr = SNESSetType(snes,type);CHKERRQ(ierr);
5457adad957SLisandro Dalcin     } else if (!((PetscObject)snes)->type_name) {
546186905e3SBarry Smith       ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
547d64ed03dSBarry Smith     }
54890d69ab7SBarry Smith     /* not used here, but called so will go into help messaage */
549909c8a9fSBarry Smith     ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr);
55093c39befSBarry Smith 
551c60f73f4SPeter Brune     ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);CHKERRQ(ierr);
55257034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr);
553186905e3SBarry Smith 
55457034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr);
555b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr);
556b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr);
55750ffb88aSMatthew Knepley     ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr);
558ddf469c8SBarry Smith     ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr);
559acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr);
56085385478SLisandro Dalcin 
561a8054027SBarry Smith     ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
562a8054027SBarry Smith     if (flg) {
563a8054027SBarry Smith       ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
564a8054027SBarry Smith     }
565e35cf81dSBarry Smith     ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
566e35cf81dSBarry Smith     if (flg) {
567e35cf81dSBarry Smith       ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
568e35cf81dSBarry Smith     }
569efd51863SBarry Smith     ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
570efd51863SBarry Smith     if (flg) {
571efd51863SBarry Smith       ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
572efd51863SBarry Smith     }
573a8054027SBarry Smith 
57485385478SLisandro Dalcin     ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
57585385478SLisandro Dalcin     if (flg) {
57685385478SLisandro Dalcin       switch (indx) {
5777f7931b9SBarry Smith       case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break;
5787f7931b9SBarry Smith       case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);    break;
57985385478SLisandro Dalcin       }
58085385478SLisandro Dalcin     }
58185385478SLisandro Dalcin 
582acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr);
583186905e3SBarry Smith 
58485385478SLisandro Dalcin     kctx = (SNESKSPEW *)snes->kspconvctx;
58585385478SLisandro Dalcin 
586acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr);
587186905e3SBarry Smith 
588fa9f3622SBarry Smith     ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr);
589fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr);
590fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr);
591fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr);
592fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr);
593fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr);
594fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr);
595186905e3SBarry Smith 
59690d69ab7SBarry Smith     flg  = PETSC_FALSE;
597acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
598a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
599eabae89aSBarry Smith 
600a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
601e8105e01SRichard Katz     if (flg) {
602649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
603649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
604e8105e01SRichard Katz     }
605eabae89aSBarry Smith 
606b271bb04SBarry Smith     ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
607b271bb04SBarry Smith     if (flg) {
608b271bb04SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr);
609b271bb04SBarry Smith     }
610b271bb04SBarry Smith 
611a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
612eabae89aSBarry Smith     if (flg) {
613649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
614f1bef1bcSMatthew Knepley       ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr);
615e8105e01SRichard Katz     }
616eabae89aSBarry Smith 
617a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
618eabae89aSBarry Smith     if (flg) {
619649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
620649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
621eabae89aSBarry Smith     }
622eabae89aSBarry Smith 
6235180491cSLisandro Dalcin     ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
6245180491cSLisandro Dalcin     if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);}
6255180491cSLisandro Dalcin 
62690d69ab7SBarry Smith     flg  = PETSC_FALSE;
627acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
628a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
62990d69ab7SBarry Smith     flg  = PETSC_FALSE;
630acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
631a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
63290d69ab7SBarry Smith     flg  = PETSC_FALSE;
633acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
634a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
63590d69ab7SBarry Smith     flg  = PETSC_FALSE;
636acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
637a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
63890d69ab7SBarry Smith     flg  = PETSC_FALSE;
639acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
640b271bb04SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
641e24b481bSBarry Smith 
64290d69ab7SBarry Smith     flg  = PETSC_FALSE;
643acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
6444b27c08aSLois Curfman McInnes     if (flg) {
6456cab3a1bSJed Brown       void *functx;
6466cab3a1bSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
6476cab3a1bSJed Brown       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr);
648ae15b995SBarry Smith       ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
6499b94acceSBarry Smith     }
650639f9d9dSBarry Smith 
651aa3661deSLisandro Dalcin     mf = mf_operator = PETSC_FALSE;
652aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
653acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr);
654a8248277SBarry Smith     if (flg && mf_operator) {
655a8248277SBarry Smith       snes->mf_operator = PETSC_TRUE;
656a8248277SBarry Smith       mf = PETSC_TRUE;
657a8248277SBarry Smith     }
658aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
659acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr);
660aa3661deSLisandro Dalcin     if (!flg && mf_operator) mf = PETSC_TRUE;
661aa3661deSLisandro Dalcin     mf_version = 1;
662aa3661deSLisandro Dalcin     ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr);
663aa3661deSLisandro Dalcin 
664d28543b3SPeter Brune 
66589b92e6fSPeter Brune     /* GS Options */
66689b92e6fSPeter Brune     ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr);
66789b92e6fSPeter Brune 
66876b2cf59SMatthew Knepley     for(i = 0; i < numberofsetfromoptions; i++) {
66976b2cf59SMatthew Knepley       ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
67076b2cf59SMatthew Knepley     }
67176b2cf59SMatthew Knepley 
672e7788613SBarry Smith     if (snes->ops->setfromoptions) {
673e7788613SBarry Smith       ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr);
674639f9d9dSBarry Smith     }
6755d973c19SBarry Smith 
6765d973c19SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
6775d973c19SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr);
678b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
6794bbc92c1SBarry Smith 
680aa3661deSLisandro Dalcin   if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); }
6811cee3971SBarry Smith 
6821cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
683aa3661deSLisandro Dalcin   ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
684aa3661deSLisandro Dalcin   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr);
68585385478SLisandro Dalcin   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
68693993e2dSLois Curfman McInnes 
6879e764e56SPeter Brune   if (!snes->linesearch) {
688f1c6b773SPeter Brune     ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
6899e764e56SPeter Brune   }
690f1c6b773SPeter Brune   ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr);
6919e764e56SPeter Brune 
69251e86f29SPeter Brune   /* if someone has set the SNES PC type, create it. */
69351e86f29SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
69451e86f29SPeter Brune   ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr);
69551e86f29SPeter Brune   if (pcset && (!snes->pc)) {
69651e86f29SPeter Brune     ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr);
69751e86f29SPeter Brune   }
6984a0c5b0cSMatthew G Knepley   if (snes->pc) {
699fde0ff24SPeter Brune     ierr = SNESSetOptionsPrefix(snes->pc, optionsprefix);CHKERRQ(ierr);
700fde0ff24SPeter Brune     ierr = SNESAppendOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr);
7014a0c5b0cSMatthew G Knepley     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
70288976e71SPeter Brune     /* default to 1 iteration */
70388976e71SPeter Brune     ierr = SNESSetTolerances(snes->pc, snes->pc->abstol, snes->pc->rtol, snes->pc->stol, 1, snes->pc->max_funcs);CHKERRQ(ierr);
704*534ebe21SPeter Brune     ierr = SNESSetNormType(snes->pc, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr);
7054a0c5b0cSMatthew G Knepley     ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr);
7064a0c5b0cSMatthew G Knepley   }
7073a40ed3dSBarry Smith   PetscFunctionReturn(0);
7089b94acceSBarry Smith }
7099b94acceSBarry Smith 
710d25893d9SBarry Smith #undef __FUNCT__
711d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext"
712d25893d9SBarry Smith /*@
713d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
714d25893d9SBarry Smith    the nonlinear solvers.
715d25893d9SBarry Smith 
716d25893d9SBarry Smith    Logically Collective on SNES
717d25893d9SBarry Smith 
718d25893d9SBarry Smith    Input Parameters:
719d25893d9SBarry Smith +  snes - the SNES context
720d25893d9SBarry Smith .  compute - function to compute the context
721d25893d9SBarry Smith -  destroy - function to destroy the context
722d25893d9SBarry Smith 
723d25893d9SBarry Smith    Level: intermediate
724d25893d9SBarry Smith 
725d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
726d25893d9SBarry Smith 
727d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
728d25893d9SBarry Smith @*/
729d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
730d25893d9SBarry Smith {
731d25893d9SBarry Smith   PetscFunctionBegin;
732d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
733d25893d9SBarry Smith   snes->ops->usercompute = compute;
734d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
735d25893d9SBarry Smith   PetscFunctionReturn(0);
736d25893d9SBarry Smith }
737a847f771SSatish Balay 
7384a2ae208SSatish Balay #undef __FUNCT__
7394a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
740b07ff414SBarry Smith /*@
7419b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
7429b94acceSBarry Smith    the nonlinear solvers.
7439b94acceSBarry Smith 
7443f9fe445SBarry Smith    Logically Collective on SNES
745fee21e36SBarry Smith 
746c7afd0dbSLois Curfman McInnes    Input Parameters:
747c7afd0dbSLois Curfman McInnes +  snes - the SNES context
748c7afd0dbSLois Curfman McInnes -  usrP - optional user context
749c7afd0dbSLois Curfman McInnes 
75036851e7fSLois Curfman McInnes    Level: intermediate
75136851e7fSLois Curfman McInnes 
7529b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
7539b94acceSBarry Smith 
754d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext()
7559b94acceSBarry Smith @*/
7567087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
7579b94acceSBarry Smith {
7581b2093e4SBarry Smith   PetscErrorCode ierr;
759b07ff414SBarry Smith   KSP            ksp;
7601b2093e4SBarry Smith 
7613a40ed3dSBarry Smith   PetscFunctionBegin;
7620700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
763b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
764b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
7659b94acceSBarry Smith   snes->user = usrP;
7663a40ed3dSBarry Smith   PetscFunctionReturn(0);
7679b94acceSBarry Smith }
76874679c65SBarry Smith 
7694a2ae208SSatish Balay #undef __FUNCT__
7704a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
771b07ff414SBarry Smith /*@
7729b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
7739b94acceSBarry Smith    nonlinear solvers.
7749b94acceSBarry Smith 
775c7afd0dbSLois Curfman McInnes    Not Collective
776c7afd0dbSLois Curfman McInnes 
7779b94acceSBarry Smith    Input Parameter:
7789b94acceSBarry Smith .  snes - SNES context
7799b94acceSBarry Smith 
7809b94acceSBarry Smith    Output Parameter:
7819b94acceSBarry Smith .  usrP - user context
7829b94acceSBarry Smith 
78336851e7fSLois Curfman McInnes    Level: intermediate
78436851e7fSLois Curfman McInnes 
7859b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
7869b94acceSBarry Smith 
7879b94acceSBarry Smith .seealso: SNESSetApplicationContext()
7889b94acceSBarry Smith @*/
789e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
7909b94acceSBarry Smith {
7913a40ed3dSBarry Smith   PetscFunctionBegin;
7920700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
793e71120c6SJed Brown   *(void**)usrP = snes->user;
7943a40ed3dSBarry Smith   PetscFunctionReturn(0);
7959b94acceSBarry Smith }
79674679c65SBarry Smith 
7974a2ae208SSatish Balay #undef __FUNCT__
7984a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
7999b94acceSBarry Smith /*@
800c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
801c8228a4eSBarry Smith    at this time.
8029b94acceSBarry Smith 
803c7afd0dbSLois Curfman McInnes    Not Collective
804c7afd0dbSLois Curfman McInnes 
8059b94acceSBarry Smith    Input Parameter:
8069b94acceSBarry Smith .  snes - SNES context
8079b94acceSBarry Smith 
8089b94acceSBarry Smith    Output Parameter:
8099b94acceSBarry Smith .  iter - iteration number
8109b94acceSBarry Smith 
811c8228a4eSBarry Smith    Notes:
812c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
813c8228a4eSBarry Smith 
814c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
81508405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
81608405cd6SLois Curfman McInnes .vb
81708405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
81808405cd6SLois Curfman McInnes       if (!(it % 2)) {
81908405cd6SLois Curfman McInnes         [compute Jacobian here]
82008405cd6SLois Curfman McInnes       }
82108405cd6SLois Curfman McInnes .ve
822c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
82308405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
824c8228a4eSBarry Smith 
82536851e7fSLois Curfman McInnes    Level: intermediate
82636851e7fSLois Curfman McInnes 
8272b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
8282b668275SBarry Smith 
829b850b91aSLisandro Dalcin .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
8309b94acceSBarry Smith @*/
8317087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
8329b94acceSBarry Smith {
8333a40ed3dSBarry Smith   PetscFunctionBegin;
8340700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8354482741eSBarry Smith   PetscValidIntPointer(iter,2);
8369b94acceSBarry Smith   *iter = snes->iter;
8373a40ed3dSBarry Smith   PetscFunctionReturn(0);
8389b94acceSBarry Smith }
83974679c65SBarry Smith 
8404a2ae208SSatish Balay #undef __FUNCT__
841360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber"
842360c497dSPeter Brune /*@
843360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
844360c497dSPeter Brune 
845360c497dSPeter Brune    Not Collective
846360c497dSPeter Brune 
847360c497dSPeter Brune    Input Parameter:
848360c497dSPeter Brune .  snes - SNES context
849360c497dSPeter Brune .  iter - iteration number
850360c497dSPeter Brune 
851360c497dSPeter Brune    Level: developer
852360c497dSPeter Brune 
853360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number,
854360c497dSPeter Brune 
855360c497dSPeter Brune .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
856360c497dSPeter Brune @*/
857360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
858360c497dSPeter Brune {
859360c497dSPeter Brune   PetscErrorCode ierr;
860360c497dSPeter Brune 
861360c497dSPeter Brune   PetscFunctionBegin;
862360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
863360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
864360c497dSPeter Brune   snes->iter = iter;
865360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
866360c497dSPeter Brune   PetscFunctionReturn(0);
867360c497dSPeter Brune }
868360c497dSPeter Brune 
869360c497dSPeter Brune #undef __FUNCT__
8704a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm"
8719b94acceSBarry Smith /*@
8729b94acceSBarry Smith    SNESGetFunctionNorm - Gets the norm of the current function that was set
8739b94acceSBarry Smith    with SNESSSetFunction().
8749b94acceSBarry Smith 
875c7afd0dbSLois Curfman McInnes    Collective on SNES
876c7afd0dbSLois Curfman McInnes 
8779b94acceSBarry Smith    Input Parameter:
8789b94acceSBarry Smith .  snes - SNES context
8799b94acceSBarry Smith 
8809b94acceSBarry Smith    Output Parameter:
8819b94acceSBarry Smith .  fnorm - 2-norm of function
8829b94acceSBarry Smith 
88336851e7fSLois Curfman McInnes    Level: intermediate
88436851e7fSLois Curfman McInnes 
8859b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm
886a86d99e1SLois Curfman McInnes 
887b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
8889b94acceSBarry Smith @*/
8897087cfbeSBarry Smith PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
8909b94acceSBarry Smith {
8913a40ed3dSBarry Smith   PetscFunctionBegin;
8920700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8934482741eSBarry Smith   PetscValidScalarPointer(fnorm,2);
8949b94acceSBarry Smith   *fnorm = snes->norm;
8953a40ed3dSBarry Smith   PetscFunctionReturn(0);
8969b94acceSBarry Smith }
89774679c65SBarry Smith 
898360c497dSPeter Brune 
899360c497dSPeter Brune #undef __FUNCT__
900360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm"
901360c497dSPeter Brune /*@
902360c497dSPeter Brune    SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm().
903360c497dSPeter Brune 
904360c497dSPeter Brune    Collective on SNES
905360c497dSPeter Brune 
906360c497dSPeter Brune    Input Parameter:
907360c497dSPeter Brune .  snes - SNES context
908360c497dSPeter Brune .  fnorm - 2-norm of function
909360c497dSPeter Brune 
910360c497dSPeter Brune    Level: developer
911360c497dSPeter Brune 
912360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm
913360c497dSPeter Brune 
914360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm().
915360c497dSPeter Brune @*/
916360c497dSPeter Brune PetscErrorCode  SNESSetFunctionNorm(SNES snes,PetscReal fnorm)
917360c497dSPeter Brune {
918360c497dSPeter Brune 
919360c497dSPeter Brune   PetscErrorCode ierr;
920360c497dSPeter Brune 
921360c497dSPeter Brune   PetscFunctionBegin;
922360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
923360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
924360c497dSPeter Brune   snes->norm = fnorm;
925360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
926360c497dSPeter Brune   PetscFunctionReturn(0);
927360c497dSPeter Brune }
928360c497dSPeter Brune 
9294a2ae208SSatish Balay #undef __FUNCT__
930b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
9319b94acceSBarry Smith /*@
932b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
9339b94acceSBarry Smith    attempted by the nonlinear solver.
9349b94acceSBarry Smith 
935c7afd0dbSLois Curfman McInnes    Not Collective
936c7afd0dbSLois Curfman McInnes 
9379b94acceSBarry Smith    Input Parameter:
9389b94acceSBarry Smith .  snes - SNES context
9399b94acceSBarry Smith 
9409b94acceSBarry Smith    Output Parameter:
9419b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
9429b94acceSBarry Smith 
943c96a6f78SLois Curfman McInnes    Notes:
944c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
945c96a6f78SLois Curfman McInnes 
94636851e7fSLois Curfman McInnes    Level: intermediate
94736851e7fSLois Curfman McInnes 
9489b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
94958ebbce7SBarry Smith 
950e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
95158ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
9529b94acceSBarry Smith @*/
9537087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
9549b94acceSBarry Smith {
9553a40ed3dSBarry Smith   PetscFunctionBegin;
9560700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9574482741eSBarry Smith   PetscValidIntPointer(nfails,2);
95850ffb88aSMatthew Knepley   *nfails = snes->numFailures;
95950ffb88aSMatthew Knepley   PetscFunctionReturn(0);
96050ffb88aSMatthew Knepley }
96150ffb88aSMatthew Knepley 
96250ffb88aSMatthew Knepley #undef __FUNCT__
963b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
96450ffb88aSMatthew Knepley /*@
965b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
96650ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
96750ffb88aSMatthew Knepley 
96850ffb88aSMatthew Knepley    Not Collective
96950ffb88aSMatthew Knepley 
97050ffb88aSMatthew Knepley    Input Parameters:
97150ffb88aSMatthew Knepley +  snes     - SNES context
97250ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
97350ffb88aSMatthew Knepley 
97450ffb88aSMatthew Knepley    Level: intermediate
97550ffb88aSMatthew Knepley 
97650ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
97758ebbce7SBarry Smith 
978e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
97958ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
98050ffb88aSMatthew Knepley @*/
9817087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
98250ffb88aSMatthew Knepley {
98350ffb88aSMatthew Knepley   PetscFunctionBegin;
9840700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
98550ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
98650ffb88aSMatthew Knepley   PetscFunctionReturn(0);
98750ffb88aSMatthew Knepley }
98850ffb88aSMatthew Knepley 
98950ffb88aSMatthew Knepley #undef __FUNCT__
990b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
99150ffb88aSMatthew Knepley /*@
992b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
99350ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
99450ffb88aSMatthew Knepley 
99550ffb88aSMatthew Knepley    Not Collective
99650ffb88aSMatthew Knepley 
99750ffb88aSMatthew Knepley    Input Parameter:
99850ffb88aSMatthew Knepley .  snes     - SNES context
99950ffb88aSMatthew Knepley 
100050ffb88aSMatthew Knepley    Output Parameter:
100150ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
100250ffb88aSMatthew Knepley 
100350ffb88aSMatthew Knepley    Level: intermediate
100450ffb88aSMatthew Knepley 
100550ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
100658ebbce7SBarry Smith 
1007e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
100858ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
100958ebbce7SBarry Smith 
101050ffb88aSMatthew Knepley @*/
10117087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
101250ffb88aSMatthew Knepley {
101350ffb88aSMatthew Knepley   PetscFunctionBegin;
10140700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10154482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
101650ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
10173a40ed3dSBarry Smith   PetscFunctionReturn(0);
10189b94acceSBarry Smith }
1019a847f771SSatish Balay 
10204a2ae208SSatish Balay #undef __FUNCT__
10212541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
10222541af92SBarry Smith /*@
10232541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
10242541af92SBarry Smith      done by SNES.
10252541af92SBarry Smith 
10262541af92SBarry Smith    Not Collective
10272541af92SBarry Smith 
10282541af92SBarry Smith    Input Parameter:
10292541af92SBarry Smith .  snes     - SNES context
10302541af92SBarry Smith 
10312541af92SBarry Smith    Output Parameter:
10322541af92SBarry Smith .  nfuncs - number of evaluations
10332541af92SBarry Smith 
10342541af92SBarry Smith    Level: intermediate
10352541af92SBarry Smith 
10362541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
103758ebbce7SBarry Smith 
1038e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
10392541af92SBarry Smith @*/
10407087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
10412541af92SBarry Smith {
10422541af92SBarry Smith   PetscFunctionBegin;
10430700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10442541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
10452541af92SBarry Smith   *nfuncs = snes->nfuncs;
10462541af92SBarry Smith   PetscFunctionReturn(0);
10472541af92SBarry Smith }
10482541af92SBarry Smith 
10492541af92SBarry Smith #undef __FUNCT__
10503d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
10513d4c4710SBarry Smith /*@
10523d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
10533d4c4710SBarry Smith    linear solvers.
10543d4c4710SBarry Smith 
10553d4c4710SBarry Smith    Not Collective
10563d4c4710SBarry Smith 
10573d4c4710SBarry Smith    Input Parameter:
10583d4c4710SBarry Smith .  snes - SNES context
10593d4c4710SBarry Smith 
10603d4c4710SBarry Smith    Output Parameter:
10613d4c4710SBarry Smith .  nfails - number of failed solves
10623d4c4710SBarry Smith 
10633d4c4710SBarry Smith    Notes:
10643d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
10653d4c4710SBarry Smith 
10663d4c4710SBarry Smith    Level: intermediate
10673d4c4710SBarry Smith 
10683d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
106958ebbce7SBarry Smith 
1070e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
10713d4c4710SBarry Smith @*/
10727087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
10733d4c4710SBarry Smith {
10743d4c4710SBarry Smith   PetscFunctionBegin;
10750700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10763d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
10773d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
10783d4c4710SBarry Smith   PetscFunctionReturn(0);
10793d4c4710SBarry Smith }
10803d4c4710SBarry Smith 
10813d4c4710SBarry Smith #undef __FUNCT__
10823d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
10833d4c4710SBarry Smith /*@
10843d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
10853d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
10863d4c4710SBarry Smith 
10873f9fe445SBarry Smith    Logically Collective on SNES
10883d4c4710SBarry Smith 
10893d4c4710SBarry Smith    Input Parameters:
10903d4c4710SBarry Smith +  snes     - SNES context
10913d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
10923d4c4710SBarry Smith 
10933d4c4710SBarry Smith    Level: intermediate
10943d4c4710SBarry Smith 
1095a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
10963d4c4710SBarry Smith 
10973d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
10983d4c4710SBarry Smith 
109958ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
11003d4c4710SBarry Smith @*/
11017087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
11023d4c4710SBarry Smith {
11033d4c4710SBarry Smith   PetscFunctionBegin;
11040700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1105c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
11063d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
11073d4c4710SBarry Smith   PetscFunctionReturn(0);
11083d4c4710SBarry Smith }
11093d4c4710SBarry Smith 
11103d4c4710SBarry Smith #undef __FUNCT__
11113d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
11123d4c4710SBarry Smith /*@
11133d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
11143d4c4710SBarry Smith      are allowed before SNES terminates
11153d4c4710SBarry Smith 
11163d4c4710SBarry Smith    Not Collective
11173d4c4710SBarry Smith 
11183d4c4710SBarry Smith    Input Parameter:
11193d4c4710SBarry Smith .  snes     - SNES context
11203d4c4710SBarry Smith 
11213d4c4710SBarry Smith    Output Parameter:
11223d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
11233d4c4710SBarry Smith 
11243d4c4710SBarry Smith    Level: intermediate
11253d4c4710SBarry Smith 
11263d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
11273d4c4710SBarry Smith 
11283d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
11293d4c4710SBarry Smith 
1130e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
11313d4c4710SBarry Smith @*/
11327087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
11333d4c4710SBarry Smith {
11343d4c4710SBarry Smith   PetscFunctionBegin;
11350700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11363d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
11373d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
11383d4c4710SBarry Smith   PetscFunctionReturn(0);
11393d4c4710SBarry Smith }
11403d4c4710SBarry Smith 
11413d4c4710SBarry Smith #undef __FUNCT__
1142b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
1143c96a6f78SLois Curfman McInnes /*@
1144b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1145c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1146c96a6f78SLois Curfman McInnes 
1147c7afd0dbSLois Curfman McInnes    Not Collective
1148c7afd0dbSLois Curfman McInnes 
1149c96a6f78SLois Curfman McInnes    Input Parameter:
1150c96a6f78SLois Curfman McInnes .  snes - SNES context
1151c96a6f78SLois Curfman McInnes 
1152c96a6f78SLois Curfman McInnes    Output Parameter:
1153c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1154c96a6f78SLois Curfman McInnes 
1155c96a6f78SLois Curfman McInnes    Notes:
1156c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1157c96a6f78SLois Curfman McInnes 
115836851e7fSLois Curfman McInnes    Level: intermediate
115936851e7fSLois Curfman McInnes 
1160c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
11612b668275SBarry Smith 
11628c7482ecSBarry Smith .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
1163c96a6f78SLois Curfman McInnes @*/
11647087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
1165c96a6f78SLois Curfman McInnes {
11663a40ed3dSBarry Smith   PetscFunctionBegin;
11670700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11684482741eSBarry Smith   PetscValidIntPointer(lits,2);
1169c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
11703a40ed3dSBarry Smith   PetscFunctionReturn(0);
1171c96a6f78SLois Curfman McInnes }
1172c96a6f78SLois Curfman McInnes 
11734a2ae208SSatish Balay #undef __FUNCT__
117494b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP"
117552baeb72SSatish Balay /*@
117694b7f48cSBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
11779b94acceSBarry Smith 
117894b7f48cSBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
1179c7afd0dbSLois Curfman McInnes 
11809b94acceSBarry Smith    Input Parameter:
11819b94acceSBarry Smith .  snes - the SNES context
11829b94acceSBarry Smith 
11839b94acceSBarry Smith    Output Parameter:
118494b7f48cSBarry Smith .  ksp - the KSP context
11859b94acceSBarry Smith 
11869b94acceSBarry Smith    Notes:
118794b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
11889b94acceSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
11892999313aSBarry Smith    PC contexts as well.
11909b94acceSBarry Smith 
119136851e7fSLois Curfman McInnes    Level: beginner
119236851e7fSLois Curfman McInnes 
119394b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
11949b94acceSBarry Smith 
11952999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
11969b94acceSBarry Smith @*/
11977087cfbeSBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
11989b94acceSBarry Smith {
11991cee3971SBarry Smith   PetscErrorCode ierr;
12001cee3971SBarry Smith 
12013a40ed3dSBarry Smith   PetscFunctionBegin;
12020700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12034482741eSBarry Smith   PetscValidPointer(ksp,2);
12041cee3971SBarry Smith 
12051cee3971SBarry Smith   if (!snes->ksp) {
12061cee3971SBarry Smith     ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr);
12071cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
12081cee3971SBarry Smith     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
12091cee3971SBarry Smith   }
121094b7f48cSBarry Smith   *ksp = snes->ksp;
12113a40ed3dSBarry Smith   PetscFunctionReturn(0);
12129b94acceSBarry Smith }
121382bf6240SBarry Smith 
12144a2ae208SSatish Balay #undef __FUNCT__
12152999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
12162999313aSBarry Smith /*@
12172999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
12182999313aSBarry Smith 
12192999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
12202999313aSBarry Smith 
12212999313aSBarry Smith    Input Parameters:
12222999313aSBarry Smith +  snes - the SNES context
12232999313aSBarry Smith -  ksp - the KSP context
12242999313aSBarry Smith 
12252999313aSBarry Smith    Notes:
12262999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
12272999313aSBarry Smith    so this routine is rarely needed.
12282999313aSBarry Smith 
12292999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
12302999313aSBarry Smith    decreased by one.
12312999313aSBarry Smith 
12322999313aSBarry Smith    Level: developer
12332999313aSBarry Smith 
12342999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
12352999313aSBarry Smith 
12362999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
12372999313aSBarry Smith @*/
12387087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
12392999313aSBarry Smith {
12402999313aSBarry Smith   PetscErrorCode ierr;
12412999313aSBarry Smith 
12422999313aSBarry Smith   PetscFunctionBegin;
12430700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12440700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
12452999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
12467dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1247906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
12482999313aSBarry Smith   snes->ksp = ksp;
12492999313aSBarry Smith   PetscFunctionReturn(0);
12502999313aSBarry Smith }
12512999313aSBarry Smith 
12527adad957SLisandro Dalcin #if 0
12532999313aSBarry Smith #undef __FUNCT__
12544a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc"
12556849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
1256e24b481bSBarry Smith {
1257e24b481bSBarry Smith   PetscFunctionBegin;
1258e24b481bSBarry Smith   PetscFunctionReturn(0);
1259e24b481bSBarry Smith }
12607adad957SLisandro Dalcin #endif
1261e24b481bSBarry Smith 
12629b94acceSBarry Smith /* -----------------------------------------------------------*/
12634a2ae208SSatish Balay #undef __FUNCT__
12644a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
126552baeb72SSatish Balay /*@
12669b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
12679b94acceSBarry Smith 
1268c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1269c7afd0dbSLois Curfman McInnes 
1270c7afd0dbSLois Curfman McInnes    Input Parameters:
1271906ed7ccSBarry Smith .  comm - MPI communicator
12729b94acceSBarry Smith 
12739b94acceSBarry Smith    Output Parameter:
12749b94acceSBarry Smith .  outsnes - the new SNES context
12759b94acceSBarry Smith 
1276c7afd0dbSLois Curfman McInnes    Options Database Keys:
1277c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1278c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1279c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1280c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1281c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1282c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1283c1f60f51SBarry Smith 
128436851e7fSLois Curfman McInnes    Level: beginner
128536851e7fSLois Curfman McInnes 
12869b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
12879b94acceSBarry Smith 
1288a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1289a8054027SBarry Smith 
12909b94acceSBarry Smith @*/
12917087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
12929b94acceSBarry Smith {
1293dfbe8321SBarry Smith   PetscErrorCode      ierr;
12949b94acceSBarry Smith   SNES                snes;
1295fa9f3622SBarry Smith   SNESKSPEW           *kctx;
129637fcc0dbSBarry Smith 
12973a40ed3dSBarry Smith   PetscFunctionBegin;
1298ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
12998ba1e511SMatthew Knepley   *outsnes = PETSC_NULL;
13008ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
13018ba1e511SMatthew Knepley   ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr);
13028ba1e511SMatthew Knepley #endif
13038ba1e511SMatthew Knepley 
13043194b578SJed Brown   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
13057adad957SLisandro Dalcin 
130685385478SLisandro Dalcin   snes->ops->converged    = SNESDefaultConverged;
13072c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
130888976e71SPeter Brune   snes->tolerancesset     = PETSC_FALSE;
13099b94acceSBarry Smith   snes->max_its           = 50;
13109750a799SBarry Smith   snes->max_funcs         = 10000;
13119b94acceSBarry Smith   snes->norm              = 0.0;
1312*534ebe21SPeter Brune   snes->normtype          = SNES_NORM_DEFAULT;
1313b4874afaSBarry Smith   snes->rtol              = 1.e-8;
1314b4874afaSBarry Smith   snes->ttol              = 0.0;
131570441072SBarry Smith   snes->abstol            = 1.e-50;
1316c60f73f4SPeter Brune   snes->stol              = 1.e-8;
13174b27c08aSLois Curfman McInnes   snes->deltatol          = 1.e-12;
13189b94acceSBarry Smith   snes->nfuncs            = 0;
131950ffb88aSMatthew Knepley   snes->numFailures       = 0;
132050ffb88aSMatthew Knepley   snes->maxFailures       = 1;
13217a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1322e35cf81dSBarry Smith   snes->lagjacobian       = 1;
1323a8054027SBarry Smith   snes->lagpreconditioner = 1;
1324639f9d9dSBarry Smith   snes->numbermonitors    = 0;
13259b94acceSBarry Smith   snes->data              = 0;
13264dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1327186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
13286f24a144SLois Curfman McInnes   snes->nwork             = 0;
132958c9b817SLisandro Dalcin   snes->work              = 0;
133058c9b817SLisandro Dalcin   snes->nvwork            = 0;
133158c9b817SLisandro Dalcin   snes->vwork             = 0;
1332758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1333758f92a0SBarry Smith   snes->conv_hist_max     = 0;
1334758f92a0SBarry Smith   snes->conv_hist         = PETSC_NULL;
1335758f92a0SBarry Smith   snes->conv_hist_its     = PETSC_NULL;
1336758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1337e4ed7901SPeter Brune   snes->vec_func_init_set = PETSC_FALSE;
1338e4ed7901SPeter Brune   snes->norm_init         = 0.;
1339e4ed7901SPeter Brune   snes->norm_init_set     = PETSC_FALSE;
1340184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
134189b92e6fSPeter Brune   snes->gssweeps          = 1;
13429b94acceSBarry Smith 
13433d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
13443d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
13453d4c4710SBarry Smith 
13469b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
134738f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr);
13489b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
13499b94acceSBarry Smith   kctx->version     = 2;
13509b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
13519b94acceSBarry Smith                              this was too large for some test cases */
135275567043SBarry Smith   kctx->rtol_last   = 0.0;
13539b94acceSBarry Smith   kctx->rtol_max    = .9;
13549b94acceSBarry Smith   kctx->gamma       = 1.0;
135562d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
135671f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
13579b94acceSBarry Smith   kctx->threshold   = .1;
135875567043SBarry Smith   kctx->lresid_last = 0.0;
135975567043SBarry Smith   kctx->norm_last   = 0.0;
13609b94acceSBarry Smith 
13619b94acceSBarry Smith   *outsnes = snes;
13623a40ed3dSBarry Smith   PetscFunctionReturn(0);
13639b94acceSBarry Smith }
13649b94acceSBarry Smith 
13654a2ae208SSatish Balay #undef __FUNCT__
13664a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
13679b94acceSBarry Smith /*@C
13689b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
13699b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
13709b94acceSBarry Smith    equations.
13719b94acceSBarry Smith 
13723f9fe445SBarry Smith    Logically Collective on SNES
1373fee21e36SBarry Smith 
1374c7afd0dbSLois Curfman McInnes    Input Parameters:
1375c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1376c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1377de044059SHong Zhang .  func - function evaluation routine
1378c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1379c7afd0dbSLois Curfman McInnes          function evaluation routine (may be PETSC_NULL)
13809b94acceSBarry Smith 
1381c7afd0dbSLois Curfman McInnes    Calling sequence of func:
13828d76a1e5SLois Curfman McInnes $    func (SNES snes,Vec x,Vec f,void *ctx);
1383c7afd0dbSLois Curfman McInnes 
1384c586c404SJed Brown +  snes - the SNES context
1385c586c404SJed Brown .  x - state at which to evaluate residual
1386c586c404SJed Brown .  f - vector to put residual
1387c7afd0dbSLois Curfman McInnes -  ctx - optional user-defined function context
13889b94acceSBarry Smith 
13899b94acceSBarry Smith    Notes:
13909b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
13919b94acceSBarry Smith $      f'(x) x = -f(x),
1392c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
13939b94acceSBarry Smith 
139436851e7fSLois Curfman McInnes    Level: beginner
139536851e7fSLois Curfman McInnes 
13969b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
13979b94acceSBarry Smith 
13988b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard()
13999b94acceSBarry Smith @*/
14007087cfbeSBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
14019b94acceSBarry Smith {
140285385478SLisandro Dalcin   PetscErrorCode ierr;
14036cab3a1bSJed Brown   DM             dm;
14046cab3a1bSJed Brown 
14053a40ed3dSBarry Smith   PetscFunctionBegin;
14060700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1407d2a683ecSLisandro Dalcin   if (r) {
1408d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1409d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
141085385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
14116bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
141285385478SLisandro Dalcin     snes->vec_func = r;
1413d2a683ecSLisandro Dalcin   }
14146cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
14156cab3a1bSJed Brown   ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr);
14163a40ed3dSBarry Smith   PetscFunctionReturn(0);
14179b94acceSBarry Smith }
14189b94acceSBarry Smith 
1419646217ecSPeter Brune 
1420646217ecSPeter Brune #undef __FUNCT__
1421e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction"
1422e4ed7901SPeter Brune /*@C
1423e4ed7901SPeter Brune    SNESSetInitialFunction - Sets the function vector to be used as the
1424e4ed7901SPeter Brune    function norm at the initialization of the method.  In some
1425e4ed7901SPeter Brune    instances, the user has precomputed the function before calling
1426e4ed7901SPeter Brune    SNESSolve.  This function allows one to avoid a redundant call
1427e4ed7901SPeter Brune    to SNESComputeFunction in that case.
1428e4ed7901SPeter Brune 
1429e4ed7901SPeter Brune    Logically Collective on SNES
1430e4ed7901SPeter Brune 
1431e4ed7901SPeter Brune    Input Parameters:
1432e4ed7901SPeter Brune +  snes - the SNES context
1433e4ed7901SPeter Brune -  f - vector to store function value
1434e4ed7901SPeter Brune 
1435e4ed7901SPeter Brune    Notes:
1436e4ed7901SPeter Brune    This should not be modified during the solution procedure.
1437e4ed7901SPeter Brune 
1438e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1439e4ed7901SPeter Brune 
1440e4ed7901SPeter Brune    Level: developer
1441e4ed7901SPeter Brune 
1442e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function
1443e4ed7901SPeter Brune 
1444e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm()
1445e4ed7901SPeter Brune @*/
1446e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunction(SNES snes, Vec f)
1447e4ed7901SPeter Brune {
1448e4ed7901SPeter Brune   PetscErrorCode ierr;
1449e4ed7901SPeter Brune   Vec            vec_func;
1450e4ed7901SPeter Brune 
1451e4ed7901SPeter Brune   PetscFunctionBegin;
1452e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1453e4ed7901SPeter Brune   PetscValidHeaderSpecific(f,VEC_CLASSID,2);
1454e4ed7901SPeter Brune   PetscCheckSameComm(snes,1,f,2);
1455e4ed7901SPeter Brune   ierr = PetscObjectReference((PetscObject)f);CHKERRQ(ierr);
1456e4ed7901SPeter Brune   ierr = SNESGetFunction(snes,&vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
1457e4ed7901SPeter Brune   ierr = VecCopy(f, vec_func);CHKERRQ(ierr);
1458217b9c2eSPeter Brune   snes->vec_func_init_set = PETSC_TRUE;
1459e4ed7901SPeter Brune   PetscFunctionReturn(0);
1460e4ed7901SPeter Brune }
1461e4ed7901SPeter Brune 
1462e4ed7901SPeter Brune 
1463e4ed7901SPeter Brune #undef __FUNCT__
1464e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunctionNorm"
1465e4ed7901SPeter Brune /*@C
1466e4ed7901SPeter Brune    SNESSetInitialFunctionNorm - Sets the function norm to be used as the function norm
1467e4ed7901SPeter Brune    at the initialization of the  method.  In some instances, the user has precomputed
1468e4ed7901SPeter Brune    the function and its norm before calling SNESSolve.  This function allows one to
1469e4ed7901SPeter Brune    avoid a redundant call to SNESComputeFunction() and VecNorm() in that case.
1470e4ed7901SPeter Brune 
1471e4ed7901SPeter Brune    Logically Collective on SNES
1472e4ed7901SPeter Brune 
1473e4ed7901SPeter Brune    Input Parameters:
1474e4ed7901SPeter Brune +  snes - the SNES context
1475e4ed7901SPeter Brune -  fnorm - the norm of F as set by SNESSetInitialFunction()
1476e4ed7901SPeter Brune 
1477e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1478e4ed7901SPeter Brune 
1479e4ed7901SPeter Brune    Level: developer
1480e4ed7901SPeter Brune 
1481e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function, norm
1482e4ed7901SPeter Brune 
1483e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction()
1484e4ed7901SPeter Brune @*/
1485e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm)
1486e4ed7901SPeter Brune {
1487e4ed7901SPeter Brune   PetscFunctionBegin;
1488e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1489e4ed7901SPeter Brune   snes->norm_init = fnorm;
1490e4ed7901SPeter Brune   snes->norm_init_set = PETSC_TRUE;
1491e4ed7901SPeter Brune   PetscFunctionReturn(0);
1492e4ed7901SPeter Brune }
1493e4ed7901SPeter Brune 
1494e4ed7901SPeter Brune #undef __FUNCT__
1495*534ebe21SPeter Brune #define __FUNCT__ "SNESSetNormType"
1496*534ebe21SPeter Brune /*@
1497*534ebe21SPeter Brune    SNESSetNormType - Sets the SNESNormType used in covergence and monitoring
1498*534ebe21SPeter Brune    of the SNES method.
1499*534ebe21SPeter Brune 
1500*534ebe21SPeter Brune    Logically Collective on SNES
1501*534ebe21SPeter Brune 
1502*534ebe21SPeter Brune    Input Parameters:
1503*534ebe21SPeter Brune +  snes - the SNES context
1504*534ebe21SPeter Brune -  normtype - the type of the norm used
1505*534ebe21SPeter Brune 
1506*534ebe21SPeter Brune    Notes:
1507*534ebe21SPeter Brune    Only certain SNES methods support certain SNESNormTypes.  Most require evaluation
1508*534ebe21SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
1509*534ebe21SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1510*534ebe21SPeter Brune    (SNESGS) and the like do not require the norm of the function to be computed, and therfore
1511*534ebe21SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
1512*534ebe21SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
1513*534ebe21SPeter Brune    their solution.
1514*534ebe21SPeter Brune 
1515*534ebe21SPeter Brune    Level: developer
1516*534ebe21SPeter Brune 
1517*534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1518*534ebe21SPeter Brune 
1519*534ebe21SPeter Brune .seealso: SNESGetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType
1520*534ebe21SPeter Brune @*/
1521*534ebe21SPeter Brune PetscErrorCode  SNESSetNormType(SNES snes, SNESNormType normtype)
1522*534ebe21SPeter Brune {
1523*534ebe21SPeter Brune   PetscFunctionBegin;
1524*534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1525*534ebe21SPeter Brune   snes->normtype = normtype;
1526*534ebe21SPeter Brune   PetscFunctionReturn(0);
1527*534ebe21SPeter Brune }
1528*534ebe21SPeter Brune 
1529*534ebe21SPeter Brune 
1530*534ebe21SPeter Brune #undef __FUNCT__
1531*534ebe21SPeter Brune #define __FUNCT__ "SNESGetNormType"
1532*534ebe21SPeter Brune /*@
1533*534ebe21SPeter Brune    SNESGetNormType - Gets the SNESNormType used in covergence and monitoring
1534*534ebe21SPeter Brune    of the SNES method.
1535*534ebe21SPeter Brune 
1536*534ebe21SPeter Brune    Logically Collective on SNES
1537*534ebe21SPeter Brune 
1538*534ebe21SPeter Brune    Input Parameters:
1539*534ebe21SPeter Brune +  snes - the SNES context
1540*534ebe21SPeter Brune -  normtype - the type of the norm used
1541*534ebe21SPeter Brune 
1542*534ebe21SPeter Brune    Level: advanced
1543*534ebe21SPeter Brune 
1544*534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1545*534ebe21SPeter Brune 
1546*534ebe21SPeter Brune .seealso: SNESSetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType
1547*534ebe21SPeter Brune @*/
1548*534ebe21SPeter Brune PetscErrorCode  SNESGetNormType(SNES snes, SNESNormType *normtype)
1549*534ebe21SPeter Brune {
1550*534ebe21SPeter Brune   PetscFunctionBegin;
1551*534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1552*534ebe21SPeter Brune   *normtype = snes->normtype;
1553*534ebe21SPeter Brune   PetscFunctionReturn(0);
1554*534ebe21SPeter Brune }
1555*534ebe21SPeter Brune 
1556*534ebe21SPeter Brune #undef __FUNCT__
1557646217ecSPeter Brune #define __FUNCT__ "SNESSetGS"
1558c79ef259SPeter Brune /*@C
1559c79ef259SPeter Brune    SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for
1560c79ef259SPeter Brune    use with composed nonlinear solvers.
1561c79ef259SPeter Brune 
1562c79ef259SPeter Brune    Input Parameters:
1563c79ef259SPeter Brune +  snes   - the SNES context
1564c79ef259SPeter Brune .  gsfunc - function evaluation routine
1565c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
1566c79ef259SPeter Brune             smoother evaluation routine (may be PETSC_NULL)
1567c79ef259SPeter Brune 
1568c79ef259SPeter Brune    Calling sequence of func:
1569c79ef259SPeter Brune $    func (SNES snes,Vec x,Vec b,void *ctx);
1570c79ef259SPeter Brune 
1571c79ef259SPeter Brune +  X   - solution vector
1572c79ef259SPeter Brune .  B   - RHS vector
1573d28543b3SPeter Brune -  ctx - optional user-defined Gauss-Seidel context
1574c79ef259SPeter Brune 
1575c79ef259SPeter Brune    Notes:
1576c79ef259SPeter Brune    The GS routines are used by the composed nonlinear solver to generate
1577c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
1578c79ef259SPeter Brune 
1579d28543b3SPeter Brune    Level: intermediate
1580c79ef259SPeter Brune 
1581d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel
1582c79ef259SPeter Brune 
1583c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS()
1584c79ef259SPeter Brune @*/
15856cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx)
15866cab3a1bSJed Brown {
15876cab3a1bSJed Brown   PetscErrorCode ierr;
15886cab3a1bSJed Brown   DM dm;
15896cab3a1bSJed Brown 
1590646217ecSPeter Brune   PetscFunctionBegin;
15916cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15926cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
15936cab3a1bSJed Brown   ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr);
1594646217ecSPeter Brune   PetscFunctionReturn(0);
1595646217ecSPeter Brune }
1596646217ecSPeter Brune 
1597d25893d9SBarry Smith #undef __FUNCT__
159889b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps"
159989b92e6fSPeter Brune /*@
160089b92e6fSPeter Brune    SNESSetGSSweeps - Sets the number of sweeps of GS to use.
160189b92e6fSPeter Brune 
160289b92e6fSPeter Brune    Input Parameters:
160389b92e6fSPeter Brune +  snes   - the SNES context
160489b92e6fSPeter Brune -  sweeps  - the number of sweeps of GS to perform.
160589b92e6fSPeter Brune 
160689b92e6fSPeter Brune    Level: intermediate
160789b92e6fSPeter Brune 
160889b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
160989b92e6fSPeter Brune 
161089b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps()
161189b92e6fSPeter Brune @*/
161289b92e6fSPeter Brune 
161389b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) {
161489b92e6fSPeter Brune   PetscFunctionBegin;
161589b92e6fSPeter Brune   snes->gssweeps = sweeps;
161689b92e6fSPeter Brune   PetscFunctionReturn(0);
161789b92e6fSPeter Brune }
161889b92e6fSPeter Brune 
161989b92e6fSPeter Brune 
162089b92e6fSPeter Brune #undef __FUNCT__
162189b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps"
162289b92e6fSPeter Brune /*@
162389b92e6fSPeter Brune    SNESGetGSSweeps - Gets the number of sweeps GS will use.
162489b92e6fSPeter Brune 
162589b92e6fSPeter Brune    Input Parameters:
162689b92e6fSPeter Brune .  snes   - the SNES context
162789b92e6fSPeter Brune 
162889b92e6fSPeter Brune    Output Parameters:
162989b92e6fSPeter Brune .  sweeps  - the number of sweeps of GS to perform.
163089b92e6fSPeter Brune 
163189b92e6fSPeter Brune    Level: intermediate
163289b92e6fSPeter Brune 
163389b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
163489b92e6fSPeter Brune 
163589b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps()
163689b92e6fSPeter Brune @*/
163789b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) {
163889b92e6fSPeter Brune   PetscFunctionBegin;
163989b92e6fSPeter Brune   *sweeps = snes->gssweeps;
164089b92e6fSPeter Brune   PetscFunctionReturn(0);
164189b92e6fSPeter Brune }
164289b92e6fSPeter Brune 
164389b92e6fSPeter Brune #undef __FUNCT__
16448b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction"
16458b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
16468b0a5094SBarry Smith {
16478b0a5094SBarry Smith   PetscErrorCode ierr;
16486cab3a1bSJed Brown   void *functx,*jacctx;
16496cab3a1bSJed Brown 
16508b0a5094SBarry Smith   PetscFunctionBegin;
16516cab3a1bSJed Brown   ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
16526cab3a1bSJed Brown   ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr);
16538b0a5094SBarry Smith   /*  A(x)*x - b(x) */
16546cab3a1bSJed Brown   ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr);
16556cab3a1bSJed Brown   ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr);
16568b0a5094SBarry Smith   ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
16578b0a5094SBarry Smith   ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
16588b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
16598b0a5094SBarry Smith   ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr);
16608b0a5094SBarry Smith   PetscFunctionReturn(0);
16618b0a5094SBarry Smith }
16628b0a5094SBarry Smith 
16638b0a5094SBarry Smith #undef __FUNCT__
16648b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian"
16658b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
16668b0a5094SBarry Smith {
16678b0a5094SBarry Smith   PetscFunctionBegin;
16688b0a5094SBarry Smith   *flag = snes->matstruct;
16698b0a5094SBarry Smith   PetscFunctionReturn(0);
16708b0a5094SBarry Smith }
16718b0a5094SBarry Smith 
16728b0a5094SBarry Smith #undef __FUNCT__
16738b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard"
16748b0a5094SBarry Smith /*@C
16750d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
16768b0a5094SBarry Smith 
16778b0a5094SBarry Smith    Logically Collective on SNES
16788b0a5094SBarry Smith 
16798b0a5094SBarry Smith    Input Parameters:
16808b0a5094SBarry Smith +  snes - the SNES context
16818b0a5094SBarry Smith .  r - vector to store function value
16828b0a5094SBarry Smith .  func - function evaluation routine
16838b0a5094SBarry 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)
16848b0a5094SBarry Smith .  mat - matrix to store A
16858b0a5094SBarry Smith .  mfunc  - function to compute matrix value
16868b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
16878b0a5094SBarry Smith          function evaluation routine (may be PETSC_NULL)
16888b0a5094SBarry Smith 
16898b0a5094SBarry Smith    Calling sequence of func:
16908b0a5094SBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
16918b0a5094SBarry Smith 
16928b0a5094SBarry Smith +  f - function vector
16938b0a5094SBarry Smith -  ctx - optional user-defined function context
16948b0a5094SBarry Smith 
16958b0a5094SBarry Smith    Calling sequence of mfunc:
16968b0a5094SBarry Smith $     mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx);
16978b0a5094SBarry Smith 
16988b0a5094SBarry Smith +  x - input vector
16998b0a5094SBarry 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(),
17008b0a5094SBarry Smith           normally just pass mat in this location
17018b0a5094SBarry Smith .  mat - form A(x) matrix
17028b0a5094SBarry Smith .  flag - flag indicating information about the preconditioner matrix
17038b0a5094SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
17048b0a5094SBarry Smith -  ctx - [optional] user-defined Jacobian context
17058b0a5094SBarry Smith 
17068b0a5094SBarry Smith    Notes:
17078b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
17088b0a5094SBarry Smith 
17098b0a5094SBarry 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}
17108b0a5094SBarry 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.
17118b0a5094SBarry Smith 
17128b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
17138b0a5094SBarry Smith 
17140d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
17150d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
17168b0a5094SBarry Smith 
17178b0a5094SBarry 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
17188b0a5094SBarry 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
17198b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
17208b0a5094SBarry Smith 
17218b0a5094SBarry Smith    Level: beginner
17228b0a5094SBarry Smith 
17238b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function
17248b0a5094SBarry Smith 
17250d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard()
17268b0a5094SBarry Smith @*/
17278b0a5094SBarry 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)
17288b0a5094SBarry Smith {
17298b0a5094SBarry Smith   PetscErrorCode ierr;
17308b0a5094SBarry Smith   PetscFunctionBegin;
17318b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
17328b0a5094SBarry Smith   snes->ops->computepfunction = func;
17338b0a5094SBarry Smith   snes->ops->computepjacobian = mfunc;
17348b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
17358b0a5094SBarry Smith   ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
17368b0a5094SBarry Smith   PetscFunctionReturn(0);
17378b0a5094SBarry Smith }
17388b0a5094SBarry Smith 
17398b0a5094SBarry Smith #undef __FUNCT__
1740d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess"
1741d25893d9SBarry Smith /*@C
1742d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1743d25893d9SBarry Smith 
1744d25893d9SBarry Smith    Logically Collective on SNES
1745d25893d9SBarry Smith 
1746d25893d9SBarry Smith    Input Parameters:
1747d25893d9SBarry Smith +  snes - the SNES context
1748d25893d9SBarry Smith .  func - function evaluation routine
1749d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
1750d25893d9SBarry Smith          function evaluation routine (may be PETSC_NULL)
1751d25893d9SBarry Smith 
1752d25893d9SBarry Smith    Calling sequence of func:
1753d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
1754d25893d9SBarry Smith 
1755d25893d9SBarry Smith .  f - function vector
1756d25893d9SBarry Smith -  ctx - optional user-defined function context
1757d25893d9SBarry Smith 
1758d25893d9SBarry Smith    Level: intermediate
1759d25893d9SBarry Smith 
1760d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
1761d25893d9SBarry Smith 
1762d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1763d25893d9SBarry Smith @*/
1764d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1765d25893d9SBarry Smith {
1766d25893d9SBarry Smith   PetscFunctionBegin;
1767d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1768d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
1769d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
1770d25893d9SBarry Smith   PetscFunctionReturn(0);
1771d25893d9SBarry Smith }
1772d25893d9SBarry Smith 
17733ab0aad5SBarry Smith /* --------------------------------------------------------------- */
17743ab0aad5SBarry Smith #undef __FUNCT__
17751096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
17761096aae1SMatthew Knepley /*@C
17771096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
17781096aae1SMatthew Knepley    it assumes a zero right hand side.
17791096aae1SMatthew Knepley 
17803f9fe445SBarry Smith    Logically Collective on SNES
17811096aae1SMatthew Knepley 
17821096aae1SMatthew Knepley    Input Parameter:
17831096aae1SMatthew Knepley .  snes - the SNES context
17841096aae1SMatthew Knepley 
17851096aae1SMatthew Knepley    Output Parameter:
1786bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
17871096aae1SMatthew Knepley 
17881096aae1SMatthew Knepley    Level: intermediate
17891096aae1SMatthew Knepley 
17901096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
17911096aae1SMatthew Knepley 
179285385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
17931096aae1SMatthew Knepley @*/
17947087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
17951096aae1SMatthew Knepley {
17961096aae1SMatthew Knepley   PetscFunctionBegin;
17970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
17981096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
179985385478SLisandro Dalcin   *rhs = snes->vec_rhs;
18001096aae1SMatthew Knepley   PetscFunctionReturn(0);
18011096aae1SMatthew Knepley }
18021096aae1SMatthew Knepley 
18031096aae1SMatthew Knepley #undef __FUNCT__
18044a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
18059b94acceSBarry Smith /*@
180636851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
18079b94acceSBarry Smith                          SNESSetFunction().
18089b94acceSBarry Smith 
1809c7afd0dbSLois Curfman McInnes    Collective on SNES
1810c7afd0dbSLois Curfman McInnes 
18119b94acceSBarry Smith    Input Parameters:
1812c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1813c7afd0dbSLois Curfman McInnes -  x - input vector
18149b94acceSBarry Smith 
18159b94acceSBarry Smith    Output Parameter:
18163638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
18179b94acceSBarry Smith 
18181bffabb2SLois Curfman McInnes    Notes:
181936851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
182036851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
182136851e7fSLois Curfman McInnes    themselves.
182236851e7fSLois Curfman McInnes 
182336851e7fSLois Curfman McInnes    Level: developer
182436851e7fSLois Curfman McInnes 
18259b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
18269b94acceSBarry Smith 
1827a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
18289b94acceSBarry Smith @*/
18297087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
18309b94acceSBarry Smith {
1831dfbe8321SBarry Smith   PetscErrorCode ierr;
18326cab3a1bSJed Brown   DM             dm;
18336cab3a1bSJed Brown   SNESDM         sdm;
18349b94acceSBarry Smith 
18353a40ed3dSBarry Smith   PetscFunctionBegin;
18360700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
18370700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
18380700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
1839c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
1840c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
18414ec14c9cSBarry Smith   VecValidValues(x,2,PETSC_TRUE);
1842184914b5SBarry Smith 
18436cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
18446cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
1845d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
18466cab3a1bSJed Brown   if (sdm->computefunction) {
1847d64ed03dSBarry Smith     PetscStackPush("SNES user function");
18486cab3a1bSJed Brown     ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
1849d64ed03dSBarry Smith     PetscStackPop;
185073250ac0SBarry Smith   } else if (snes->dm) {
1851644e2e5bSBarry Smith     ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr);
1852c90fad12SPeter Brune   } else if (snes->vec_rhs) {
1853c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
1854644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
185585385478SLisandro Dalcin   if (snes->vec_rhs) {
185685385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
18573ab0aad5SBarry Smith   }
1858ae3c334cSLois Curfman McInnes   snes->nfuncs++;
1859d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
18604ec14c9cSBarry Smith   VecValidValues(y,3,PETSC_FALSE);
18613a40ed3dSBarry Smith   PetscFunctionReturn(0);
18629b94acceSBarry Smith }
18639b94acceSBarry Smith 
18644a2ae208SSatish Balay #undef __FUNCT__
1865646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS"
1866c79ef259SPeter Brune /*@
1867c79ef259SPeter Brune    SNESComputeGS - Calls the Gauss-Seidel function that has been set with
1868c79ef259SPeter Brune                    SNESSetGS().
1869c79ef259SPeter Brune 
1870c79ef259SPeter Brune    Collective on SNES
1871c79ef259SPeter Brune 
1872c79ef259SPeter Brune    Input Parameters:
1873c79ef259SPeter Brune +  snes - the SNES context
1874c79ef259SPeter Brune .  x - input vector
1875c79ef259SPeter Brune -  b - rhs vector
1876c79ef259SPeter Brune 
1877c79ef259SPeter Brune    Output Parameter:
1878c79ef259SPeter Brune .  x - new solution vector
1879c79ef259SPeter Brune 
1880c79ef259SPeter Brune    Notes:
1881c79ef259SPeter Brune    SNESComputeGS() is typically used within composed nonlinear solver
1882c79ef259SPeter Brune    implementations, so most users would not generally call this routine
1883c79ef259SPeter Brune    themselves.
1884c79ef259SPeter Brune 
1885c79ef259SPeter Brune    Level: developer
1886c79ef259SPeter Brune 
1887c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function
1888c79ef259SPeter Brune 
1889c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction()
1890c79ef259SPeter Brune @*/
1891646217ecSPeter Brune PetscErrorCode  SNESComputeGS(SNES snes,Vec b,Vec x)
1892646217ecSPeter Brune {
1893646217ecSPeter Brune   PetscErrorCode ierr;
189489b92e6fSPeter Brune   PetscInt i;
18956cab3a1bSJed Brown   DM dm;
18966cab3a1bSJed Brown   SNESDM sdm;
1897646217ecSPeter Brune 
1898646217ecSPeter Brune   PetscFunctionBegin;
1899646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1900646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
1901646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
1902646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
1903646217ecSPeter Brune   if(b) PetscCheckSameComm(snes,1,b,3);
19044ec14c9cSBarry Smith   if (b) VecValidValues(b,2,PETSC_TRUE);
1905701cf23dSPeter Brune   ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
19066cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
19076cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
19086cab3a1bSJed Brown   if (sdm->computegs) {
190989b92e6fSPeter Brune     for (i = 0; i < snes->gssweeps; i++) {
1910646217ecSPeter Brune       PetscStackPush("SNES user GS");
19116cab3a1bSJed Brown       ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
1912646217ecSPeter Brune       PetscStackPop;
191389b92e6fSPeter Brune     }
1914646217ecSPeter Brune   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve().");
1915701cf23dSPeter Brune   ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
19164ec14c9cSBarry Smith   VecValidValues(x,3,PETSC_FALSE);
1917646217ecSPeter Brune   PetscFunctionReturn(0);
1918646217ecSPeter Brune }
1919646217ecSPeter Brune 
1920646217ecSPeter Brune 
1921646217ecSPeter Brune #undef __FUNCT__
19224a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
192362fef451SLois Curfman McInnes /*@
192462fef451SLois Curfman McInnes    SNESComputeJacobian - Computes the Jacobian matrix that has been
192562fef451SLois Curfman McInnes    set with SNESSetJacobian().
192662fef451SLois Curfman McInnes 
1927c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
1928c7afd0dbSLois Curfman McInnes 
192962fef451SLois Curfman McInnes    Input Parameters:
1930c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1931c7afd0dbSLois Curfman McInnes -  x - input vector
193262fef451SLois Curfman McInnes 
193362fef451SLois Curfman McInnes    Output Parameters:
1934c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
193562fef451SLois Curfman McInnes .  B - optional preconditioning matrix
19362b668275SBarry Smith -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1937fee21e36SBarry Smith 
1938e35cf81dSBarry Smith   Options Database Keys:
1939e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
1940693365a8SJed Brown .    -snes_lag_jacobian <lag>
1941693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
1942693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
1943693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
19444c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
1945c01495d3SJed Brown .    -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference
1946c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
1947c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
1948c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
1949c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
19504c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
1951c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
1952c01495d3SJed Brown 
1953e35cf81dSBarry Smith 
195462fef451SLois Curfman McInnes    Notes:
195562fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
195662fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
195762fef451SLois Curfman McInnes 
195894b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the
1959dc5a77f8SLois Curfman McInnes    flag parameter.
196062fef451SLois Curfman McInnes 
196136851e7fSLois Curfman McInnes    Level: developer
196236851e7fSLois Curfman McInnes 
196362fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
196462fef451SLois Curfman McInnes 
1965e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
196662fef451SLois Curfman McInnes @*/
19677087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
19689b94acceSBarry Smith {
1969dfbe8321SBarry Smith   PetscErrorCode ierr;
1970ace3abfcSBarry Smith   PetscBool      flag;
19716cab3a1bSJed Brown   DM             dm;
19726cab3a1bSJed Brown   SNESDM         sdm;
19733a40ed3dSBarry Smith 
19743a40ed3dSBarry Smith   PetscFunctionBegin;
19750700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
19760700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
19774482741eSBarry Smith   PetscValidPointer(flg,5);
1978c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
19794ec14c9cSBarry Smith   VecValidValues(X,2,PETSC_TRUE);
19806cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
19816cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
19826cab3a1bSJed Brown   if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
1983ebd3b9afSBarry Smith 
1984ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
1985ebd3b9afSBarry Smith 
1986fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
1987fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
1988fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
1989fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
1990e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1991e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
1992ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1993ebd3b9afSBarry Smith     if (flag) {
1994ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1995ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1996ebd3b9afSBarry Smith     }
1997e35cf81dSBarry Smith     PetscFunctionReturn(0);
1998e35cf81dSBarry Smith   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
1999e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
2000e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
2001ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
2002ebd3b9afSBarry Smith     if (flag) {
2003ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2004ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2005ebd3b9afSBarry Smith     }
2006e35cf81dSBarry Smith     PetscFunctionReturn(0);
2007e35cf81dSBarry Smith   }
2008e35cf81dSBarry Smith 
2009c4fc05e7SBarry Smith   *flg = DIFFERENT_NONZERO_PATTERN;
2010e35cf81dSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
2011d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
20126cab3a1bSJed Brown   ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr);
2013d64ed03dSBarry Smith   PetscStackPop;
2014d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
2015a8054027SBarry Smith 
20163b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
20173b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
20183b4f5425SBarry Smith     snes->lagpreconditioner = -1;
20193b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
2020a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
2021a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
2022a8054027SBarry Smith   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
2023a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
2024a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
2025a8054027SBarry Smith   }
2026a8054027SBarry Smith 
20276d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
20280700a824SBarry Smith   /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
20290700a824SBarry Smith     PetscValidHeaderSpecific(*B,MAT_CLASSID,4);   */
2030693365a8SJed Brown   {
2031693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
2032693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr);
2033693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
2034693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
2035693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr);
2036693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
2037693365a8SJed Brown       Mat Bexp_mine = PETSC_NULL,Bexp,FDexp;
2038693365a8SJed Brown       MatStructure mstruct;
2039693365a8SJed Brown       PetscViewer vdraw,vstdout;
20406b3a5b13SJed Brown       PetscBool flg;
2041693365a8SJed Brown       if (flag_operator) {
2042693365a8SJed Brown         ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr);
2043693365a8SJed Brown         Bexp = Bexp_mine;
2044693365a8SJed Brown       } else {
2045693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
2046693365a8SJed Brown         ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
2047693365a8SJed Brown         if (flg) Bexp = *B;
2048693365a8SJed Brown         else {
2049693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
2050693365a8SJed Brown           ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr);
2051693365a8SJed Brown           Bexp = Bexp_mine;
2052693365a8SJed Brown         }
2053693365a8SJed Brown       }
2054693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
2055693365a8SJed Brown       ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr);
2056693365a8SJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
2057693365a8SJed Brown       if (flag_draw || flag_contour) {
2058693365a8SJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
2059693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
2060693365a8SJed Brown       } else vdraw = PETSC_NULL;
2061693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr);
2062693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
2063693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
2064693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
2065693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2066693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
2067693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2068693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
2069693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2070693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
2071693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
2072693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
2073693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
2074693365a8SJed Brown       }
2075693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
2076693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
2077693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
2078693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
2079693365a8SJed Brown     }
2080693365a8SJed Brown   }
20814c30e9fbSJed Brown   {
20826719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
20836719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
20844c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr);
20856719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr);
20864c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
20874c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
20886719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr);
20896719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr);
20906719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr);
20916719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
20924c30e9fbSJed Brown       Mat Bfd;
20934c30e9fbSJed Brown       MatStructure mstruct;
20944c30e9fbSJed Brown       PetscViewer vdraw,vstdout;
20954c30e9fbSJed Brown       ISColoring iscoloring;
20964c30e9fbSJed Brown       MatFDColoring matfdcoloring;
20974c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
20984c30e9fbSJed Brown       void *funcctx;
20996719d8e4SJed Brown       PetscReal norm1,norm2,normmax;
21004c30e9fbSJed Brown 
21014c30e9fbSJed Brown       ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
21024c30e9fbSJed Brown       ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
21034c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
21044c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
21054c30e9fbSJed Brown 
21064c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
21074c30e9fbSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr);
21084c30e9fbSJed Brown       ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr);
21094c30e9fbSJed Brown       ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
21104c30e9fbSJed Brown       ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
21114c30e9fbSJed Brown       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
21124c30e9fbSJed Brown       ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr);
21134c30e9fbSJed Brown       ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
21144c30e9fbSJed Brown 
21154c30e9fbSJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
21164c30e9fbSJed Brown       if (flag_draw || flag_contour) {
21174c30e9fbSJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
21184c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
21194c30e9fbSJed Brown       } else vdraw = PETSC_NULL;
21204c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
21216719d8e4SJed Brown       if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);}
21224c30e9fbSJed Brown       if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);}
21234c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
21246719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
21254c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
21264c30e9fbSJed Brown       ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
21274c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
21286719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
21294c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
21306719d8e4SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr);
21316719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
21324c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
21334c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
21344c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
21354c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
21364c30e9fbSJed Brown       }
21374c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
21386719d8e4SJed Brown 
21396719d8e4SJed Brown       if (flag_threshold) {
21406719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
21416719d8e4SJed Brown         ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr);
21426719d8e4SJed Brown         ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr);
21436719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
21446719d8e4SJed Brown           const PetscScalar *ba,*ca;
21456719d8e4SJed Brown           const PetscInt *bj,*cj;
21466719d8e4SJed Brown           PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
21476719d8e4SJed Brown           PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0;
21486719d8e4SJed Brown           ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
21496719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
21506719d8e4SJed Brown           if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
21516719d8e4SJed Brown           for (j=0; j<bn; j++) {
21526719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
21536719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
21546719d8e4SJed Brown               maxentrycol = bj[j];
21556719d8e4SJed Brown               maxentry = PetscRealPart(ba[j]);
21566719d8e4SJed Brown             }
21576719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
21586719d8e4SJed Brown               maxdiffcol = bj[j];
21596719d8e4SJed Brown               maxdiff = PetscRealPart(ca[j]);
21606719d8e4SJed Brown             }
21616719d8e4SJed Brown             if (rdiff > maxrdiff) {
21626719d8e4SJed Brown               maxrdiffcol = bj[j];
21636719d8e4SJed Brown               maxrdiff = rdiff;
21646719d8e4SJed Brown             }
21656719d8e4SJed Brown           }
21666719d8e4SJed Brown           if (maxrdiff > 1) {
21676719d8e4SJed 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);
21686719d8e4SJed Brown             for (j=0; j<bn; j++) {
21696719d8e4SJed Brown               PetscReal rdiff;
21706719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
21716719d8e4SJed Brown               if (rdiff > 1) {
21726719d8e4SJed Brown                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr);
21736719d8e4SJed Brown               }
21746719d8e4SJed Brown             }
21756719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
21766719d8e4SJed Brown           }
21776719d8e4SJed Brown           ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
21786719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
21796719d8e4SJed Brown         }
21806719d8e4SJed Brown       }
21814c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
21824c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
21834c30e9fbSJed Brown     }
21844c30e9fbSJed Brown   }
21853a40ed3dSBarry Smith   PetscFunctionReturn(0);
21869b94acceSBarry Smith }
21879b94acceSBarry Smith 
21884a2ae208SSatish Balay #undef __FUNCT__
21894a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
21909b94acceSBarry Smith /*@C
21919b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2192044dda88SLois Curfman McInnes    location to store the matrix.
21939b94acceSBarry Smith 
21943f9fe445SBarry Smith    Logically Collective on SNES and Mat
2195c7afd0dbSLois Curfman McInnes 
21969b94acceSBarry Smith    Input Parameters:
2197c7afd0dbSLois Curfman McInnes +  snes - the SNES context
21989b94acceSBarry Smith .  A - Jacobian matrix
21999b94acceSBarry Smith .  B - preconditioner matrix (usually same as the Jacobian)
2200efd51863SBarry Smith .  func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value)
2201c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
2202efd51863SBarry Smith          Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value)
22039b94acceSBarry Smith 
22049b94acceSBarry Smith    Calling sequence of func:
22058d76a1e5SLois Curfman McInnes $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
22069b94acceSBarry Smith 
2207c7afd0dbSLois Curfman McInnes +  x - input vector
22089b94acceSBarry Smith .  A - Jacobian matrix
22099b94acceSBarry Smith .  B - preconditioner matrix, usually the same as A
2210ac21db08SLois Curfman McInnes .  flag - flag indicating information about the preconditioner matrix
22112b668275SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
2212c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined Jacobian context
22139b94acceSBarry Smith 
22149b94acceSBarry Smith    Notes:
221594b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the flag
22162cd2dfdcSLois Curfman McInnes    output parameter in the routine func().  Be sure to read this information!
2217ac21db08SLois Curfman McInnes 
2218ac21db08SLois Curfman McInnes    The routine func() takes Mat * as the matrix arguments rather than Mat.
22199b94acceSBarry Smith    This allows the Jacobian evaluation routine to replace A and/or B with a
22209b94acceSBarry Smith    completely new new matrix structure (not just different matrix elements)
22219b94acceSBarry Smith    when appropriate, for instance, if the nonzero structure is changing
22229b94acceSBarry Smith    throughout the global iterations.
22239b94acceSBarry Smith 
222416913363SBarry Smith    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
222516913363SBarry Smith    each matrix.
222616913363SBarry Smith 
2227a8a26c1eSJed Brown    If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument
2228a8a26c1eSJed Brown    must be a MatFDColoring.
2229a8a26c1eSJed Brown 
2230c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2231c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2232c3cc8fd1SJed Brown 
223336851e7fSLois Curfman McInnes    Level: beginner
223436851e7fSLois Curfman McInnes 
22359b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
22369b94acceSBarry Smith 
22373ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
22389b94acceSBarry Smith @*/
22397087cfbeSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
22409b94acceSBarry Smith {
2241dfbe8321SBarry Smith   PetscErrorCode ierr;
22426cab3a1bSJed Brown   DM             dm;
22433a7fca6bSBarry Smith 
22443a40ed3dSBarry Smith   PetscFunctionBegin;
22450700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
22460700a824SBarry Smith   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
22470700a824SBarry Smith   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
2248c9780b6fSBarry Smith   if (A) PetscCheckSameComm(snes,1,A,2);
224906975374SJed Brown   if (B) PetscCheckSameComm(snes,1,B,3);
22506cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
22516cab3a1bSJed Brown   ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr);
22523a7fca6bSBarry Smith   if (A) {
22537dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
22546bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
22559b94acceSBarry Smith     snes->jacobian = A;
22563a7fca6bSBarry Smith   }
22573a7fca6bSBarry Smith   if (B) {
22587dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
22596bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
22609b94acceSBarry Smith     snes->jacobian_pre = B;
22613a7fca6bSBarry Smith   }
22623a40ed3dSBarry Smith   PetscFunctionReturn(0);
22639b94acceSBarry Smith }
226462fef451SLois Curfman McInnes 
22654a2ae208SSatish Balay #undef __FUNCT__
22664a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
2267c2aafc4cSSatish Balay /*@C
2268b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2269b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2270b4fd4287SBarry Smith 
2271c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2272c7afd0dbSLois Curfman McInnes 
2273b4fd4287SBarry Smith    Input Parameter:
2274b4fd4287SBarry Smith .  snes - the nonlinear solver context
2275b4fd4287SBarry Smith 
2276b4fd4287SBarry Smith    Output Parameters:
2277c7afd0dbSLois Curfman McInnes +  A - location to stash Jacobian matrix (or PETSC_NULL)
2278b4fd4287SBarry Smith .  B - location to stash preconditioner matrix (or PETSC_NULL)
227970e92668SMatthew Knepley .  func - location to put Jacobian function (or PETSC_NULL)
228070e92668SMatthew Knepley -  ctx - location to stash Jacobian ctx (or PETSC_NULL)
2281fee21e36SBarry Smith 
228236851e7fSLois Curfman McInnes    Level: advanced
228336851e7fSLois Curfman McInnes 
2284b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian()
2285b4fd4287SBarry Smith @*/
22867087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
2287b4fd4287SBarry Smith {
22886cab3a1bSJed Brown   PetscErrorCode ierr;
22896cab3a1bSJed Brown   DM             dm;
22906cab3a1bSJed Brown   SNESDM         sdm;
22916cab3a1bSJed Brown 
22923a40ed3dSBarry Smith   PetscFunctionBegin;
22930700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2294b4fd4287SBarry Smith   if (A)    *A    = snes->jacobian;
2295b4fd4287SBarry Smith   if (B)    *B    = snes->jacobian_pre;
22966cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
22976cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
22986cab3a1bSJed Brown   if (func) *func = sdm->computejacobian;
22996cab3a1bSJed Brown   if (ctx)  *ctx  = sdm->jacobianctx;
23003a40ed3dSBarry Smith   PetscFunctionReturn(0);
2301b4fd4287SBarry Smith }
2302b4fd4287SBarry Smith 
23039b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
23049b94acceSBarry Smith 
23054a2ae208SSatish Balay #undef __FUNCT__
23064a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
23079b94acceSBarry Smith /*@
23089b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
2309272ac6f2SLois Curfman McInnes    of a nonlinear solver.
23109b94acceSBarry Smith 
2311fee21e36SBarry Smith    Collective on SNES
2312fee21e36SBarry Smith 
2313c7afd0dbSLois Curfman McInnes    Input Parameters:
231470e92668SMatthew Knepley .  snes - the SNES context
2315c7afd0dbSLois Curfman McInnes 
2316272ac6f2SLois Curfman McInnes    Notes:
2317272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
2318272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
2319272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
2320272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
2321272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
2322272ac6f2SLois Curfman McInnes 
232336851e7fSLois Curfman McInnes    Level: advanced
232436851e7fSLois Curfman McInnes 
23259b94acceSBarry Smith .keywords: SNES, nonlinear, setup
23269b94acceSBarry Smith 
23279b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
23289b94acceSBarry Smith @*/
23297087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
23309b94acceSBarry Smith {
2331dfbe8321SBarry Smith   PetscErrorCode ierr;
23326cab3a1bSJed Brown   DM             dm;
23336cab3a1bSJed Brown   SNESDM         sdm;
23343a40ed3dSBarry Smith 
23353a40ed3dSBarry Smith   PetscFunctionBegin;
23360700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
23374dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
23389b94acceSBarry Smith 
23397adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
234085385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
234185385478SLisandro Dalcin   }
234285385478SLisandro Dalcin 
2343a63bb30eSJed Brown   ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
234417186662SBarry Smith   if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
234558c9b817SLisandro Dalcin   if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
234658c9b817SLisandro Dalcin 
234758c9b817SLisandro Dalcin   if (!snes->vec_sol_update /* && snes->vec_sol */) {
234858c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
234958c9b817SLisandro Dalcin     ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr);
235058c9b817SLisandro Dalcin   }
235158c9b817SLisandro Dalcin 
23526cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
23536cab3a1bSJed Brown   ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */
23546cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
23556cab3a1bSJed Brown   if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc");
23566cab3a1bSJed Brown   if (!snes->vec_func) {
23576cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2358214df951SJed Brown   }
2359efd51863SBarry Smith 
2360b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
2361b710008aSBarry Smith 
2362f1c6b773SPeter Brune   if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);}
23639e764e56SPeter Brune 
2364d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
2365d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
2366d25893d9SBarry Smith   }
2367d25893d9SBarry Smith 
2368410397dcSLisandro Dalcin   if (snes->ops->setup) {
2369410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2370410397dcSLisandro Dalcin   }
237158c9b817SLisandro Dalcin 
23727aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
23733a40ed3dSBarry Smith   PetscFunctionReturn(0);
23749b94acceSBarry Smith }
23759b94acceSBarry Smith 
23764a2ae208SSatish Balay #undef __FUNCT__
237737596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
237837596af1SLisandro Dalcin /*@
237937596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
238037596af1SLisandro Dalcin 
238137596af1SLisandro Dalcin    Collective on SNES
238237596af1SLisandro Dalcin 
238337596af1SLisandro Dalcin    Input Parameter:
238437596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
238537596af1SLisandro Dalcin 
2386d25893d9SBarry Smith    Level: intermediate
2387d25893d9SBarry Smith 
2388d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
238937596af1SLisandro Dalcin 
239037596af1SLisandro Dalcin .keywords: SNES, destroy
239137596af1SLisandro Dalcin 
239237596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
239337596af1SLisandro Dalcin @*/
239437596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
239537596af1SLisandro Dalcin {
239637596af1SLisandro Dalcin   PetscErrorCode ierr;
239737596af1SLisandro Dalcin 
239837596af1SLisandro Dalcin   PetscFunctionBegin;
239937596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2400d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
2401d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
2402d25893d9SBarry Smith     snes->user = PETSC_NULL;
2403d25893d9SBarry Smith   }
24048a23116dSBarry Smith   if (snes->pc) {
24058a23116dSBarry Smith     ierr = SNESReset(snes->pc);CHKERRQ(ierr);
24068a23116dSBarry Smith   }
24078a23116dSBarry Smith 
240837596af1SLisandro Dalcin   if (snes->ops->reset) {
240937596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
241037596af1SLisandro Dalcin   }
24119e764e56SPeter Brune   if (snes->ksp) {
24129e764e56SPeter Brune     ierr = KSPReset(snes->ksp);CHKERRQ(ierr);
24139e764e56SPeter Brune   }
24149e764e56SPeter Brune 
24159e764e56SPeter Brune   if (snes->linesearch) {
2416f1c6b773SPeter Brune     ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr);
24179e764e56SPeter Brune   }
24189e764e56SPeter Brune 
24196bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
24206bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
24216bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
24226bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
24236bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
24246bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2425c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
2426c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
242737596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
242837596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
242937596af1SLisandro Dalcin   PetscFunctionReturn(0);
243037596af1SLisandro Dalcin }
243137596af1SLisandro Dalcin 
243237596af1SLisandro Dalcin #undef __FUNCT__
24334a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
243452baeb72SSatish Balay /*@
24359b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
24369b94acceSBarry Smith    with SNESCreate().
24379b94acceSBarry Smith 
2438c7afd0dbSLois Curfman McInnes    Collective on SNES
2439c7afd0dbSLois Curfman McInnes 
24409b94acceSBarry Smith    Input Parameter:
24419b94acceSBarry Smith .  snes - the SNES context
24429b94acceSBarry Smith 
244336851e7fSLois Curfman McInnes    Level: beginner
244436851e7fSLois Curfman McInnes 
24459b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
24469b94acceSBarry Smith 
244763a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
24489b94acceSBarry Smith @*/
24496bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
24509b94acceSBarry Smith {
24516849ba73SBarry Smith   PetscErrorCode ierr;
24523a40ed3dSBarry Smith 
24533a40ed3dSBarry Smith   PetscFunctionBegin;
24546bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
24556bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
24566bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2457d4bb536fSBarry Smith 
24586bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
24598a23116dSBarry Smith   ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr);
24606b8b9a38SLisandro Dalcin 
2461be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
24626bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
24636bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
24646d4c513bSLisandro Dalcin 
24656bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
24666bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
2467f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr);
24686b8b9a38SLisandro Dalcin 
24696bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
24706bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
24716bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
24726b8b9a38SLisandro Dalcin   }
24736bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
24746bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
24756bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
247658c9b817SLisandro Dalcin   }
24776bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2478a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
24793a40ed3dSBarry Smith  PetscFunctionReturn(0);
24809b94acceSBarry Smith }
24819b94acceSBarry Smith 
24829b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
24839b94acceSBarry Smith 
24844a2ae208SSatish Balay #undef __FUNCT__
2485a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
2486a8054027SBarry Smith /*@
2487a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2488a8054027SBarry Smith 
24893f9fe445SBarry Smith    Logically Collective on SNES
2490a8054027SBarry Smith 
2491a8054027SBarry Smith    Input Parameters:
2492a8054027SBarry Smith +  snes - the SNES context
2493a8054027SBarry 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
24943b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2495a8054027SBarry Smith 
2496a8054027SBarry Smith    Options Database Keys:
2497a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2498a8054027SBarry Smith 
2499a8054027SBarry Smith    Notes:
2500a8054027SBarry Smith    The default is 1
2501a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2502a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2503a8054027SBarry Smith 
2504a8054027SBarry Smith    Level: intermediate
2505a8054027SBarry Smith 
2506a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2507a8054027SBarry Smith 
2508e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2509a8054027SBarry Smith 
2510a8054027SBarry Smith @*/
25117087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2512a8054027SBarry Smith {
2513a8054027SBarry Smith   PetscFunctionBegin;
25140700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2515e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2516e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2517c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2518a8054027SBarry Smith   snes->lagpreconditioner = lag;
2519a8054027SBarry Smith   PetscFunctionReturn(0);
2520a8054027SBarry Smith }
2521a8054027SBarry Smith 
2522a8054027SBarry Smith #undef __FUNCT__
2523efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
2524efd51863SBarry Smith /*@
2525efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2526efd51863SBarry Smith 
2527efd51863SBarry Smith    Logically Collective on SNES
2528efd51863SBarry Smith 
2529efd51863SBarry Smith    Input Parameters:
2530efd51863SBarry Smith +  snes - the SNES context
2531efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
2532efd51863SBarry Smith 
2533efd51863SBarry Smith    Options Database Keys:
2534efd51863SBarry Smith .    -snes_grid_sequence <steps>
2535efd51863SBarry Smith 
2536efd51863SBarry Smith    Level: intermediate
2537efd51863SBarry Smith 
2538c0df2a02SJed Brown    Notes:
2539c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2540c0df2a02SJed Brown 
2541efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2542efd51863SBarry Smith 
2543efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2544efd51863SBarry Smith 
2545efd51863SBarry Smith @*/
2546efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2547efd51863SBarry Smith {
2548efd51863SBarry Smith   PetscFunctionBegin;
2549efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2550efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
2551efd51863SBarry Smith   snes->gridsequence = steps;
2552efd51863SBarry Smith   PetscFunctionReturn(0);
2553efd51863SBarry Smith }
2554efd51863SBarry Smith 
2555efd51863SBarry Smith #undef __FUNCT__
2556a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
2557a8054027SBarry Smith /*@
2558a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
2559a8054027SBarry Smith 
25603f9fe445SBarry Smith    Not Collective
2561a8054027SBarry Smith 
2562a8054027SBarry Smith    Input Parameter:
2563a8054027SBarry Smith .  snes - the SNES context
2564a8054027SBarry Smith 
2565a8054027SBarry Smith    Output Parameter:
2566a8054027SBarry 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
25673b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2568a8054027SBarry Smith 
2569a8054027SBarry Smith    Options Database Keys:
2570a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2571a8054027SBarry Smith 
2572a8054027SBarry Smith    Notes:
2573a8054027SBarry Smith    The default is 1
2574a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2575a8054027SBarry Smith 
2576a8054027SBarry Smith    Level: intermediate
2577a8054027SBarry Smith 
2578a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2579a8054027SBarry Smith 
2580a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
2581a8054027SBarry Smith 
2582a8054027SBarry Smith @*/
25837087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
2584a8054027SBarry Smith {
2585a8054027SBarry Smith   PetscFunctionBegin;
25860700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2587a8054027SBarry Smith   *lag = snes->lagpreconditioner;
2588a8054027SBarry Smith   PetscFunctionReturn(0);
2589a8054027SBarry Smith }
2590a8054027SBarry Smith 
2591a8054027SBarry Smith #undef __FUNCT__
2592e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
2593e35cf81dSBarry Smith /*@
2594e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
2595e35cf81dSBarry Smith      often the preconditioner is rebuilt.
2596e35cf81dSBarry Smith 
25973f9fe445SBarry Smith    Logically Collective on SNES
2598e35cf81dSBarry Smith 
2599e35cf81dSBarry Smith    Input Parameters:
2600e35cf81dSBarry Smith +  snes - the SNES context
2601e35cf81dSBarry 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
2602fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
2603e35cf81dSBarry Smith 
2604e35cf81dSBarry Smith    Options Database Keys:
2605e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2606e35cf81dSBarry Smith 
2607e35cf81dSBarry Smith    Notes:
2608e35cf81dSBarry Smith    The default is 1
2609e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2610fe3ffe1eSBarry 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
2611fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
2612e35cf81dSBarry Smith 
2613e35cf81dSBarry Smith    Level: intermediate
2614e35cf81dSBarry Smith 
2615e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2616e35cf81dSBarry Smith 
2617e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
2618e35cf81dSBarry Smith 
2619e35cf81dSBarry Smith @*/
26207087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
2621e35cf81dSBarry Smith {
2622e35cf81dSBarry Smith   PetscFunctionBegin;
26230700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2624e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2625e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2626c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2627e35cf81dSBarry Smith   snes->lagjacobian = lag;
2628e35cf81dSBarry Smith   PetscFunctionReturn(0);
2629e35cf81dSBarry Smith }
2630e35cf81dSBarry Smith 
2631e35cf81dSBarry Smith #undef __FUNCT__
2632e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
2633e35cf81dSBarry Smith /*@
2634e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
2635e35cf81dSBarry Smith 
26363f9fe445SBarry Smith    Not Collective
2637e35cf81dSBarry Smith 
2638e35cf81dSBarry Smith    Input Parameter:
2639e35cf81dSBarry Smith .  snes - the SNES context
2640e35cf81dSBarry Smith 
2641e35cf81dSBarry Smith    Output Parameter:
2642e35cf81dSBarry 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
2643e35cf81dSBarry Smith          the Jacobian is built etc.
2644e35cf81dSBarry Smith 
2645e35cf81dSBarry Smith    Options Database Keys:
2646e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2647e35cf81dSBarry Smith 
2648e35cf81dSBarry Smith    Notes:
2649e35cf81dSBarry Smith    The default is 1
2650e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2651e35cf81dSBarry Smith 
2652e35cf81dSBarry Smith    Level: intermediate
2653e35cf81dSBarry Smith 
2654e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2655e35cf81dSBarry Smith 
2656e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
2657e35cf81dSBarry Smith 
2658e35cf81dSBarry Smith @*/
26597087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
2660e35cf81dSBarry Smith {
2661e35cf81dSBarry Smith   PetscFunctionBegin;
26620700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2663e35cf81dSBarry Smith   *lag = snes->lagjacobian;
2664e35cf81dSBarry Smith   PetscFunctionReturn(0);
2665e35cf81dSBarry Smith }
2666e35cf81dSBarry Smith 
2667e35cf81dSBarry Smith #undef __FUNCT__
26684a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
26699b94acceSBarry Smith /*@
2670d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
26719b94acceSBarry Smith 
26723f9fe445SBarry Smith    Logically Collective on SNES
2673c7afd0dbSLois Curfman McInnes 
26749b94acceSBarry Smith    Input Parameters:
2675c7afd0dbSLois Curfman McInnes +  snes - the SNES context
267670441072SBarry Smith .  abstol - absolute convergence tolerance
267733174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
267833174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
267933174efeSLois Curfman McInnes            of the change in the solution between steps
268033174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2681c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2682fee21e36SBarry Smith 
268333174efeSLois Curfman McInnes    Options Database Keys:
268470441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
2685c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
2686c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
2687c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
2688c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
26899b94acceSBarry Smith 
2690d7a720efSLois Curfman McInnes    Notes:
26919b94acceSBarry Smith    The default maximum number of iterations is 50.
26929b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
26939b94acceSBarry Smith 
269436851e7fSLois Curfman McInnes    Level: intermediate
269536851e7fSLois Curfman McInnes 
269633174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
26979b94acceSBarry Smith 
26982492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
26999b94acceSBarry Smith @*/
27007087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
27019b94acceSBarry Smith {
27023a40ed3dSBarry Smith   PetscFunctionBegin;
27030700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2704c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
2705c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
2706c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
2707c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
2708c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
2709c5eb9154SBarry Smith 
2710ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
2711ab54825eSJed Brown     if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol);
2712ab54825eSJed Brown     snes->abstol = abstol;
2713ab54825eSJed Brown   }
2714ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
2715ab54825eSJed 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);
2716ab54825eSJed Brown     snes->rtol = rtol;
2717ab54825eSJed Brown   }
2718ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
2719ab54825eSJed Brown     if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol);
2720c60f73f4SPeter Brune     snes->stol = stol;
2721ab54825eSJed Brown   }
2722ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
2723ab54825eSJed Brown     if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
2724ab54825eSJed Brown     snes->max_its = maxit;
2725ab54825eSJed Brown   }
2726ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
2727ab54825eSJed Brown     if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
2728ab54825eSJed Brown     snes->max_funcs = maxf;
2729ab54825eSJed Brown   }
273088976e71SPeter Brune   snes->tolerancesset = PETSC_TRUE;
27313a40ed3dSBarry Smith   PetscFunctionReturn(0);
27329b94acceSBarry Smith }
27339b94acceSBarry Smith 
27344a2ae208SSatish Balay #undef __FUNCT__
27354a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
27369b94acceSBarry Smith /*@
273733174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
273833174efeSLois Curfman McInnes 
2739c7afd0dbSLois Curfman McInnes    Not Collective
2740c7afd0dbSLois Curfman McInnes 
274133174efeSLois Curfman McInnes    Input Parameters:
2742c7afd0dbSLois Curfman McInnes +  snes - the SNES context
274385385478SLisandro Dalcin .  atol - absolute convergence tolerance
274433174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
274533174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
274633174efeSLois Curfman McInnes            of the change in the solution between steps
274733174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2748c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2749fee21e36SBarry Smith 
275033174efeSLois Curfman McInnes    Notes:
275133174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
275233174efeSLois Curfman McInnes 
275336851e7fSLois Curfman McInnes    Level: intermediate
275436851e7fSLois Curfman McInnes 
275533174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
275633174efeSLois Curfman McInnes 
275733174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
275833174efeSLois Curfman McInnes @*/
27597087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
276033174efeSLois Curfman McInnes {
27613a40ed3dSBarry Smith   PetscFunctionBegin;
27620700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
276385385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
276433174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
2765c60f73f4SPeter Brune   if (stol)  *stol  = snes->stol;
276633174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
276733174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
27683a40ed3dSBarry Smith   PetscFunctionReturn(0);
276933174efeSLois Curfman McInnes }
277033174efeSLois Curfman McInnes 
27714a2ae208SSatish Balay #undef __FUNCT__
27724a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
277333174efeSLois Curfman McInnes /*@
27749b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
27759b94acceSBarry Smith 
27763f9fe445SBarry Smith    Logically Collective on SNES
2777fee21e36SBarry Smith 
2778c7afd0dbSLois Curfman McInnes    Input Parameters:
2779c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2780c7afd0dbSLois Curfman McInnes -  tol - tolerance
2781c7afd0dbSLois Curfman McInnes 
27829b94acceSBarry Smith    Options Database Key:
2783c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
27849b94acceSBarry Smith 
278536851e7fSLois Curfman McInnes    Level: intermediate
278636851e7fSLois Curfman McInnes 
27879b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
27889b94acceSBarry Smith 
27892492ecdbSBarry Smith .seealso: SNESSetTolerances()
27909b94acceSBarry Smith @*/
27917087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
27929b94acceSBarry Smith {
27933a40ed3dSBarry Smith   PetscFunctionBegin;
27940700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2795c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
27969b94acceSBarry Smith   snes->deltatol = tol;
27973a40ed3dSBarry Smith   PetscFunctionReturn(0);
27989b94acceSBarry Smith }
27999b94acceSBarry Smith 
2800df9fa365SBarry Smith /*
2801df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
2802df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
2803df9fa365SBarry Smith    macros instead of functions
2804df9fa365SBarry Smith */
28054a2ae208SSatish Balay #undef __FUNCT__
2806a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
28077087cfbeSBarry Smith PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2808ce1608b8SBarry Smith {
2809dfbe8321SBarry Smith   PetscErrorCode ierr;
2810ce1608b8SBarry Smith 
2811ce1608b8SBarry Smith   PetscFunctionBegin;
28120700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2813a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
2814ce1608b8SBarry Smith   PetscFunctionReturn(0);
2815ce1608b8SBarry Smith }
2816ce1608b8SBarry Smith 
28174a2ae208SSatish Balay #undef __FUNCT__
2818a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
28197087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2820df9fa365SBarry Smith {
2821dfbe8321SBarry Smith   PetscErrorCode ierr;
2822df9fa365SBarry Smith 
2823df9fa365SBarry Smith   PetscFunctionBegin;
2824a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2825df9fa365SBarry Smith   PetscFunctionReturn(0);
2826df9fa365SBarry Smith }
2827df9fa365SBarry Smith 
28284a2ae208SSatish Balay #undef __FUNCT__
2829a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
28306bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
2831df9fa365SBarry Smith {
2832dfbe8321SBarry Smith   PetscErrorCode ierr;
2833df9fa365SBarry Smith 
2834df9fa365SBarry Smith   PetscFunctionBegin;
2835a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2836df9fa365SBarry Smith   PetscFunctionReturn(0);
2837df9fa365SBarry Smith }
2838df9fa365SBarry Smith 
28397087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
2840b271bb04SBarry Smith #undef __FUNCT__
2841b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
28427087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2843b271bb04SBarry Smith {
2844b271bb04SBarry Smith   PetscDrawLG      lg;
2845b271bb04SBarry Smith   PetscErrorCode   ierr;
2846b271bb04SBarry Smith   PetscReal        x,y,per;
2847b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
2848b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
2849b271bb04SBarry Smith   PetscDraw        draw;
2850b271bb04SBarry Smith   PetscFunctionBegin;
2851b271bb04SBarry Smith   if (!monctx) {
2852b271bb04SBarry Smith     MPI_Comm    comm;
2853b271bb04SBarry Smith 
2854b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2855b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
2856b271bb04SBarry Smith   }
2857b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
2858b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2859b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2860b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
2861b271bb04SBarry Smith   x = (PetscReal) n;
2862b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
2863b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2864b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2865b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2866b271bb04SBarry Smith   }
2867b271bb04SBarry Smith 
2868b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
2869b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2870b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2871b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
2872b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
2873b271bb04SBarry Smith   x = (PetscReal) n;
2874b271bb04SBarry Smith   y = 100.0*per;
2875b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2876b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2877b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2878b271bb04SBarry Smith   }
2879b271bb04SBarry Smith 
2880b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
2881b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2882b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2883b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
2884b271bb04SBarry Smith   x = (PetscReal) n;
2885b271bb04SBarry Smith   y = (prev - rnorm)/prev;
2886b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2887b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2888b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2889b271bb04SBarry Smith   }
2890b271bb04SBarry Smith 
2891b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
2892b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2893b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2894b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
2895b271bb04SBarry Smith   x = (PetscReal) n;
2896b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
2897b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
2898b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2899b271bb04SBarry Smith   }
2900b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2901b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2902b271bb04SBarry Smith   }
2903b271bb04SBarry Smith   prev = rnorm;
2904b271bb04SBarry Smith   PetscFunctionReturn(0);
2905b271bb04SBarry Smith }
2906b271bb04SBarry Smith 
2907b271bb04SBarry Smith #undef __FUNCT__
2908b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
29097087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2910b271bb04SBarry Smith {
2911b271bb04SBarry Smith   PetscErrorCode ierr;
2912b271bb04SBarry Smith 
2913b271bb04SBarry Smith   PetscFunctionBegin;
2914b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2915b271bb04SBarry Smith   PetscFunctionReturn(0);
2916b271bb04SBarry Smith }
2917b271bb04SBarry Smith 
2918b271bb04SBarry Smith #undef __FUNCT__
2919b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
29206bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG *draw)
2921b271bb04SBarry Smith {
2922b271bb04SBarry Smith   PetscErrorCode ierr;
2923b271bb04SBarry Smith 
2924b271bb04SBarry Smith   PetscFunctionBegin;
2925b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2926b271bb04SBarry Smith   PetscFunctionReturn(0);
2927b271bb04SBarry Smith }
2928b271bb04SBarry Smith 
29297a03ce2fSLisandro Dalcin #undef __FUNCT__
29307a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
2931228d79bcSJed Brown /*@
2932228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
2933228d79bcSJed Brown 
2934228d79bcSJed Brown    Collective on SNES
2935228d79bcSJed Brown 
2936228d79bcSJed Brown    Input Parameters:
2937228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
2938228d79bcSJed Brown .  iter - iteration number
2939228d79bcSJed Brown -  rnorm - relative norm of the residual
2940228d79bcSJed Brown 
2941228d79bcSJed Brown    Notes:
2942228d79bcSJed Brown    This routine is called by the SNES implementations.
2943228d79bcSJed Brown    It does not typically need to be called by the user.
2944228d79bcSJed Brown 
2945228d79bcSJed Brown    Level: developer
2946228d79bcSJed Brown 
2947228d79bcSJed Brown .seealso: SNESMonitorSet()
2948228d79bcSJed Brown @*/
29497a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
29507a03ce2fSLisandro Dalcin {
29517a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
29527a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
29537a03ce2fSLisandro Dalcin 
29547a03ce2fSLisandro Dalcin   PetscFunctionBegin;
29557a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
29567a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
29577a03ce2fSLisandro Dalcin   }
29587a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
29597a03ce2fSLisandro Dalcin }
29607a03ce2fSLisandro Dalcin 
29619b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
29629b94acceSBarry Smith 
29634a2ae208SSatish Balay #undef __FUNCT__
2964a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
29659b94acceSBarry Smith /*@C
2966a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
29679b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
29689b94acceSBarry Smith    progress.
29699b94acceSBarry Smith 
29703f9fe445SBarry Smith    Logically Collective on SNES
2971fee21e36SBarry Smith 
2972c7afd0dbSLois Curfman McInnes    Input Parameters:
2973c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2974c7afd0dbSLois Curfman McInnes .  func - monitoring routine
2975b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
2976e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
2977b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
2978b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
29799b94acceSBarry Smith 
2980c7afd0dbSLois Curfman McInnes    Calling sequence of func:
2981a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
2982c7afd0dbSLois Curfman McInnes 
2983c7afd0dbSLois Curfman McInnes +    snes - the SNES context
2984c7afd0dbSLois Curfman McInnes .    its - iteration number
2985c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
298640a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
29879b94acceSBarry Smith 
29889665c990SLois Curfman McInnes    Options Database Keys:
2989a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
2990a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
2991a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
2992cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
2993c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
2994a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
2995c7afd0dbSLois Curfman McInnes                             does not cancel those set via
2996c7afd0dbSLois Curfman McInnes                             the options database.
29979665c990SLois Curfman McInnes 
2998639f9d9dSBarry Smith    Notes:
29996bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
3000a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
30016bc08f3fSLois Curfman McInnes    order in which they were set.
3002639f9d9dSBarry Smith 
3003025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
3004025f1a04SBarry Smith 
300536851e7fSLois Curfman McInnes    Level: intermediate
300636851e7fSLois Curfman McInnes 
30079b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
30089b94acceSBarry Smith 
3009a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
30109b94acceSBarry Smith @*/
3011c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
30129b94acceSBarry Smith {
3013b90d0a6eSBarry Smith   PetscInt       i;
3014649052a6SBarry Smith   PetscErrorCode ierr;
3015b90d0a6eSBarry Smith 
30163a40ed3dSBarry Smith   PetscFunctionBegin;
30170700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
301817186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
3019b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
3020649052a6SBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
3021649052a6SBarry Smith       if (monitordestroy) {
3022c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
3023649052a6SBarry Smith       }
3024b90d0a6eSBarry Smith       PetscFunctionReturn(0);
3025b90d0a6eSBarry Smith     }
3026b90d0a6eSBarry Smith   }
3027b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
3028b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
3029639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
30303a40ed3dSBarry Smith   PetscFunctionReturn(0);
30319b94acceSBarry Smith }
30329b94acceSBarry Smith 
30334a2ae208SSatish Balay #undef __FUNCT__
3034a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
30355cd90555SBarry Smith /*@C
3036a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
30375cd90555SBarry Smith 
30383f9fe445SBarry Smith    Logically Collective on SNES
3039c7afd0dbSLois Curfman McInnes 
30405cd90555SBarry Smith    Input Parameters:
30415cd90555SBarry Smith .  snes - the SNES context
30425cd90555SBarry Smith 
30431a480d89SAdministrator    Options Database Key:
3044a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
3045a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
3046c7afd0dbSLois Curfman McInnes     set via the options database
30475cd90555SBarry Smith 
30485cd90555SBarry Smith    Notes:
30495cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
30505cd90555SBarry Smith 
305136851e7fSLois Curfman McInnes    Level: intermediate
305236851e7fSLois Curfman McInnes 
30535cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
30545cd90555SBarry Smith 
3055a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
30565cd90555SBarry Smith @*/
30577087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
30585cd90555SBarry Smith {
3059d952e501SBarry Smith   PetscErrorCode ierr;
3060d952e501SBarry Smith   PetscInt       i;
3061d952e501SBarry Smith 
30625cd90555SBarry Smith   PetscFunctionBegin;
30630700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3064d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
3065d952e501SBarry Smith     if (snes->monitordestroy[i]) {
30663c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
3067d952e501SBarry Smith     }
3068d952e501SBarry Smith   }
30695cd90555SBarry Smith   snes->numbermonitors = 0;
30705cd90555SBarry Smith   PetscFunctionReturn(0);
30715cd90555SBarry Smith }
30725cd90555SBarry Smith 
30734a2ae208SSatish Balay #undef __FUNCT__
30744a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
30759b94acceSBarry Smith /*@C
30769b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
30779b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
30789b94acceSBarry Smith 
30793f9fe445SBarry Smith    Logically Collective on SNES
3080fee21e36SBarry Smith 
3081c7afd0dbSLois Curfman McInnes    Input Parameters:
3082c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3083c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
30847f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
30857f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
30869b94acceSBarry Smith 
3087c7afd0dbSLois Curfman McInnes    Calling sequence of func:
308806ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
3089c7afd0dbSLois Curfman McInnes 
3090c7afd0dbSLois Curfman McInnes +    snes - the SNES context
309106ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
3092c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
3093184914b5SBarry Smith .    reason - reason for convergence/divergence
3094c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
30954b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
30964b27c08aSLois Curfman McInnes -    f - 2-norm of function
30979b94acceSBarry Smith 
309836851e7fSLois Curfman McInnes    Level: advanced
309936851e7fSLois Curfman McInnes 
31009b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
31019b94acceSBarry Smith 
310285385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
31039b94acceSBarry Smith @*/
31047087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
31059b94acceSBarry Smith {
31067f7931b9SBarry Smith   PetscErrorCode ierr;
31077f7931b9SBarry Smith 
31083a40ed3dSBarry Smith   PetscFunctionBegin;
31090700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
311085385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
31117f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
31127f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
31137f7931b9SBarry Smith   }
311485385478SLisandro Dalcin   snes->ops->converged        = func;
31157f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
311685385478SLisandro Dalcin   snes->cnvP                  = cctx;
31173a40ed3dSBarry Smith   PetscFunctionReturn(0);
31189b94acceSBarry Smith }
31199b94acceSBarry Smith 
31204a2ae208SSatish Balay #undef __FUNCT__
31214a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
312252baeb72SSatish Balay /*@
3123184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
3124184914b5SBarry Smith 
3125184914b5SBarry Smith    Not Collective
3126184914b5SBarry Smith 
3127184914b5SBarry Smith    Input Parameter:
3128184914b5SBarry Smith .  snes - the SNES context
3129184914b5SBarry Smith 
3130184914b5SBarry Smith    Output Parameter:
31314d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
3132184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
3133184914b5SBarry Smith 
3134184914b5SBarry Smith    Level: intermediate
3135184914b5SBarry Smith 
3136184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
3137184914b5SBarry Smith 
3138184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
3139184914b5SBarry Smith 
314085385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
3141184914b5SBarry Smith @*/
31427087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
3143184914b5SBarry Smith {
3144184914b5SBarry Smith   PetscFunctionBegin;
31450700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
31464482741eSBarry Smith   PetscValidPointer(reason,2);
3147184914b5SBarry Smith   *reason = snes->reason;
3148184914b5SBarry Smith   PetscFunctionReturn(0);
3149184914b5SBarry Smith }
3150184914b5SBarry Smith 
31514a2ae208SSatish Balay #undef __FUNCT__
31524a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
3153c9005455SLois Curfman McInnes /*@
3154c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
3155c9005455SLois Curfman McInnes 
31563f9fe445SBarry Smith    Logically Collective on SNES
3157fee21e36SBarry Smith 
3158c7afd0dbSLois Curfman McInnes    Input Parameters:
3159c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
31608c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
3161cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
3162758f92a0SBarry Smith .  na  - size of a and its
316364731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
3164758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
3165c7afd0dbSLois Curfman McInnes 
3166308dcc3eSBarry Smith    Notes:
3167308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
3168308dcc3eSBarry Smith    default array of length 10000 is allocated.
3169308dcc3eSBarry Smith 
3170c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
3171c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
3172c9005455SLois Curfman McInnes    during the section of code that is being timed.
3173c9005455SLois Curfman McInnes 
317436851e7fSLois Curfman McInnes    Level: intermediate
317536851e7fSLois Curfman McInnes 
3176c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
3177758f92a0SBarry Smith 
317808405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
3179758f92a0SBarry Smith 
3180c9005455SLois Curfman McInnes @*/
31817087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
3182c9005455SLois Curfman McInnes {
3183308dcc3eSBarry Smith   PetscErrorCode ierr;
3184308dcc3eSBarry Smith 
31853a40ed3dSBarry Smith   PetscFunctionBegin;
31860700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
31874482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
3188a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
3189308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
3190308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
3191308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
3192308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
3193308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
3194308dcc3eSBarry Smith   }
3195c9005455SLois Curfman McInnes   snes->conv_hist       = a;
3196758f92a0SBarry Smith   snes->conv_hist_its   = its;
3197758f92a0SBarry Smith   snes->conv_hist_max   = na;
3198a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
3199758f92a0SBarry Smith   snes->conv_hist_reset = reset;
3200758f92a0SBarry Smith   PetscFunctionReturn(0);
3201758f92a0SBarry Smith }
3202758f92a0SBarry Smith 
3203308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3204c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
3205c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
3206308dcc3eSBarry Smith EXTERN_C_BEGIN
3207308dcc3eSBarry Smith #undef __FUNCT__
3208308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
3209308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
3210308dcc3eSBarry Smith {
3211308dcc3eSBarry Smith   mxArray        *mat;
3212308dcc3eSBarry Smith   PetscInt       i;
3213308dcc3eSBarry Smith   PetscReal      *ar;
3214308dcc3eSBarry Smith 
3215308dcc3eSBarry Smith   PetscFunctionBegin;
3216308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
3217308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
3218308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
3219308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
3220308dcc3eSBarry Smith   }
3221308dcc3eSBarry Smith   PetscFunctionReturn(mat);
3222308dcc3eSBarry Smith }
3223308dcc3eSBarry Smith EXTERN_C_END
3224308dcc3eSBarry Smith #endif
3225308dcc3eSBarry Smith 
3226308dcc3eSBarry Smith 
32274a2ae208SSatish Balay #undef __FUNCT__
32284a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
32290c4c9dddSBarry Smith /*@C
3230758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
3231758f92a0SBarry Smith 
32323f9fe445SBarry Smith    Not Collective
3233758f92a0SBarry Smith 
3234758f92a0SBarry Smith    Input Parameter:
3235758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
3236758f92a0SBarry Smith 
3237758f92a0SBarry Smith    Output Parameters:
3238758f92a0SBarry Smith .  a   - array to hold history
3239758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
3240758f92a0SBarry Smith          negative if not converged) for each solve.
3241758f92a0SBarry Smith -  na  - size of a and its
3242758f92a0SBarry Smith 
3243758f92a0SBarry Smith    Notes:
3244758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
3245758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
3246758f92a0SBarry Smith 
3247758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
3248758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
3249758f92a0SBarry Smith    during the section of code that is being timed.
3250758f92a0SBarry Smith 
3251758f92a0SBarry Smith    Level: intermediate
3252758f92a0SBarry Smith 
3253758f92a0SBarry Smith .keywords: SNES, get, convergence, history
3254758f92a0SBarry Smith 
3255758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
3256758f92a0SBarry Smith 
3257758f92a0SBarry Smith @*/
32587087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3259758f92a0SBarry Smith {
3260758f92a0SBarry Smith   PetscFunctionBegin;
32610700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3262758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
3263758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
3264758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
32653a40ed3dSBarry Smith   PetscFunctionReturn(0);
3266c9005455SLois Curfman McInnes }
3267c9005455SLois Curfman McInnes 
3268e74ef692SMatthew Knepley #undef __FUNCT__
3269e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
3270ac226902SBarry Smith /*@C
327176b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
3272eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
32737e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
327476b2cf59SMatthew Knepley 
32753f9fe445SBarry Smith   Logically Collective on SNES
327676b2cf59SMatthew Knepley 
327776b2cf59SMatthew Knepley   Input Parameters:
327876b2cf59SMatthew Knepley . snes - The nonlinear solver context
327976b2cf59SMatthew Knepley . func - The function
328076b2cf59SMatthew Knepley 
328176b2cf59SMatthew Knepley   Calling sequence of func:
3282b5d30489SBarry Smith . func (SNES snes, PetscInt step);
328376b2cf59SMatthew Knepley 
328476b2cf59SMatthew Knepley . step - The current step of the iteration
328576b2cf59SMatthew Knepley 
3286fe97e370SBarry Smith   Level: advanced
3287fe97e370SBarry Smith 
3288fe97e370SBarry 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()
3289fe97e370SBarry Smith         This is not used by most users.
329076b2cf59SMatthew Knepley 
329176b2cf59SMatthew Knepley .keywords: SNES, update
3292b5d30489SBarry Smith 
329385385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
329476b2cf59SMatthew Knepley @*/
32957087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
329676b2cf59SMatthew Knepley {
329776b2cf59SMatthew Knepley   PetscFunctionBegin;
32980700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
3299e7788613SBarry Smith   snes->ops->update = func;
330076b2cf59SMatthew Knepley   PetscFunctionReturn(0);
330176b2cf59SMatthew Knepley }
330276b2cf59SMatthew Knepley 
3303e74ef692SMatthew Knepley #undef __FUNCT__
3304e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
330576b2cf59SMatthew Knepley /*@
330676b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
330776b2cf59SMatthew Knepley 
330876b2cf59SMatthew Knepley   Not collective
330976b2cf59SMatthew Knepley 
331076b2cf59SMatthew Knepley   Input Parameters:
331176b2cf59SMatthew Knepley . snes - The nonlinear solver context
331276b2cf59SMatthew Knepley . step - The current step of the iteration
331376b2cf59SMatthew Knepley 
3314205452f4SMatthew Knepley   Level: intermediate
3315205452f4SMatthew Knepley 
331676b2cf59SMatthew Knepley .keywords: SNES, update
3317a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
331876b2cf59SMatthew Knepley @*/
33197087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
332076b2cf59SMatthew Knepley {
332176b2cf59SMatthew Knepley   PetscFunctionBegin;
332276b2cf59SMatthew Knepley   PetscFunctionReturn(0);
332376b2cf59SMatthew Knepley }
332476b2cf59SMatthew Knepley 
33254a2ae208SSatish Balay #undef __FUNCT__
33264a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
33279b94acceSBarry Smith /*
33289b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
33299b94acceSBarry Smith    positive parameter delta.
33309b94acceSBarry Smith 
33319b94acceSBarry Smith     Input Parameters:
3332c7afd0dbSLois Curfman McInnes +   snes - the SNES context
33339b94acceSBarry Smith .   y - approximate solution of linear system
33349b94acceSBarry Smith .   fnorm - 2-norm of current function
3335c7afd0dbSLois Curfman McInnes -   delta - trust region size
33369b94acceSBarry Smith 
33379b94acceSBarry Smith     Output Parameters:
3338c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
33399b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
33409b94acceSBarry Smith     region, and exceeds zero otherwise.
3341c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
33429b94acceSBarry Smith 
33439b94acceSBarry Smith     Note:
33444b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
33459b94acceSBarry Smith     is set to be the maximum allowable step size.
33469b94acceSBarry Smith 
33479b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
33489b94acceSBarry Smith */
3349dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
33509b94acceSBarry Smith {
3351064f8208SBarry Smith   PetscReal      nrm;
3352ea709b57SSatish Balay   PetscScalar    cnorm;
3353dfbe8321SBarry Smith   PetscErrorCode ierr;
33543a40ed3dSBarry Smith 
33553a40ed3dSBarry Smith   PetscFunctionBegin;
33560700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
33570700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3358c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
3359184914b5SBarry Smith 
3360064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
3361064f8208SBarry Smith   if (nrm > *delta) {
3362064f8208SBarry Smith      nrm = *delta/nrm;
3363064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
3364064f8208SBarry Smith      cnorm = nrm;
33652dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
33669b94acceSBarry Smith      *ynorm = *delta;
33679b94acceSBarry Smith   } else {
33689b94acceSBarry Smith      *gpnorm = 0.0;
3369064f8208SBarry Smith      *ynorm = nrm;
33709b94acceSBarry Smith   }
33713a40ed3dSBarry Smith   PetscFunctionReturn(0);
33729b94acceSBarry Smith }
33739b94acceSBarry Smith 
33744a2ae208SSatish Balay #undef __FUNCT__
33754a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
33766ce558aeSBarry Smith /*@C
3377f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
3378f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
33799b94acceSBarry Smith 
3380c7afd0dbSLois Curfman McInnes    Collective on SNES
3381c7afd0dbSLois Curfman McInnes 
3382b2002411SLois Curfman McInnes    Input Parameters:
3383c7afd0dbSLois Curfman McInnes +  snes - the SNES context
33843cebf274SJed Brown .  b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero.
338585385478SLisandro Dalcin -  x - the solution vector.
33869b94acceSBarry Smith 
3387b2002411SLois Curfman McInnes    Notes:
33888ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
33898ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
33908ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
33918ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
33928ddd3da0SLois Curfman McInnes 
339336851e7fSLois Curfman McInnes    Level: beginner
339436851e7fSLois Curfman McInnes 
33959b94acceSBarry Smith .keywords: SNES, nonlinear, solve
33969b94acceSBarry Smith 
3397c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
33989b94acceSBarry Smith @*/
33997087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
34009b94acceSBarry Smith {
3401dfbe8321SBarry Smith   PetscErrorCode ierr;
3402ace3abfcSBarry Smith   PetscBool      flg;
3403eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
3404eabae89aSBarry Smith   PetscViewer    viewer;
3405efd51863SBarry Smith   PetscInt       grid;
3406a69afd8bSBarry Smith   Vec            xcreated = PETSC_NULL;
3407caa4e7f2SJed Brown   DM             dm;
3408052efed2SBarry Smith 
34093a40ed3dSBarry Smith   PetscFunctionBegin;
34100700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3411a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3412a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
34130700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
341485385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
341585385478SLisandro Dalcin 
3416caa4e7f2SJed Brown   if (!x) {
3417caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3418caa4e7f2SJed Brown     ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr);
3419a69afd8bSBarry Smith     x    = xcreated;
3420a69afd8bSBarry Smith   }
3421a69afd8bSBarry Smith 
3422a8248277SBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);}
3423efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
3424efd51863SBarry Smith 
342585385478SLisandro Dalcin     /* set solution vector */
3426efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
34276bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
342885385478SLisandro Dalcin     snes->vec_sol = x;
3429caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3430caa4e7f2SJed Brown 
3431caa4e7f2SJed Brown     /* set affine vector if provided */
343285385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
34336bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
343485385478SLisandro Dalcin     snes->vec_rhs = b;
343585385478SLisandro Dalcin 
343670e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
34373f149594SLisandro Dalcin 
34387eee914bSBarry Smith     if (!grid) {
34397eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
3440d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
3441dd568438SSatish Balay       } else if (snes->dm) {
3442dd568438SSatish Balay         PetscBool ig;
3443dd568438SSatish Balay         ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr);
3444dd568438SSatish Balay         if (ig) {
34457eee914bSBarry Smith           ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr);
34467eee914bSBarry Smith         }
3447d25893d9SBarry Smith       }
3448dd568438SSatish Balay     }
3449d25893d9SBarry Smith 
3450abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
345150ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
3452d5e45103SBarry Smith 
34533f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
34544936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
345585385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
34564936397dSBarry Smith     if (snes->domainerror){
34574936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
34584936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
34594936397dSBarry Smith     }
346017186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
34613f149594SLisandro Dalcin 
34627adad957SLisandro Dalcin     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
3463eabae89aSBarry Smith     if (flg && !PetscPreLoadingOn) {
34647adad957SLisandro Dalcin       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
3465eabae89aSBarry Smith       ierr = SNESView(snes,viewer);CHKERRQ(ierr);
34666bf464f9SBarry Smith       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3467eabae89aSBarry Smith     }
3468eabae89aSBarry Smith 
346990d69ab7SBarry Smith     flg  = PETSC_FALSE;
3470acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
3471da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
34725968eb51SBarry Smith     if (snes->printreason) {
3473a8248277SBarry Smith       ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
34745968eb51SBarry Smith       if (snes->reason > 0) {
3475c7e7b494SJed 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);
34765968eb51SBarry Smith       } else {
3477c7e7b494SJed 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);
34785968eb51SBarry Smith       }
3479a8248277SBarry Smith       ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
34805968eb51SBarry Smith     }
34815968eb51SBarry Smith 
34828501fc72SJed Brown     flg = PETSC_FALSE;
34838501fc72SJed Brown     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
34848501fc72SJed Brown     if (flg) {
34858501fc72SJed Brown       PetscViewer viewer;
34868501fc72SJed Brown       ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
34878501fc72SJed Brown       ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr);
34888501fc72SJed Brown       ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr);
34898501fc72SJed Brown       ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr);
34908501fc72SJed Brown       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
34918501fc72SJed Brown     }
34928501fc72SJed Brown 
3493e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
3494efd51863SBarry Smith     if (grid <  snes->gridsequence) {
3495efd51863SBarry Smith       DM  fine;
3496efd51863SBarry Smith       Vec xnew;
3497efd51863SBarry Smith       Mat interp;
3498efd51863SBarry Smith 
3499efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
3500c5c77316SJed Brown       if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
3501e727c939SJed Brown       ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
3502efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
3503efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
3504efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
3505efd51863SBarry Smith       x    = xnew;
3506efd51863SBarry Smith 
3507efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
3508efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
3509efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
3510a8248277SBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);
3511efd51863SBarry Smith     }
3512efd51863SBarry Smith   }
3513a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
35143a40ed3dSBarry Smith   PetscFunctionReturn(0);
35159b94acceSBarry Smith }
35169b94acceSBarry Smith 
35179b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
35189b94acceSBarry Smith 
35194a2ae208SSatish Balay #undef __FUNCT__
35204a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
352182bf6240SBarry Smith /*@C
35224b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
35239b94acceSBarry Smith 
3524fee21e36SBarry Smith    Collective on SNES
3525fee21e36SBarry Smith 
3526c7afd0dbSLois Curfman McInnes    Input Parameters:
3527c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3528454a90a3SBarry Smith -  type - a known method
3529c7afd0dbSLois Curfman McInnes 
3530c7afd0dbSLois Curfman McInnes    Options Database Key:
3531454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
3532c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
3533ae12b187SLois Curfman McInnes 
35349b94acceSBarry Smith    Notes:
3535e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
35364b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
3537c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
35384b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
3539c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
35409b94acceSBarry Smith 
3541ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
3542ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
3543ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
3544ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
3545ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
3546ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
3547ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
3548ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
3549ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
3550b0a32e0cSBarry Smith   appropriate method.
355136851e7fSLois Curfman McInnes 
355236851e7fSLois Curfman McInnes   Level: intermediate
3553a703fe33SLois Curfman McInnes 
3554454a90a3SBarry Smith .keywords: SNES, set, type
3555435da068SBarry Smith 
3556435da068SBarry Smith .seealso: SNESType, SNESCreate()
3557435da068SBarry Smith 
35589b94acceSBarry Smith @*/
35597087cfbeSBarry Smith PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
35609b94acceSBarry Smith {
3561dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
3562ace3abfcSBarry Smith   PetscBool      match;
35633a40ed3dSBarry Smith 
35643a40ed3dSBarry Smith   PetscFunctionBegin;
35650700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35664482741eSBarry Smith   PetscValidCharPointer(type,2);
356782bf6240SBarry Smith 
35686831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
35690f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
357092ff6ae8SBarry Smith 
35714b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
3572e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
357375396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
3574b5c23020SJed Brown   if (snes->ops->destroy) {
3575b5c23020SJed Brown     ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
3576b5c23020SJed Brown     snes->ops->destroy = PETSC_NULL;
3577b5c23020SJed Brown   }
357875396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
357975396ef9SLisandro Dalcin   snes->ops->setup          = 0;
358075396ef9SLisandro Dalcin   snes->ops->solve          = 0;
358175396ef9SLisandro Dalcin   snes->ops->view           = 0;
358275396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
358375396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
358475396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
358575396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
3586454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
358703bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
35889fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
35899fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
35909fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
35919fb22e1aSBarry Smith   }
35929fb22e1aSBarry Smith #endif
35933a40ed3dSBarry Smith   PetscFunctionReturn(0);
35949b94acceSBarry Smith }
35959b94acceSBarry Smith 
3596a847f771SSatish Balay 
35979b94acceSBarry Smith /* --------------------------------------------------------------------- */
35984a2ae208SSatish Balay #undef __FUNCT__
35994a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
360052baeb72SSatish Balay /*@
36019b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
3602f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
36039b94acceSBarry Smith 
3604fee21e36SBarry Smith    Not Collective
3605fee21e36SBarry Smith 
360636851e7fSLois Curfman McInnes    Level: advanced
360736851e7fSLois Curfman McInnes 
36089b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
36099b94acceSBarry Smith 
36109b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
36119b94acceSBarry Smith @*/
36127087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
36139b94acceSBarry Smith {
3614dfbe8321SBarry Smith   PetscErrorCode ierr;
361582bf6240SBarry Smith 
36163a40ed3dSBarry Smith   PetscFunctionBegin;
36171441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
36184c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
36193a40ed3dSBarry Smith   PetscFunctionReturn(0);
36209b94acceSBarry Smith }
36219b94acceSBarry Smith 
36224a2ae208SSatish Balay #undef __FUNCT__
36234a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
36249b94acceSBarry Smith /*@C
36259a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
36269b94acceSBarry Smith 
3627c7afd0dbSLois Curfman McInnes    Not Collective
3628c7afd0dbSLois Curfman McInnes 
36299b94acceSBarry Smith    Input Parameter:
36304b0e389bSBarry Smith .  snes - nonlinear solver context
36319b94acceSBarry Smith 
36329b94acceSBarry Smith    Output Parameter:
36333a7fca6bSBarry Smith .  type - SNES method (a character string)
36349b94acceSBarry Smith 
363536851e7fSLois Curfman McInnes    Level: intermediate
363636851e7fSLois Curfman McInnes 
3637454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
36389b94acceSBarry Smith @*/
36397087cfbeSBarry Smith PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
36409b94acceSBarry Smith {
36413a40ed3dSBarry Smith   PetscFunctionBegin;
36420700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36434482741eSBarry Smith   PetscValidPointer(type,2);
36447adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
36453a40ed3dSBarry Smith   PetscFunctionReturn(0);
36469b94acceSBarry Smith }
36479b94acceSBarry Smith 
36484a2ae208SSatish Balay #undef __FUNCT__
36494a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
365052baeb72SSatish Balay /*@
36519b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
3652c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
36539b94acceSBarry Smith 
3654c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3655c7afd0dbSLois Curfman McInnes 
36569b94acceSBarry Smith    Input Parameter:
36579b94acceSBarry Smith .  snes - the SNES context
36589b94acceSBarry Smith 
36599b94acceSBarry Smith    Output Parameter:
36609b94acceSBarry Smith .  x - the solution
36619b94acceSBarry Smith 
366270e92668SMatthew Knepley    Level: intermediate
366336851e7fSLois Curfman McInnes 
36649b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
36659b94acceSBarry Smith 
366685385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
36679b94acceSBarry Smith @*/
36687087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
36699b94acceSBarry Smith {
36703a40ed3dSBarry Smith   PetscFunctionBegin;
36710700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36724482741eSBarry Smith   PetscValidPointer(x,2);
367385385478SLisandro Dalcin   *x = snes->vec_sol;
367470e92668SMatthew Knepley   PetscFunctionReturn(0);
367570e92668SMatthew Knepley }
367670e92668SMatthew Knepley 
367770e92668SMatthew Knepley #undef __FUNCT__
36784a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
367952baeb72SSatish Balay /*@
36809b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
36819b94acceSBarry Smith    stored.
36829b94acceSBarry Smith 
3683c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3684c7afd0dbSLois Curfman McInnes 
36859b94acceSBarry Smith    Input Parameter:
36869b94acceSBarry Smith .  snes - the SNES context
36879b94acceSBarry Smith 
36889b94acceSBarry Smith    Output Parameter:
36899b94acceSBarry Smith .  x - the solution update
36909b94acceSBarry Smith 
369136851e7fSLois Curfman McInnes    Level: advanced
369236851e7fSLois Curfman McInnes 
36939b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
36949b94acceSBarry Smith 
369585385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
36969b94acceSBarry Smith @*/
36977087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
36989b94acceSBarry Smith {
36993a40ed3dSBarry Smith   PetscFunctionBegin;
37000700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37014482741eSBarry Smith   PetscValidPointer(x,2);
370285385478SLisandro Dalcin   *x = snes->vec_sol_update;
37033a40ed3dSBarry Smith   PetscFunctionReturn(0);
37049b94acceSBarry Smith }
37059b94acceSBarry Smith 
37064a2ae208SSatish Balay #undef __FUNCT__
37074a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
37089b94acceSBarry Smith /*@C
37093638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
37109b94acceSBarry Smith 
3711a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
3712c7afd0dbSLois Curfman McInnes 
37139b94acceSBarry Smith    Input Parameter:
37149b94acceSBarry Smith .  snes - the SNES context
37159b94acceSBarry Smith 
37169b94acceSBarry Smith    Output Parameter:
37177bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
371870e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
371970e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
37209b94acceSBarry Smith 
372136851e7fSLois Curfman McInnes    Level: advanced
372236851e7fSLois Curfman McInnes 
3723a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
37249b94acceSBarry Smith 
37254b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
37269b94acceSBarry Smith @*/
37277087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
37289b94acceSBarry Smith {
3729a63bb30eSJed Brown   PetscErrorCode ierr;
37306cab3a1bSJed Brown   DM             dm;
3731a63bb30eSJed Brown 
37323a40ed3dSBarry Smith   PetscFunctionBegin;
37330700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3734a63bb30eSJed Brown   if (r) {
3735a63bb30eSJed Brown     if (!snes->vec_func) {
3736a63bb30eSJed Brown       if (snes->vec_rhs) {
3737a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
3738a63bb30eSJed Brown       } else if (snes->vec_sol) {
3739a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
3740a63bb30eSJed Brown       } else if (snes->dm) {
3741a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
3742a63bb30eSJed Brown       }
3743a63bb30eSJed Brown     }
3744a63bb30eSJed Brown     *r = snes->vec_func;
3745a63bb30eSJed Brown   }
37466cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
37476cab3a1bSJed Brown   ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr);
37483a40ed3dSBarry Smith   PetscFunctionReturn(0);
37499b94acceSBarry Smith }
37509b94acceSBarry Smith 
3751c79ef259SPeter Brune /*@C
3752c79ef259SPeter Brune    SNESGetGS - Returns the GS function and context.
3753c79ef259SPeter Brune 
3754c79ef259SPeter Brune    Input Parameter:
3755c79ef259SPeter Brune .  snes - the SNES context
3756c79ef259SPeter Brune 
3757c79ef259SPeter Brune    Output Parameter:
3758c79ef259SPeter Brune +  gsfunc - the function (or PETSC_NULL)
3759c79ef259SPeter Brune -  ctx    - the function context (or PETSC_NULL)
3760c79ef259SPeter Brune 
3761c79ef259SPeter Brune    Level: advanced
3762c79ef259SPeter Brune 
3763c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
3764c79ef259SPeter Brune 
3765c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction()
3766c79ef259SPeter Brune @*/
3767c79ef259SPeter Brune 
37684a2ae208SSatish Balay #undef __FUNCT__
3769646217ecSPeter Brune #define __FUNCT__ "SNESGetGS"
3770646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx)
3771646217ecSPeter Brune {
37726cab3a1bSJed Brown   PetscErrorCode ierr;
37736cab3a1bSJed Brown   DM             dm;
37746cab3a1bSJed Brown 
3775646217ecSPeter Brune   PetscFunctionBegin;
3776646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37776cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
37786cab3a1bSJed Brown   ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr);
3779646217ecSPeter Brune   PetscFunctionReturn(0);
3780646217ecSPeter Brune }
3781646217ecSPeter Brune 
37824a2ae208SSatish Balay #undef __FUNCT__
37834a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
37843c7409f5SSatish Balay /*@C
37853c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
3786d850072dSLois Curfman McInnes    SNES options in the database.
37873c7409f5SSatish Balay 
37883f9fe445SBarry Smith    Logically Collective on SNES
3789fee21e36SBarry Smith 
3790c7afd0dbSLois Curfman McInnes    Input Parameter:
3791c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3792c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3793c7afd0dbSLois Curfman McInnes 
3794d850072dSLois Curfman McInnes    Notes:
3795a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3796c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3797d850072dSLois Curfman McInnes 
379836851e7fSLois Curfman McInnes    Level: advanced
379936851e7fSLois Curfman McInnes 
38003c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
3801a86d99e1SLois Curfman McInnes 
3802a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
38033c7409f5SSatish Balay @*/
38047087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
38053c7409f5SSatish Balay {
3806dfbe8321SBarry Smith   PetscErrorCode ierr;
38073c7409f5SSatish Balay 
38083a40ed3dSBarry Smith   PetscFunctionBegin;
38090700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3810639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
38111cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
381294b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
38133a40ed3dSBarry Smith   PetscFunctionReturn(0);
38143c7409f5SSatish Balay }
38153c7409f5SSatish Balay 
38164a2ae208SSatish Balay #undef __FUNCT__
38174a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
38183c7409f5SSatish Balay /*@C
3819f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
3820d850072dSLois Curfman McInnes    SNES options in the database.
38213c7409f5SSatish Balay 
38223f9fe445SBarry Smith    Logically Collective on SNES
3823fee21e36SBarry Smith 
3824c7afd0dbSLois Curfman McInnes    Input Parameters:
3825c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3826c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3827c7afd0dbSLois Curfman McInnes 
3828d850072dSLois Curfman McInnes    Notes:
3829a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3830c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3831d850072dSLois Curfman McInnes 
383236851e7fSLois Curfman McInnes    Level: advanced
383336851e7fSLois Curfman McInnes 
38343c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
3835a86d99e1SLois Curfman McInnes 
3836a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
38373c7409f5SSatish Balay @*/
38387087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
38393c7409f5SSatish Balay {
3840dfbe8321SBarry Smith   PetscErrorCode ierr;
38413c7409f5SSatish Balay 
38423a40ed3dSBarry Smith   PetscFunctionBegin;
38430700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3844639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
38451cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
384694b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
38473a40ed3dSBarry Smith   PetscFunctionReturn(0);
38483c7409f5SSatish Balay }
38493c7409f5SSatish Balay 
38504a2ae208SSatish Balay #undef __FUNCT__
38514a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
38529ab63eb5SSatish Balay /*@C
38533c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
38543c7409f5SSatish Balay    SNES options in the database.
38553c7409f5SSatish Balay 
3856c7afd0dbSLois Curfman McInnes    Not Collective
3857c7afd0dbSLois Curfman McInnes 
38583c7409f5SSatish Balay    Input Parameter:
38593c7409f5SSatish Balay .  snes - the SNES context
38603c7409f5SSatish Balay 
38613c7409f5SSatish Balay    Output Parameter:
38623c7409f5SSatish Balay .  prefix - pointer to the prefix string used
38633c7409f5SSatish Balay 
38644ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
38659ab63eb5SSatish Balay    sufficient length to hold the prefix.
38669ab63eb5SSatish Balay 
386736851e7fSLois Curfman McInnes    Level: advanced
386836851e7fSLois Curfman McInnes 
38693c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
3870a86d99e1SLois Curfman McInnes 
3871a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
38723c7409f5SSatish Balay @*/
38737087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
38743c7409f5SSatish Balay {
3875dfbe8321SBarry Smith   PetscErrorCode ierr;
38763c7409f5SSatish Balay 
38773a40ed3dSBarry Smith   PetscFunctionBegin;
38780700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3879639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
38803a40ed3dSBarry Smith   PetscFunctionReturn(0);
38813c7409f5SSatish Balay }
38823c7409f5SSatish Balay 
3883b2002411SLois Curfman McInnes 
38844a2ae208SSatish Balay #undef __FUNCT__
38854a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
38863cea93caSBarry Smith /*@C
38873cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
38883cea93caSBarry Smith 
38897f6c08e0SMatthew Knepley   Level: advanced
38903cea93caSBarry Smith @*/
38917087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
3892b2002411SLois Curfman McInnes {
3893e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
3894dfbe8321SBarry Smith   PetscErrorCode ierr;
3895b2002411SLois Curfman McInnes 
3896b2002411SLois Curfman McInnes   PetscFunctionBegin;
3897b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3898c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3899b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
3900b2002411SLois Curfman McInnes }
3901da9b6338SBarry Smith 
3902da9b6338SBarry Smith #undef __FUNCT__
3903da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
39047087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
3905da9b6338SBarry Smith {
3906dfbe8321SBarry Smith   PetscErrorCode ierr;
390777431f27SBarry Smith   PetscInt       N,i,j;
3908da9b6338SBarry Smith   Vec            u,uh,fh;
3909da9b6338SBarry Smith   PetscScalar    value;
3910da9b6338SBarry Smith   PetscReal      norm;
3911da9b6338SBarry Smith 
3912da9b6338SBarry Smith   PetscFunctionBegin;
3913da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
3914da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
3915da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
3916da9b6338SBarry Smith 
3917da9b6338SBarry Smith   /* currently only works for sequential */
3918da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
3919da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
3920da9b6338SBarry Smith   for (i=0; i<N; i++) {
3921da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
392277431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
3923da9b6338SBarry Smith     for (j=-10; j<11; j++) {
3924ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
3925da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
39263ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
3927da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
392877431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
3929da9b6338SBarry Smith       value = -value;
3930da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
3931da9b6338SBarry Smith     }
3932da9b6338SBarry Smith   }
39336bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
39346bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
3935da9b6338SBarry Smith   PetscFunctionReturn(0);
3936da9b6338SBarry Smith }
393771f87433Sdalcinl 
393871f87433Sdalcinl #undef __FUNCT__
3939fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
394071f87433Sdalcinl /*@
3941fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
394271f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
394371f87433Sdalcinl    Newton method.
394471f87433Sdalcinl 
39453f9fe445SBarry Smith    Logically Collective on SNES
394671f87433Sdalcinl 
394771f87433Sdalcinl    Input Parameters:
394871f87433Sdalcinl +  snes - SNES context
394971f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
395071f87433Sdalcinl 
395164ba62caSBarry Smith     Options Database:
395264ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
395364ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
395464ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
395564ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
395664ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
395764ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
395864ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
395964ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
396064ba62caSBarry Smith 
396171f87433Sdalcinl    Notes:
396271f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
396371f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
396471f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
396571f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
396671f87433Sdalcinl    solver.
396771f87433Sdalcinl 
396871f87433Sdalcinl    Level: advanced
396971f87433Sdalcinl 
397071f87433Sdalcinl    Reference:
397171f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
397271f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
397371f87433Sdalcinl 
397471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
397571f87433Sdalcinl 
3976fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
397771f87433Sdalcinl @*/
39787087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
397971f87433Sdalcinl {
398071f87433Sdalcinl   PetscFunctionBegin;
39810700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3982acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
398371f87433Sdalcinl   snes->ksp_ewconv = flag;
398471f87433Sdalcinl   PetscFunctionReturn(0);
398571f87433Sdalcinl }
398671f87433Sdalcinl 
398771f87433Sdalcinl #undef __FUNCT__
3988fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
398971f87433Sdalcinl /*@
3990fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
399171f87433Sdalcinl    for computing relative tolerance for linear solvers within an
399271f87433Sdalcinl    inexact Newton method.
399371f87433Sdalcinl 
399471f87433Sdalcinl    Not Collective
399571f87433Sdalcinl 
399671f87433Sdalcinl    Input Parameter:
399771f87433Sdalcinl .  snes - SNES context
399871f87433Sdalcinl 
399971f87433Sdalcinl    Output Parameter:
400071f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
400171f87433Sdalcinl 
400271f87433Sdalcinl    Notes:
400371f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
400471f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
400571f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
400671f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
400771f87433Sdalcinl    solver.
400871f87433Sdalcinl 
400971f87433Sdalcinl    Level: advanced
401071f87433Sdalcinl 
401171f87433Sdalcinl    Reference:
401271f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
401371f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
401471f87433Sdalcinl 
401571f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
401671f87433Sdalcinl 
4017fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
401871f87433Sdalcinl @*/
40197087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
402071f87433Sdalcinl {
402171f87433Sdalcinl   PetscFunctionBegin;
40220700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
402371f87433Sdalcinl   PetscValidPointer(flag,2);
402471f87433Sdalcinl   *flag = snes->ksp_ewconv;
402571f87433Sdalcinl   PetscFunctionReturn(0);
402671f87433Sdalcinl }
402771f87433Sdalcinl 
402871f87433Sdalcinl #undef __FUNCT__
4029fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
403071f87433Sdalcinl /*@
4031fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
403271f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
403371f87433Sdalcinl    Newton method.
403471f87433Sdalcinl 
40353f9fe445SBarry Smith    Logically Collective on SNES
403671f87433Sdalcinl 
403771f87433Sdalcinl    Input Parameters:
403871f87433Sdalcinl +    snes - SNES context
403971f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
404071f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
404171f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
404271f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
404371f87433Sdalcinl              (0 <= gamma2 <= 1)
404471f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
404571f87433Sdalcinl .    alpha2 - power for safeguard
404671f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
404771f87433Sdalcinl 
404871f87433Sdalcinl    Note:
404971f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
405071f87433Sdalcinl 
405171f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
405271f87433Sdalcinl 
405371f87433Sdalcinl    Level: advanced
405471f87433Sdalcinl 
405571f87433Sdalcinl    Reference:
405671f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
405771f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
405871f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
405971f87433Sdalcinl 
406071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
406171f87433Sdalcinl 
4062fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
406371f87433Sdalcinl @*/
40647087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
406571f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
406671f87433Sdalcinl {
4067fa9f3622SBarry Smith   SNESKSPEW *kctx;
406871f87433Sdalcinl   PetscFunctionBegin;
40690700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4070fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4071e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
4072c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
4073c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
4074c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
4075c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
4076c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
4077c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
4078c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
407971f87433Sdalcinl 
408071f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
408171f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
408271f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
408371f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
408471f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
408571f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
408671f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
408771f87433Sdalcinl 
408871f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
4089e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
409071f87433Sdalcinl   }
409171f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
4092e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
409371f87433Sdalcinl   }
409471f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
4095e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
409671f87433Sdalcinl   }
409771f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
4098e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
409971f87433Sdalcinl   }
410071f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
4101e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
410271f87433Sdalcinl   }
410371f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
4104e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
410571f87433Sdalcinl   }
410671f87433Sdalcinl   PetscFunctionReturn(0);
410771f87433Sdalcinl }
410871f87433Sdalcinl 
410971f87433Sdalcinl #undef __FUNCT__
4110fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
411171f87433Sdalcinl /*@
4112fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
411371f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
411471f87433Sdalcinl    Newton method.
411571f87433Sdalcinl 
411671f87433Sdalcinl    Not Collective
411771f87433Sdalcinl 
411871f87433Sdalcinl    Input Parameters:
411971f87433Sdalcinl      snes - SNES context
412071f87433Sdalcinl 
412171f87433Sdalcinl    Output Parameters:
412271f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
412371f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
412471f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
412571f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
412671f87433Sdalcinl              (0 <= gamma2 <= 1)
412771f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
412871f87433Sdalcinl .    alpha2 - power for safeguard
412971f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
413071f87433Sdalcinl 
413171f87433Sdalcinl    Level: advanced
413271f87433Sdalcinl 
413371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
413471f87433Sdalcinl 
4135fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
413671f87433Sdalcinl @*/
41377087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
413871f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
413971f87433Sdalcinl {
4140fa9f3622SBarry Smith   SNESKSPEW *kctx;
414171f87433Sdalcinl   PetscFunctionBegin;
41420700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4143fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4144e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
414571f87433Sdalcinl   if(version)   *version   = kctx->version;
414671f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
414771f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
414871f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
414971f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
415071f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
415171f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
415271f87433Sdalcinl   PetscFunctionReturn(0);
415371f87433Sdalcinl }
415471f87433Sdalcinl 
415571f87433Sdalcinl #undef __FUNCT__
4156fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
4157fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
415871f87433Sdalcinl {
415971f87433Sdalcinl   PetscErrorCode ierr;
4160fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
416171f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
416271f87433Sdalcinl 
416371f87433Sdalcinl   PetscFunctionBegin;
4164e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
416571f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
416671f87433Sdalcinl     rtol = kctx->rtol_0;
416771f87433Sdalcinl   } else {
416871f87433Sdalcinl     if (kctx->version == 1) {
416971f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
417071f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
417171f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
417271f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
417371f87433Sdalcinl     } else if (kctx->version == 2) {
417471f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
417571f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
417671f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
417771f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
417871f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
417971f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
418071f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
418171f87433Sdalcinl       stol = PetscMax(rtol,stol);
418271f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
418371f87433Sdalcinl       /* safeguard: avoid oversolving */
418471f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
418571f87433Sdalcinl       stol = PetscMax(rtol,stol);
418671f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
4187e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
418871f87433Sdalcinl   }
418971f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
419071f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
419171f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
419271f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
419371f87433Sdalcinl   PetscFunctionReturn(0);
419471f87433Sdalcinl }
419571f87433Sdalcinl 
419671f87433Sdalcinl #undef __FUNCT__
4197fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
4198fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
419971f87433Sdalcinl {
420071f87433Sdalcinl   PetscErrorCode ierr;
4201fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
420271f87433Sdalcinl   PCSide         pcside;
420371f87433Sdalcinl   Vec            lres;
420471f87433Sdalcinl 
420571f87433Sdalcinl   PetscFunctionBegin;
4206e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
420771f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
420871f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
420971f87433Sdalcinl   if (kctx->version == 1) {
4210b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
421171f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
421271f87433Sdalcinl       /* KSP residual is true linear residual */
421371f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
421471f87433Sdalcinl     } else {
421571f87433Sdalcinl       /* KSP residual is preconditioned residual */
421671f87433Sdalcinl       /* compute true linear residual norm */
421771f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
421871f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
421971f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
422071f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
42216bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
422271f87433Sdalcinl     }
422371f87433Sdalcinl   }
422471f87433Sdalcinl   PetscFunctionReturn(0);
422571f87433Sdalcinl }
422671f87433Sdalcinl 
422771f87433Sdalcinl #undef __FUNCT__
422871f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
422971f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
423071f87433Sdalcinl {
423171f87433Sdalcinl   PetscErrorCode ierr;
423271f87433Sdalcinl 
423371f87433Sdalcinl   PetscFunctionBegin;
4234fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
423571f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
4236fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
423771f87433Sdalcinl   PetscFunctionReturn(0);
423871f87433Sdalcinl }
42396c699258SBarry Smith 
42406c699258SBarry Smith #undef __FUNCT__
42416c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
42426c699258SBarry Smith /*@
42436c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
42446c699258SBarry Smith 
42453f9fe445SBarry Smith    Logically Collective on SNES
42466c699258SBarry Smith 
42476c699258SBarry Smith    Input Parameters:
42486c699258SBarry Smith +  snes - the preconditioner context
42496c699258SBarry Smith -  dm - the dm
42506c699258SBarry Smith 
42516c699258SBarry Smith    Level: intermediate
42526c699258SBarry Smith 
42536c699258SBarry Smith 
42546c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
42556c699258SBarry Smith @*/
42567087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
42576c699258SBarry Smith {
42586c699258SBarry Smith   PetscErrorCode ierr;
4259345fed2cSBarry Smith   KSP            ksp;
42606cab3a1bSJed Brown   SNESDM         sdm;
42616c699258SBarry Smith 
42626c699258SBarry Smith   PetscFunctionBegin;
42630700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4264d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
42656cab3a1bSJed Brown   if (snes->dm) {               /* Move the SNESDM context over to the new DM unless the new DM already has one */
42666cab3a1bSJed Brown     PetscContainer oldcontainer,container;
42676cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr);
42686cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr);
42696cab3a1bSJed Brown     if (oldcontainer && !container) {
42706cab3a1bSJed Brown       ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr);
42716cab3a1bSJed Brown       ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr);
42726cab3a1bSJed Brown       if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */
42736cab3a1bSJed Brown         sdm->originaldm = dm;
42746cab3a1bSJed Brown       }
42756cab3a1bSJed Brown     }
42766bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
42776cab3a1bSJed Brown   }
42786c699258SBarry Smith   snes->dm = dm;
4279345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4280345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4281f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
42822c155ee1SBarry Smith   if (snes->pc) {
42832c155ee1SBarry Smith     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
42842c155ee1SBarry Smith   }
42856c699258SBarry Smith   PetscFunctionReturn(0);
42866c699258SBarry Smith }
42876c699258SBarry Smith 
42886c699258SBarry Smith #undef __FUNCT__
42896c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
42906c699258SBarry Smith /*@
42916c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
42926c699258SBarry Smith 
42933f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
42946c699258SBarry Smith 
42956c699258SBarry Smith    Input Parameter:
42966c699258SBarry Smith . snes - the preconditioner context
42976c699258SBarry Smith 
42986c699258SBarry Smith    Output Parameter:
42996c699258SBarry Smith .  dm - the dm
43006c699258SBarry Smith 
43016c699258SBarry Smith    Level: intermediate
43026c699258SBarry Smith 
43036c699258SBarry Smith 
43046c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
43056c699258SBarry Smith @*/
43067087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
43076c699258SBarry Smith {
43086cab3a1bSJed Brown   PetscErrorCode ierr;
43096cab3a1bSJed Brown 
43106c699258SBarry Smith   PetscFunctionBegin;
43110700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
43126cab3a1bSJed Brown   if (!snes->dm) {
43136cab3a1bSJed Brown     ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr);
43146cab3a1bSJed Brown   }
43156c699258SBarry Smith   *dm = snes->dm;
43166c699258SBarry Smith   PetscFunctionReturn(0);
43176c699258SBarry Smith }
43180807856dSBarry Smith 
431931823bd8SMatthew G Knepley #undef __FUNCT__
432031823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
432131823bd8SMatthew G Knepley /*@
4322fd4b34e9SJed Brown   SNESSetPC - Sets the nonlinear preconditioner to be used.
432331823bd8SMatthew G Knepley 
432431823bd8SMatthew G Knepley   Collective on SNES
432531823bd8SMatthew G Knepley 
432631823bd8SMatthew G Knepley   Input Parameters:
432731823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
432831823bd8SMatthew G Knepley - pc   - the preconditioner object
432931823bd8SMatthew G Knepley 
433031823bd8SMatthew G Knepley   Notes:
433131823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
433231823bd8SMatthew G Knepley   to configure it using the API).
433331823bd8SMatthew G Knepley 
433431823bd8SMatthew G Knepley   Level: developer
433531823bd8SMatthew G Knepley 
433631823bd8SMatthew G Knepley .keywords: SNES, set, precondition
433731823bd8SMatthew G Knepley .seealso: SNESGetPC()
433831823bd8SMatthew G Knepley @*/
433931823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
434031823bd8SMatthew G Knepley {
434131823bd8SMatthew G Knepley   PetscErrorCode ierr;
434231823bd8SMatthew G Knepley 
434331823bd8SMatthew G Knepley   PetscFunctionBegin;
434431823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
434531823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
434631823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
434731823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4348bf11d3b6SBarry Smith   ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr);
434931823bd8SMatthew G Knepley   snes->pc = pc;
435031823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
435131823bd8SMatthew G Knepley   PetscFunctionReturn(0);
435231823bd8SMatthew G Knepley }
435331823bd8SMatthew G Knepley 
435431823bd8SMatthew G Knepley #undef __FUNCT__
435531823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
435631823bd8SMatthew G Knepley /*@
4357fd4b34e9SJed Brown   SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().
435831823bd8SMatthew G Knepley 
435931823bd8SMatthew G Knepley   Not Collective
436031823bd8SMatthew G Knepley 
436131823bd8SMatthew G Knepley   Input Parameter:
436231823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
436331823bd8SMatthew G Knepley 
436431823bd8SMatthew G Knepley   Output Parameter:
436531823bd8SMatthew G Knepley . pc - preconditioner context
436631823bd8SMatthew G Knepley 
436731823bd8SMatthew G Knepley   Level: developer
436831823bd8SMatthew G Knepley 
436931823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
437031823bd8SMatthew G Knepley .seealso: SNESSetPC()
437131823bd8SMatthew G Knepley @*/
437231823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
437331823bd8SMatthew G Knepley {
437431823bd8SMatthew G Knepley   PetscErrorCode ierr;
437531823bd8SMatthew G Knepley 
437631823bd8SMatthew G Knepley   PetscFunctionBegin;
437731823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
437831823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
437931823bd8SMatthew G Knepley   if (!snes->pc) {
438031823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr);
43814a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr);
438231823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
438331823bd8SMatthew G Knepley   }
438431823bd8SMatthew G Knepley   *pc = snes->pc;
438531823bd8SMatthew G Knepley   PetscFunctionReturn(0);
438631823bd8SMatthew G Knepley }
438731823bd8SMatthew G Knepley 
43889e764e56SPeter Brune #undef __FUNCT__
4389f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch"
43909e764e56SPeter Brune /*@
4391f1c6b773SPeter Brune   SNESSetSNESLineSearch - Sets the linesearch.
43929e764e56SPeter Brune 
43939e764e56SPeter Brune   Collective on SNES
43949e764e56SPeter Brune 
43959e764e56SPeter Brune   Input Parameters:
43969e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
43979e764e56SPeter Brune - linesearch   - the linesearch object
43989e764e56SPeter Brune 
43999e764e56SPeter Brune   Notes:
4400f1c6b773SPeter Brune   Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example,
44019e764e56SPeter Brune   to configure it using the API).
44029e764e56SPeter Brune 
44039e764e56SPeter Brune   Level: developer
44049e764e56SPeter Brune 
44059e764e56SPeter Brune .keywords: SNES, set, linesearch
4406f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch()
44079e764e56SPeter Brune @*/
4408f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch)
44099e764e56SPeter Brune {
44109e764e56SPeter Brune   PetscErrorCode ierr;
44119e764e56SPeter Brune 
44129e764e56SPeter Brune   PetscFunctionBegin;
44139e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4414f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
44159e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
44169e764e56SPeter Brune   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
4417f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
44189e764e56SPeter Brune   snes->linesearch = linesearch;
44199e764e56SPeter Brune   ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
44209e764e56SPeter Brune   PetscFunctionReturn(0);
44219e764e56SPeter Brune }
44229e764e56SPeter Brune 
44239e764e56SPeter Brune #undef __FUNCT__
4424f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch"
4425ea5d4fccSPeter Brune /*@C
4426f1c6b773SPeter Brune   SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch().
44279e764e56SPeter Brune 
44289e764e56SPeter Brune   Not Collective
44299e764e56SPeter Brune 
44309e764e56SPeter Brune   Input Parameter:
44319e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
44329e764e56SPeter Brune 
44339e764e56SPeter Brune   Output Parameter:
44349e764e56SPeter Brune . linesearch - linesearch context
44359e764e56SPeter Brune 
44369e764e56SPeter Brune   Level: developer
44379e764e56SPeter Brune 
44389e764e56SPeter Brune .keywords: SNES, get, linesearch
4439f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch()
44409e764e56SPeter Brune @*/
4441f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch)
44429e764e56SPeter Brune {
44439e764e56SPeter Brune   PetscErrorCode ierr;
44449e764e56SPeter Brune   const char     *optionsprefix;
44459e764e56SPeter Brune 
44469e764e56SPeter Brune   PetscFunctionBegin;
44479e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
44489e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
44499e764e56SPeter Brune   if (!snes->linesearch) {
44509e764e56SPeter Brune     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
4451f1c6b773SPeter Brune     ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr);
4452f1c6b773SPeter Brune     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
4453b1dca40bSPeter Brune     ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr);
44549e764e56SPeter Brune     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
44559e764e56SPeter Brune     ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
44569e764e56SPeter Brune   }
44579e764e56SPeter Brune   *linesearch = snes->linesearch;
44589e764e56SPeter Brune   PetscFunctionReturn(0);
44599e764e56SPeter Brune }
44609e764e56SPeter Brune 
446169b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4462c6db04a5SJed Brown #include <mex.h>
446369b4f73cSBarry Smith 
44648f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
44658f6e6473SBarry Smith 
44660807856dSBarry Smith #undef __FUNCT__
44670807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
44680807856dSBarry Smith /*
44690807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
44700807856dSBarry Smith                          SNESSetFunctionMatlab().
44710807856dSBarry Smith 
44720807856dSBarry Smith    Collective on SNES
44730807856dSBarry Smith 
44740807856dSBarry Smith    Input Parameters:
44750807856dSBarry Smith +  snes - the SNES context
44760807856dSBarry Smith -  x - input vector
44770807856dSBarry Smith 
44780807856dSBarry Smith    Output Parameter:
44790807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
44800807856dSBarry Smith 
44810807856dSBarry Smith    Notes:
44820807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
44830807856dSBarry Smith    implementations, so most users would not generally call this routine
44840807856dSBarry Smith    themselves.
44850807856dSBarry Smith 
44860807856dSBarry Smith    Level: developer
44870807856dSBarry Smith 
44880807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
44890807856dSBarry Smith 
44900807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
449161b2408cSBarry Smith */
44927087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
44930807856dSBarry Smith {
4494e650e774SBarry Smith   PetscErrorCode    ierr;
44958f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
44968f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
44978f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
449891621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
4499e650e774SBarry Smith 
45000807856dSBarry Smith   PetscFunctionBegin;
45010807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
45020807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
45030807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
45040807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
45050807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
45060807856dSBarry Smith 
45070807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
4508e650e774SBarry Smith 
450991621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4510e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4511e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
451291621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
451391621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
451491621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
45158f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
45168f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
4517b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
4518e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4519e650e774SBarry Smith   mxDestroyArray(prhs[0]);
4520e650e774SBarry Smith   mxDestroyArray(prhs[1]);
4521e650e774SBarry Smith   mxDestroyArray(prhs[2]);
45228f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
4523e650e774SBarry Smith   mxDestroyArray(plhs[0]);
45240807856dSBarry Smith   PetscFunctionReturn(0);
45250807856dSBarry Smith }
45260807856dSBarry Smith 
45270807856dSBarry Smith 
45280807856dSBarry Smith #undef __FUNCT__
45290807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
453061b2408cSBarry Smith /*
45310807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
45320807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4533e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
45340807856dSBarry Smith 
45350807856dSBarry Smith    Logically Collective on SNES
45360807856dSBarry Smith 
45370807856dSBarry Smith    Input Parameters:
45380807856dSBarry Smith +  snes - the SNES context
45390807856dSBarry Smith .  r - vector to store function value
45400807856dSBarry Smith -  func - function evaluation routine
45410807856dSBarry Smith 
45420807856dSBarry Smith    Calling sequence of func:
454361b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
45440807856dSBarry Smith 
45450807856dSBarry Smith 
45460807856dSBarry Smith    Notes:
45470807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
45480807856dSBarry Smith $      f'(x) x = -f(x),
45490807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
45500807856dSBarry Smith 
45510807856dSBarry Smith    Level: beginner
45520807856dSBarry Smith 
45530807856dSBarry Smith .keywords: SNES, nonlinear, set, function
45540807856dSBarry Smith 
45550807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
455661b2408cSBarry Smith */
45577087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
45580807856dSBarry Smith {
45590807856dSBarry Smith   PetscErrorCode    ierr;
45608f6e6473SBarry Smith   SNESMatlabContext *sctx;
45610807856dSBarry Smith 
45620807856dSBarry Smith   PetscFunctionBegin;
45638f6e6473SBarry Smith   /* currently sctx is memory bleed */
45648f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
45658f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
45668f6e6473SBarry Smith   /*
45678f6e6473SBarry Smith      This should work, but it doesn't
45688f6e6473SBarry Smith   sctx->ctx = ctx;
45698f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
45708f6e6473SBarry Smith   */
45718f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
45728f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
45730807856dSBarry Smith   PetscFunctionReturn(0);
45740807856dSBarry Smith }
457569b4f73cSBarry Smith 
457661b2408cSBarry Smith #undef __FUNCT__
457761b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
457861b2408cSBarry Smith /*
457961b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
458061b2408cSBarry Smith                          SNESSetJacobianMatlab().
458161b2408cSBarry Smith 
458261b2408cSBarry Smith    Collective on SNES
458361b2408cSBarry Smith 
458461b2408cSBarry Smith    Input Parameters:
458561b2408cSBarry Smith +  snes - the SNES context
458661b2408cSBarry Smith .  x - input vector
458761b2408cSBarry Smith .  A, B - the matrices
458861b2408cSBarry Smith -  ctx - user context
458961b2408cSBarry Smith 
459061b2408cSBarry Smith    Output Parameter:
459161b2408cSBarry Smith .  flag - structure of the matrix
459261b2408cSBarry Smith 
459361b2408cSBarry Smith    Level: developer
459461b2408cSBarry Smith 
459561b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
459661b2408cSBarry Smith 
459761b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
459861b2408cSBarry Smith @*/
45997087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
460061b2408cSBarry Smith {
460161b2408cSBarry Smith   PetscErrorCode    ierr;
460261b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
460361b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
460461b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
460561b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
460661b2408cSBarry Smith 
460761b2408cSBarry Smith   PetscFunctionBegin;
460861b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
460961b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
461061b2408cSBarry Smith 
461161b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
461261b2408cSBarry Smith 
461361b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
461461b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
461561b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
461661b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
461761b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
461861b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
461961b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
462061b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
462161b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
462261b2408cSBarry Smith   prhs[5] =  sctx->ctx;
4623b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
462461b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
462561b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
462661b2408cSBarry Smith   mxDestroyArray(prhs[0]);
462761b2408cSBarry Smith   mxDestroyArray(prhs[1]);
462861b2408cSBarry Smith   mxDestroyArray(prhs[2]);
462961b2408cSBarry Smith   mxDestroyArray(prhs[3]);
463061b2408cSBarry Smith   mxDestroyArray(prhs[4]);
463161b2408cSBarry Smith   mxDestroyArray(plhs[0]);
463261b2408cSBarry Smith   mxDestroyArray(plhs[1]);
463361b2408cSBarry Smith   PetscFunctionReturn(0);
463461b2408cSBarry Smith }
463561b2408cSBarry Smith 
463661b2408cSBarry Smith 
463761b2408cSBarry Smith #undef __FUNCT__
463861b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
463961b2408cSBarry Smith /*
464061b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
464161b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4642e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
464361b2408cSBarry Smith 
464461b2408cSBarry Smith    Logically Collective on SNES
464561b2408cSBarry Smith 
464661b2408cSBarry Smith    Input Parameters:
464761b2408cSBarry Smith +  snes - the SNES context
464861b2408cSBarry Smith .  A,B - Jacobian matrices
464961b2408cSBarry Smith .  func - function evaluation routine
465061b2408cSBarry Smith -  ctx - user context
465161b2408cSBarry Smith 
465261b2408cSBarry Smith    Calling sequence of func:
465361b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
465461b2408cSBarry Smith 
465561b2408cSBarry Smith 
465661b2408cSBarry Smith    Level: developer
465761b2408cSBarry Smith 
465861b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
465961b2408cSBarry Smith 
466061b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
466161b2408cSBarry Smith */
46627087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
466361b2408cSBarry Smith {
466461b2408cSBarry Smith   PetscErrorCode    ierr;
466561b2408cSBarry Smith   SNESMatlabContext *sctx;
466661b2408cSBarry Smith 
466761b2408cSBarry Smith   PetscFunctionBegin;
466861b2408cSBarry Smith   /* currently sctx is memory bleed */
466961b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
467061b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
467161b2408cSBarry Smith   /*
467261b2408cSBarry Smith      This should work, but it doesn't
467361b2408cSBarry Smith   sctx->ctx = ctx;
467461b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
467561b2408cSBarry Smith   */
467661b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
467761b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
467861b2408cSBarry Smith   PetscFunctionReturn(0);
467961b2408cSBarry Smith }
468069b4f73cSBarry Smith 
4681f9eb7ae2SShri Abhyankar #undef __FUNCT__
4682f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
4683f9eb7ae2SShri Abhyankar /*
4684f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
4685f9eb7ae2SShri Abhyankar 
4686f9eb7ae2SShri Abhyankar    Collective on SNES
4687f9eb7ae2SShri Abhyankar 
4688f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
4689f9eb7ae2SShri Abhyankar @*/
46907087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
4691f9eb7ae2SShri Abhyankar {
4692f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
469348f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
4694f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
4695f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
4696f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
4697f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
4698f9eb7ae2SShri Abhyankar 
4699f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4700f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4701f9eb7ae2SShri Abhyankar 
4702f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4703f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4704f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
4705f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
4706f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
4707f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
4708f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
4709f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
4710f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
4711f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4712f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
4713f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
4714f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
4715f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
4716f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
4717f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
4718f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4719f9eb7ae2SShri Abhyankar }
4720f9eb7ae2SShri Abhyankar 
4721f9eb7ae2SShri Abhyankar 
4722f9eb7ae2SShri Abhyankar #undef __FUNCT__
4723f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
4724f9eb7ae2SShri Abhyankar /*
4725e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
4726f9eb7ae2SShri Abhyankar 
4727f9eb7ae2SShri Abhyankar    Level: developer
4728f9eb7ae2SShri Abhyankar 
4729f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
4730f9eb7ae2SShri Abhyankar 
4731f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
4732f9eb7ae2SShri Abhyankar */
47337087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
4734f9eb7ae2SShri Abhyankar {
4735f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
4736f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
4737f9eb7ae2SShri Abhyankar 
4738f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4739f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
4740f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
4741f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4742f9eb7ae2SShri Abhyankar   /*
4743f9eb7ae2SShri Abhyankar      This should work, but it doesn't
4744f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
4745f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
4746f9eb7ae2SShri Abhyankar   */
4747f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
4748f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4749f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4750f9eb7ae2SShri Abhyankar }
4751f9eb7ae2SShri Abhyankar 
475269b4f73cSBarry Smith #endif
4753