xref: /petsc/src/snes/interface/snes.c (revision c60f73f4d12ae23f7a6515fb30c4fbf057680c11)
19b94acceSBarry Smith 
2c6db04a5SJed Brown #include <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",
205*c60f73f4SPeter 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__
341caa4e7f2SJed Brown #define __FUNCT__ "KSPComputeOperators_SNES"
342caa4e7f2SJed Brown static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,MatStructure *mstruct,void *ctx)
343caa4e7f2SJed Brown {
344caa4e7f2SJed Brown   SNES snes = (SNES)ctx;
345caa4e7f2SJed Brown   PetscErrorCode ierr;
346caa4e7f2SJed Brown   Mat Asave = A,Bsave = B;
347caa4e7f2SJed Brown 
348caa4e7f2SJed Brown   PetscFunctionBegin;
349caa4e7f2SJed Brown   ierr = SNESComputeJacobian(snes,snes->vec_sol,&A,&B,mstruct);CHKERRQ(ierr);
350caa4e7f2SJed Brown   if (A != Asave || B != Bsave) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_SUP,"No support for changing matrices at this time");
351caa4e7f2SJed Brown   PetscFunctionReturn(0);
352caa4e7f2SJed Brown }
353caa4e7f2SJed Brown 
354caa4e7f2SJed Brown #undef __FUNCT__
3556cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices"
3566cab3a1bSJed Brown /*@
3576cab3a1bSJed Brown    SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX()
3586cab3a1bSJed Brown 
3596cab3a1bSJed Brown    Collective
3606cab3a1bSJed Brown 
3616cab3a1bSJed Brown    Input Arguments:
3626cab3a1bSJed Brown .  snes - snes to configure
3636cab3a1bSJed Brown 
3646cab3a1bSJed Brown    Level: developer
3656cab3a1bSJed Brown 
3666cab3a1bSJed Brown .seealso: SNESSetUp()
3676cab3a1bSJed Brown @*/
3686cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes)
3696cab3a1bSJed Brown {
3706cab3a1bSJed Brown   PetscErrorCode ierr;
3716cab3a1bSJed Brown   DM             dm;
3726cab3a1bSJed Brown   SNESDM         sdm;
3736cab3a1bSJed Brown 
3746cab3a1bSJed Brown   PetscFunctionBegin;
3756cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3766cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
377caa4e7f2SJed Brown   if (!sdm->computejacobian) {
3786cab3a1bSJed Brown     Mat J,B;
3796cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
3806cab3a1bSJed Brown     if (snes->mf_operator) {
3816cab3a1bSJed Brown       ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
3826cab3a1bSJed Brown       ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
3836cab3a1bSJed Brown       ierr = MatSetFromOptions(J);CHKERRQ(ierr);
3846cab3a1bSJed Brown     } else {
3856cab3a1bSJed Brown       J = B;
3866cab3a1bSJed Brown       ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
3876cab3a1bSJed Brown     }
3886cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr);
3896cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
3906cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
3916cab3a1bSJed Brown   } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) {
3926cab3a1bSJed Brown     Mat J;
3936cab3a1bSJed Brown     void *functx;
3946cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
3956cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
3966cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
3976cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
3986cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
3996cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
400caa4e7f2SJed Brown   } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
4016cab3a1bSJed Brown     Mat J,B;
4026cab3a1bSJed Brown     void *functx;
4036cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4046cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4056cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4066cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4076cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
4086cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,functx);CHKERRQ(ierr);
4096cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
4106cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
411caa4e7f2SJed Brown   } else if (!snes->jacobian_pre) {
4126cab3a1bSJed Brown     Mat J,B;
4136cab3a1bSJed Brown     J = snes->jacobian;
4146cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4156cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
4166cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
4176cab3a1bSJed Brown   }
418caa4e7f2SJed Brown   {
419caa4e7f2SJed Brown     PetscBool flg = PETSC_FALSE;
420caa4e7f2SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_kspcompute",&flg,PETSC_NULL);CHKERRQ(ierr);
421caa4e7f2SJed Brown     if (flg) {                  /* Plan to transition to this model */
422caa4e7f2SJed Brown       KSP ksp;
423caa4e7f2SJed Brown       ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
424caa4e7f2SJed Brown       ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr);
425caa4e7f2SJed Brown     }
426caa4e7f2SJed Brown   }
4276cab3a1bSJed Brown   PetscFunctionReturn(0);
4286cab3a1bSJed Brown }
4296cab3a1bSJed Brown 
4306cab3a1bSJed Brown #undef __FUNCT__
4314a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions"
4329b94acceSBarry Smith /*@
43394b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
4349b94acceSBarry Smith 
435c7afd0dbSLois Curfman McInnes    Collective on SNES
436c7afd0dbSLois Curfman McInnes 
4379b94acceSBarry Smith    Input Parameter:
4389b94acceSBarry Smith .  snes - the SNES context
4399b94acceSBarry Smith 
44036851e7fSLois Curfman McInnes    Options Database Keys:
441ea630c6eSPeter Brune +  -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas
44282738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
44382738288SBarry Smith                 of the change in the solution between steps
44470441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
445b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
446b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
447b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
4484839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
449ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
450a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
451e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
452b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
4532492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
45482738288SBarry Smith                                solver; hence iterations will continue until max_it
4551fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
45682738288SBarry Smith                                of convergence test
457e8105e01SRichard Katz .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
458e8105e01SRichard Katz                                        filename given prints to stdout
459a6570f20SBarry Smith .  -snes_monitor_solution - plots solution at each iteration
460a6570f20SBarry Smith .  -snes_monitor_residual - plots residual (not its norm) at each iteration
461a6570f20SBarry Smith .  -snes_monitor_solution_update - plots update to solution at each iteration
462a6570f20SBarry Smith .  -snes_monitor_draw - plots residual norm at each iteration
463e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
4645968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
465fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
46682738288SBarry Smith 
46782738288SBarry Smith     Options Database for Eisenstat-Walker method:
468fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
4694b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
47036851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
47136851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
47236851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
47336851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
47436851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
47536851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
47682738288SBarry Smith 
47711ca99fdSLois Curfman McInnes    Notes:
47811ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
4790598bfebSBarry Smith    the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>.
48083e2fdc7SBarry Smith 
48136851e7fSLois Curfman McInnes    Level: beginner
48236851e7fSLois Curfman McInnes 
4839b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
4849b94acceSBarry Smith 
48569ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
4869b94acceSBarry Smith @*/
4877087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
4889b94acceSBarry Smith {
489872b6db9SPeter Brune   PetscBool               flg,mf,mf_operator,pcset;
490efd51863SBarry Smith   PetscInt                i,indx,lag,mf_version,grids;
491aa3661deSLisandro Dalcin   MatStructure            matflag;
49285385478SLisandro Dalcin   const char              *deft = SNESLS;
49385385478SLisandro Dalcin   const char              *convtests[] = {"default","skip"};
49485385478SLisandro Dalcin   SNESKSPEW               *kctx = NULL;
495e8105e01SRichard Katz   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
49651e86f29SPeter Brune   const char              *optionsprefix;
497649052a6SBarry Smith   PetscViewer             monviewer;
49885385478SLisandro Dalcin   PetscErrorCode          ierr;
4999b94acceSBarry Smith 
5003a40ed3dSBarry Smith   PetscFunctionBegin;
5010700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
502ca161407SBarry Smith 
503186905e3SBarry Smith   if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
5043194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
5057adad957SLisandro Dalcin     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
506b0a32e0cSBarry Smith     ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
507d64ed03dSBarry Smith     if (flg) {
508186905e3SBarry Smith       ierr = SNESSetType(snes,type);CHKERRQ(ierr);
5097adad957SLisandro Dalcin     } else if (!((PetscObject)snes)->type_name) {
510186905e3SBarry Smith       ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
511d64ed03dSBarry Smith     }
51290d69ab7SBarry Smith     /* not used here, but called so will go into help messaage */
513909c8a9fSBarry Smith     ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr);
51493c39befSBarry Smith 
515*c60f73f4SPeter Brune     ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);CHKERRQ(ierr);
51657034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr);
517186905e3SBarry Smith 
51857034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr);
519b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr);
520b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr);
52150ffb88aSMatthew Knepley     ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr);
522ddf469c8SBarry Smith     ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr);
523acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr);
52485385478SLisandro Dalcin 
525a8054027SBarry Smith     ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
526a8054027SBarry Smith     if (flg) {
527a8054027SBarry Smith       ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
528a8054027SBarry Smith     }
529e35cf81dSBarry Smith     ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
530e35cf81dSBarry Smith     if (flg) {
531e35cf81dSBarry Smith       ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
532e35cf81dSBarry Smith     }
533efd51863SBarry Smith     ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
534efd51863SBarry Smith     if (flg) {
535efd51863SBarry Smith       ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
536efd51863SBarry Smith     }
537a8054027SBarry Smith 
53885385478SLisandro Dalcin     ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
53985385478SLisandro Dalcin     if (flg) {
54085385478SLisandro Dalcin       switch (indx) {
5417f7931b9SBarry Smith       case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break;
5427f7931b9SBarry Smith       case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);    break;
54385385478SLisandro Dalcin       }
54485385478SLisandro Dalcin     }
54585385478SLisandro Dalcin 
546acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr);
547186905e3SBarry Smith 
54885385478SLisandro Dalcin     kctx = (SNESKSPEW *)snes->kspconvctx;
54985385478SLisandro Dalcin 
550acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr);
551186905e3SBarry Smith 
552fa9f3622SBarry Smith     ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr);
553fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr);
554fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr);
555fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr);
556fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr);
557fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr);
558fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr);
559186905e3SBarry Smith 
56090d69ab7SBarry Smith     flg  = PETSC_FALSE;
561acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
562a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
563eabae89aSBarry Smith 
564a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
565e8105e01SRichard Katz     if (flg) {
566649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
567649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
568e8105e01SRichard Katz     }
569eabae89aSBarry Smith 
570b271bb04SBarry Smith     ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
571b271bb04SBarry Smith     if (flg) {
572b271bb04SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr);
573b271bb04SBarry Smith     }
574b271bb04SBarry Smith 
575a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
576eabae89aSBarry Smith     if (flg) {
577649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
578f1bef1bcSMatthew Knepley       ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr);
579e8105e01SRichard Katz     }
580eabae89aSBarry Smith 
581a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
582eabae89aSBarry Smith     if (flg) {
583649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
584649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
585eabae89aSBarry Smith     }
586eabae89aSBarry Smith 
5875180491cSLisandro Dalcin     ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
5885180491cSLisandro Dalcin     if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);}
5895180491cSLisandro Dalcin 
59090d69ab7SBarry Smith     flg  = PETSC_FALSE;
591acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
592a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
59390d69ab7SBarry Smith     flg  = PETSC_FALSE;
594acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
595a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
59690d69ab7SBarry Smith     flg  = PETSC_FALSE;
597acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
598a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
59990d69ab7SBarry Smith     flg  = PETSC_FALSE;
600acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
601a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
60290d69ab7SBarry Smith     flg  = PETSC_FALSE;
603acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
604b271bb04SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
605e24b481bSBarry Smith 
60690d69ab7SBarry Smith     flg  = PETSC_FALSE;
607acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
6084b27c08aSLois Curfman McInnes     if (flg) {
6096cab3a1bSJed Brown       void *functx;
6106cab3a1bSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
6116cab3a1bSJed Brown       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr);
612ae15b995SBarry Smith       ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
6139b94acceSBarry Smith     }
614639f9d9dSBarry Smith 
615aa3661deSLisandro Dalcin     mf = mf_operator = PETSC_FALSE;
616aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
617acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr);
618a8248277SBarry Smith     if (flg && mf_operator) {
619a8248277SBarry Smith       snes->mf_operator = PETSC_TRUE;
620a8248277SBarry Smith       mf = PETSC_TRUE;
621a8248277SBarry Smith     }
622aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
623acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr);
624aa3661deSLisandro Dalcin     if (!flg && mf_operator) mf = PETSC_TRUE;
625aa3661deSLisandro Dalcin     mf_version = 1;
626aa3661deSLisandro Dalcin     ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr);
627aa3661deSLisandro Dalcin 
628d28543b3SPeter Brune 
62989b92e6fSPeter Brune     /* GS Options */
63089b92e6fSPeter Brune     ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr);
63189b92e6fSPeter Brune 
63276b2cf59SMatthew Knepley     for(i = 0; i < numberofsetfromoptions; i++) {
63376b2cf59SMatthew Knepley       ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
63476b2cf59SMatthew Knepley     }
63576b2cf59SMatthew Knepley 
636e7788613SBarry Smith     if (snes->ops->setfromoptions) {
637e7788613SBarry Smith       ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr);
638639f9d9dSBarry Smith     }
6395d973c19SBarry Smith 
6405d973c19SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
6415d973c19SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr);
642b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
6434bbc92c1SBarry Smith 
644aa3661deSLisandro Dalcin   if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); }
6451cee3971SBarry Smith 
6461cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
647aa3661deSLisandro Dalcin   ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
648aa3661deSLisandro Dalcin   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr);
64985385478SLisandro Dalcin   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
65093993e2dSLois Curfman McInnes 
6519e764e56SPeter Brune   if (!snes->linesearch) {
652f1c6b773SPeter Brune     ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
6539e764e56SPeter Brune   }
654f1c6b773SPeter Brune   ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr);
6559e764e56SPeter Brune 
65651e86f29SPeter Brune   /* if someone has set the SNES PC type, create it. */
65751e86f29SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
65851e86f29SPeter Brune   ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr);
65951e86f29SPeter Brune   if (pcset && (!snes->pc)) {
66051e86f29SPeter Brune     ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr);
66151e86f29SPeter Brune   }
6624a0c5b0cSMatthew G Knepley   if (snes->pc) {
663fde0ff24SPeter Brune     ierr = SNESSetOptionsPrefix(snes->pc, optionsprefix);CHKERRQ(ierr);
664fde0ff24SPeter Brune     ierr = SNESAppendOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr);
6654a0c5b0cSMatthew G Knepley     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
6664a0c5b0cSMatthew G Knepley     ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr);
6674a0c5b0cSMatthew G Knepley   }
6683a40ed3dSBarry Smith   PetscFunctionReturn(0);
6699b94acceSBarry Smith }
6709b94acceSBarry Smith 
671d25893d9SBarry Smith #undef __FUNCT__
672d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext"
673d25893d9SBarry Smith /*@
674d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
675d25893d9SBarry Smith    the nonlinear solvers.
676d25893d9SBarry Smith 
677d25893d9SBarry Smith    Logically Collective on SNES
678d25893d9SBarry Smith 
679d25893d9SBarry Smith    Input Parameters:
680d25893d9SBarry Smith +  snes - the SNES context
681d25893d9SBarry Smith .  compute - function to compute the context
682d25893d9SBarry Smith -  destroy - function to destroy the context
683d25893d9SBarry Smith 
684d25893d9SBarry Smith    Level: intermediate
685d25893d9SBarry Smith 
686d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
687d25893d9SBarry Smith 
688d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
689d25893d9SBarry Smith @*/
690d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
691d25893d9SBarry Smith {
692d25893d9SBarry Smith   PetscFunctionBegin;
693d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
694d25893d9SBarry Smith   snes->ops->usercompute = compute;
695d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
696d25893d9SBarry Smith   PetscFunctionReturn(0);
697d25893d9SBarry Smith }
698a847f771SSatish Balay 
6994a2ae208SSatish Balay #undef __FUNCT__
7004a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
701b07ff414SBarry Smith /*@
7029b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
7039b94acceSBarry Smith    the nonlinear solvers.
7049b94acceSBarry Smith 
7053f9fe445SBarry Smith    Logically Collective on SNES
706fee21e36SBarry Smith 
707c7afd0dbSLois Curfman McInnes    Input Parameters:
708c7afd0dbSLois Curfman McInnes +  snes - the SNES context
709c7afd0dbSLois Curfman McInnes -  usrP - optional user context
710c7afd0dbSLois Curfman McInnes 
71136851e7fSLois Curfman McInnes    Level: intermediate
71236851e7fSLois Curfman McInnes 
7139b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
7149b94acceSBarry Smith 
715d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext()
7169b94acceSBarry Smith @*/
7177087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
7189b94acceSBarry Smith {
7191b2093e4SBarry Smith   PetscErrorCode ierr;
720b07ff414SBarry Smith   KSP            ksp;
7211b2093e4SBarry Smith 
7223a40ed3dSBarry Smith   PetscFunctionBegin;
7230700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
724b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
725b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
7269b94acceSBarry Smith   snes->user = usrP;
7273a40ed3dSBarry Smith   PetscFunctionReturn(0);
7289b94acceSBarry Smith }
72974679c65SBarry Smith 
7304a2ae208SSatish Balay #undef __FUNCT__
7314a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
732b07ff414SBarry Smith /*@
7339b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
7349b94acceSBarry Smith    nonlinear solvers.
7359b94acceSBarry Smith 
736c7afd0dbSLois Curfman McInnes    Not Collective
737c7afd0dbSLois Curfman McInnes 
7389b94acceSBarry Smith    Input Parameter:
7399b94acceSBarry Smith .  snes - SNES context
7409b94acceSBarry Smith 
7419b94acceSBarry Smith    Output Parameter:
7429b94acceSBarry Smith .  usrP - user context
7439b94acceSBarry Smith 
74436851e7fSLois Curfman McInnes    Level: intermediate
74536851e7fSLois Curfman McInnes 
7469b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
7479b94acceSBarry Smith 
7489b94acceSBarry Smith .seealso: SNESSetApplicationContext()
7499b94acceSBarry Smith @*/
750e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
7519b94acceSBarry Smith {
7523a40ed3dSBarry Smith   PetscFunctionBegin;
7530700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
754e71120c6SJed Brown   *(void**)usrP = snes->user;
7553a40ed3dSBarry Smith   PetscFunctionReturn(0);
7569b94acceSBarry Smith }
75774679c65SBarry Smith 
7584a2ae208SSatish Balay #undef __FUNCT__
7594a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
7609b94acceSBarry Smith /*@
761c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
762c8228a4eSBarry Smith    at this time.
7639b94acceSBarry Smith 
764c7afd0dbSLois Curfman McInnes    Not Collective
765c7afd0dbSLois Curfman McInnes 
7669b94acceSBarry Smith    Input Parameter:
7679b94acceSBarry Smith .  snes - SNES context
7689b94acceSBarry Smith 
7699b94acceSBarry Smith    Output Parameter:
7709b94acceSBarry Smith .  iter - iteration number
7719b94acceSBarry Smith 
772c8228a4eSBarry Smith    Notes:
773c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
774c8228a4eSBarry Smith 
775c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
77608405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
77708405cd6SLois Curfman McInnes .vb
77808405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
77908405cd6SLois Curfman McInnes       if (!(it % 2)) {
78008405cd6SLois Curfman McInnes         [compute Jacobian here]
78108405cd6SLois Curfman McInnes       }
78208405cd6SLois Curfman McInnes .ve
783c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
78408405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
785c8228a4eSBarry Smith 
78636851e7fSLois Curfman McInnes    Level: intermediate
78736851e7fSLois Curfman McInnes 
7882b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
7892b668275SBarry Smith 
790b850b91aSLisandro Dalcin .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
7919b94acceSBarry Smith @*/
7927087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
7939b94acceSBarry Smith {
7943a40ed3dSBarry Smith   PetscFunctionBegin;
7950700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7964482741eSBarry Smith   PetscValidIntPointer(iter,2);
7979b94acceSBarry Smith   *iter = snes->iter;
7983a40ed3dSBarry Smith   PetscFunctionReturn(0);
7999b94acceSBarry Smith }
80074679c65SBarry Smith 
8014a2ae208SSatish Balay #undef __FUNCT__
802360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber"
803360c497dSPeter Brune /*@
804360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
805360c497dSPeter Brune 
806360c497dSPeter Brune    Not Collective
807360c497dSPeter Brune 
808360c497dSPeter Brune    Input Parameter:
809360c497dSPeter Brune .  snes - SNES context
810360c497dSPeter Brune .  iter - iteration number
811360c497dSPeter Brune 
812360c497dSPeter Brune    Level: developer
813360c497dSPeter Brune 
814360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number,
815360c497dSPeter Brune 
816360c497dSPeter Brune .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
817360c497dSPeter Brune @*/
818360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
819360c497dSPeter Brune {
820360c497dSPeter Brune   PetscErrorCode ierr;
821360c497dSPeter Brune 
822360c497dSPeter Brune   PetscFunctionBegin;
823360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
824360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
825360c497dSPeter Brune   snes->iter = iter;
826360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
827360c497dSPeter Brune   PetscFunctionReturn(0);
828360c497dSPeter Brune }
829360c497dSPeter Brune 
830360c497dSPeter Brune #undef __FUNCT__
8314a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm"
8329b94acceSBarry Smith /*@
8339b94acceSBarry Smith    SNESGetFunctionNorm - Gets the norm of the current function that was set
8349b94acceSBarry Smith    with SNESSSetFunction().
8359b94acceSBarry Smith 
836c7afd0dbSLois Curfman McInnes    Collective on SNES
837c7afd0dbSLois Curfman McInnes 
8389b94acceSBarry Smith    Input Parameter:
8399b94acceSBarry Smith .  snes - SNES context
8409b94acceSBarry Smith 
8419b94acceSBarry Smith    Output Parameter:
8429b94acceSBarry Smith .  fnorm - 2-norm of function
8439b94acceSBarry Smith 
84436851e7fSLois Curfman McInnes    Level: intermediate
84536851e7fSLois Curfman McInnes 
8469b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm
847a86d99e1SLois Curfman McInnes 
848b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
8499b94acceSBarry Smith @*/
8507087cfbeSBarry Smith PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
8519b94acceSBarry Smith {
8523a40ed3dSBarry Smith   PetscFunctionBegin;
8530700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8544482741eSBarry Smith   PetscValidScalarPointer(fnorm,2);
8559b94acceSBarry Smith   *fnorm = snes->norm;
8563a40ed3dSBarry Smith   PetscFunctionReturn(0);
8579b94acceSBarry Smith }
85874679c65SBarry Smith 
859360c497dSPeter Brune 
860360c497dSPeter Brune #undef __FUNCT__
861360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm"
862360c497dSPeter Brune /*@
863360c497dSPeter Brune    SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm().
864360c497dSPeter Brune 
865360c497dSPeter Brune    Collective on SNES
866360c497dSPeter Brune 
867360c497dSPeter Brune    Input Parameter:
868360c497dSPeter Brune .  snes - SNES context
869360c497dSPeter Brune .  fnorm - 2-norm of function
870360c497dSPeter Brune 
871360c497dSPeter Brune    Level: developer
872360c497dSPeter Brune 
873360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm
874360c497dSPeter Brune 
875360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm().
876360c497dSPeter Brune @*/
877360c497dSPeter Brune PetscErrorCode  SNESSetFunctionNorm(SNES snes,PetscReal fnorm)
878360c497dSPeter Brune {
879360c497dSPeter Brune 
880360c497dSPeter Brune   PetscErrorCode ierr;
881360c497dSPeter Brune 
882360c497dSPeter Brune   PetscFunctionBegin;
883360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
884360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
885360c497dSPeter Brune   snes->norm = fnorm;
886360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
887360c497dSPeter Brune   PetscFunctionReturn(0);
888360c497dSPeter Brune }
889360c497dSPeter Brune 
8904a2ae208SSatish Balay #undef __FUNCT__
891b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
8929b94acceSBarry Smith /*@
893b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
8949b94acceSBarry Smith    attempted by the nonlinear solver.
8959b94acceSBarry Smith 
896c7afd0dbSLois Curfman McInnes    Not Collective
897c7afd0dbSLois Curfman McInnes 
8989b94acceSBarry Smith    Input Parameter:
8999b94acceSBarry Smith .  snes - SNES context
9009b94acceSBarry Smith 
9019b94acceSBarry Smith    Output Parameter:
9029b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
9039b94acceSBarry Smith 
904c96a6f78SLois Curfman McInnes    Notes:
905c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
906c96a6f78SLois Curfman McInnes 
90736851e7fSLois Curfman McInnes    Level: intermediate
90836851e7fSLois Curfman McInnes 
9099b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
91058ebbce7SBarry Smith 
911e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
91258ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
9139b94acceSBarry Smith @*/
9147087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
9159b94acceSBarry Smith {
9163a40ed3dSBarry Smith   PetscFunctionBegin;
9170700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9184482741eSBarry Smith   PetscValidIntPointer(nfails,2);
91950ffb88aSMatthew Knepley   *nfails = snes->numFailures;
92050ffb88aSMatthew Knepley   PetscFunctionReturn(0);
92150ffb88aSMatthew Knepley }
92250ffb88aSMatthew Knepley 
92350ffb88aSMatthew Knepley #undef __FUNCT__
924b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
92550ffb88aSMatthew Knepley /*@
926b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
92750ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
92850ffb88aSMatthew Knepley 
92950ffb88aSMatthew Knepley    Not Collective
93050ffb88aSMatthew Knepley 
93150ffb88aSMatthew Knepley    Input Parameters:
93250ffb88aSMatthew Knepley +  snes     - SNES context
93350ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
93450ffb88aSMatthew Knepley 
93550ffb88aSMatthew Knepley    Level: intermediate
93650ffb88aSMatthew Knepley 
93750ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
93858ebbce7SBarry Smith 
939e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
94058ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
94150ffb88aSMatthew Knepley @*/
9427087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
94350ffb88aSMatthew Knepley {
94450ffb88aSMatthew Knepley   PetscFunctionBegin;
9450700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
94650ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
94750ffb88aSMatthew Knepley   PetscFunctionReturn(0);
94850ffb88aSMatthew Knepley }
94950ffb88aSMatthew Knepley 
95050ffb88aSMatthew Knepley #undef __FUNCT__
951b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
95250ffb88aSMatthew Knepley /*@
953b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
95450ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
95550ffb88aSMatthew Knepley 
95650ffb88aSMatthew Knepley    Not Collective
95750ffb88aSMatthew Knepley 
95850ffb88aSMatthew Knepley    Input Parameter:
95950ffb88aSMatthew Knepley .  snes     - SNES context
96050ffb88aSMatthew Knepley 
96150ffb88aSMatthew Knepley    Output Parameter:
96250ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
96350ffb88aSMatthew Knepley 
96450ffb88aSMatthew Knepley    Level: intermediate
96550ffb88aSMatthew Knepley 
96650ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
96758ebbce7SBarry Smith 
968e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
96958ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
97058ebbce7SBarry Smith 
97150ffb88aSMatthew Knepley @*/
9727087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
97350ffb88aSMatthew Knepley {
97450ffb88aSMatthew Knepley   PetscFunctionBegin;
9750700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9764482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
97750ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
9783a40ed3dSBarry Smith   PetscFunctionReturn(0);
9799b94acceSBarry Smith }
980a847f771SSatish Balay 
9814a2ae208SSatish Balay #undef __FUNCT__
9822541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
9832541af92SBarry Smith /*@
9842541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
9852541af92SBarry Smith      done by SNES.
9862541af92SBarry Smith 
9872541af92SBarry Smith    Not Collective
9882541af92SBarry Smith 
9892541af92SBarry Smith    Input Parameter:
9902541af92SBarry Smith .  snes     - SNES context
9912541af92SBarry Smith 
9922541af92SBarry Smith    Output Parameter:
9932541af92SBarry Smith .  nfuncs - number of evaluations
9942541af92SBarry Smith 
9952541af92SBarry Smith    Level: intermediate
9962541af92SBarry Smith 
9972541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
99858ebbce7SBarry Smith 
999e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
10002541af92SBarry Smith @*/
10017087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
10022541af92SBarry Smith {
10032541af92SBarry Smith   PetscFunctionBegin;
10040700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10052541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
10062541af92SBarry Smith   *nfuncs = snes->nfuncs;
10072541af92SBarry Smith   PetscFunctionReturn(0);
10082541af92SBarry Smith }
10092541af92SBarry Smith 
10102541af92SBarry Smith #undef __FUNCT__
10113d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
10123d4c4710SBarry Smith /*@
10133d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
10143d4c4710SBarry Smith    linear solvers.
10153d4c4710SBarry Smith 
10163d4c4710SBarry Smith    Not Collective
10173d4c4710SBarry Smith 
10183d4c4710SBarry Smith    Input Parameter:
10193d4c4710SBarry Smith .  snes - SNES context
10203d4c4710SBarry Smith 
10213d4c4710SBarry Smith    Output Parameter:
10223d4c4710SBarry Smith .  nfails - number of failed solves
10233d4c4710SBarry Smith 
10243d4c4710SBarry Smith    Notes:
10253d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
10263d4c4710SBarry Smith 
10273d4c4710SBarry Smith    Level: intermediate
10283d4c4710SBarry Smith 
10293d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
103058ebbce7SBarry Smith 
1031e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
10323d4c4710SBarry Smith @*/
10337087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
10343d4c4710SBarry Smith {
10353d4c4710SBarry Smith   PetscFunctionBegin;
10360700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10373d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
10383d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
10393d4c4710SBarry Smith   PetscFunctionReturn(0);
10403d4c4710SBarry Smith }
10413d4c4710SBarry Smith 
10423d4c4710SBarry Smith #undef __FUNCT__
10433d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
10443d4c4710SBarry Smith /*@
10453d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
10463d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
10473d4c4710SBarry Smith 
10483f9fe445SBarry Smith    Logically Collective on SNES
10493d4c4710SBarry Smith 
10503d4c4710SBarry Smith    Input Parameters:
10513d4c4710SBarry Smith +  snes     - SNES context
10523d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
10533d4c4710SBarry Smith 
10543d4c4710SBarry Smith    Level: intermediate
10553d4c4710SBarry Smith 
1056a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
10573d4c4710SBarry Smith 
10583d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
10593d4c4710SBarry Smith 
106058ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
10613d4c4710SBarry Smith @*/
10627087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
10633d4c4710SBarry Smith {
10643d4c4710SBarry Smith   PetscFunctionBegin;
10650700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1066c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
10673d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
10683d4c4710SBarry Smith   PetscFunctionReturn(0);
10693d4c4710SBarry Smith }
10703d4c4710SBarry Smith 
10713d4c4710SBarry Smith #undef __FUNCT__
10723d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
10733d4c4710SBarry Smith /*@
10743d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
10753d4c4710SBarry Smith      are allowed before SNES terminates
10763d4c4710SBarry Smith 
10773d4c4710SBarry Smith    Not Collective
10783d4c4710SBarry Smith 
10793d4c4710SBarry Smith    Input Parameter:
10803d4c4710SBarry Smith .  snes     - SNES context
10813d4c4710SBarry Smith 
10823d4c4710SBarry Smith    Output Parameter:
10833d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
10843d4c4710SBarry Smith 
10853d4c4710SBarry Smith    Level: intermediate
10863d4c4710SBarry Smith 
10873d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
10883d4c4710SBarry Smith 
10893d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
10903d4c4710SBarry Smith 
1091e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
10923d4c4710SBarry Smith @*/
10937087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
10943d4c4710SBarry Smith {
10953d4c4710SBarry Smith   PetscFunctionBegin;
10960700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10973d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
10983d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
10993d4c4710SBarry Smith   PetscFunctionReturn(0);
11003d4c4710SBarry Smith }
11013d4c4710SBarry Smith 
11023d4c4710SBarry Smith #undef __FUNCT__
1103b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
1104c96a6f78SLois Curfman McInnes /*@
1105b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1106c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1107c96a6f78SLois Curfman McInnes 
1108c7afd0dbSLois Curfman McInnes    Not Collective
1109c7afd0dbSLois Curfman McInnes 
1110c96a6f78SLois Curfman McInnes    Input Parameter:
1111c96a6f78SLois Curfman McInnes .  snes - SNES context
1112c96a6f78SLois Curfman McInnes 
1113c96a6f78SLois Curfman McInnes    Output Parameter:
1114c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1115c96a6f78SLois Curfman McInnes 
1116c96a6f78SLois Curfman McInnes    Notes:
1117c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1118c96a6f78SLois Curfman McInnes 
111936851e7fSLois Curfman McInnes    Level: intermediate
112036851e7fSLois Curfman McInnes 
1121c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
11222b668275SBarry Smith 
11238c7482ecSBarry Smith .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
1124c96a6f78SLois Curfman McInnes @*/
11257087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
1126c96a6f78SLois Curfman McInnes {
11273a40ed3dSBarry Smith   PetscFunctionBegin;
11280700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11294482741eSBarry Smith   PetscValidIntPointer(lits,2);
1130c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
11313a40ed3dSBarry Smith   PetscFunctionReturn(0);
1132c96a6f78SLois Curfman McInnes }
1133c96a6f78SLois Curfman McInnes 
11344a2ae208SSatish Balay #undef __FUNCT__
113594b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP"
113652baeb72SSatish Balay /*@
113794b7f48cSBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
11389b94acceSBarry Smith 
113994b7f48cSBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
1140c7afd0dbSLois Curfman McInnes 
11419b94acceSBarry Smith    Input Parameter:
11429b94acceSBarry Smith .  snes - the SNES context
11439b94acceSBarry Smith 
11449b94acceSBarry Smith    Output Parameter:
114594b7f48cSBarry Smith .  ksp - the KSP context
11469b94acceSBarry Smith 
11479b94acceSBarry Smith    Notes:
114894b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
11499b94acceSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
11502999313aSBarry Smith    PC contexts as well.
11519b94acceSBarry Smith 
115236851e7fSLois Curfman McInnes    Level: beginner
115336851e7fSLois Curfman McInnes 
115494b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
11559b94acceSBarry Smith 
11562999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
11579b94acceSBarry Smith @*/
11587087cfbeSBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
11599b94acceSBarry Smith {
11601cee3971SBarry Smith   PetscErrorCode ierr;
11611cee3971SBarry Smith 
11623a40ed3dSBarry Smith   PetscFunctionBegin;
11630700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11644482741eSBarry Smith   PetscValidPointer(ksp,2);
11651cee3971SBarry Smith 
11661cee3971SBarry Smith   if (!snes->ksp) {
11671cee3971SBarry Smith     ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr);
11681cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
11691cee3971SBarry Smith     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
11701cee3971SBarry Smith   }
117194b7f48cSBarry Smith   *ksp = snes->ksp;
11723a40ed3dSBarry Smith   PetscFunctionReturn(0);
11739b94acceSBarry Smith }
117482bf6240SBarry Smith 
11754a2ae208SSatish Balay #undef __FUNCT__
11762999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
11772999313aSBarry Smith /*@
11782999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
11792999313aSBarry Smith 
11802999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
11812999313aSBarry Smith 
11822999313aSBarry Smith    Input Parameters:
11832999313aSBarry Smith +  snes - the SNES context
11842999313aSBarry Smith -  ksp - the KSP context
11852999313aSBarry Smith 
11862999313aSBarry Smith    Notes:
11872999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
11882999313aSBarry Smith    so this routine is rarely needed.
11892999313aSBarry Smith 
11902999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
11912999313aSBarry Smith    decreased by one.
11922999313aSBarry Smith 
11932999313aSBarry Smith    Level: developer
11942999313aSBarry Smith 
11952999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
11962999313aSBarry Smith 
11972999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
11982999313aSBarry Smith @*/
11997087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
12002999313aSBarry Smith {
12012999313aSBarry Smith   PetscErrorCode ierr;
12022999313aSBarry Smith 
12032999313aSBarry Smith   PetscFunctionBegin;
12040700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12050700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
12062999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
12077dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1208906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
12092999313aSBarry Smith   snes->ksp = ksp;
12102999313aSBarry Smith   PetscFunctionReturn(0);
12112999313aSBarry Smith }
12122999313aSBarry Smith 
12137adad957SLisandro Dalcin #if 0
12142999313aSBarry Smith #undef __FUNCT__
12154a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc"
12166849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
1217e24b481bSBarry Smith {
1218e24b481bSBarry Smith   PetscFunctionBegin;
1219e24b481bSBarry Smith   PetscFunctionReturn(0);
1220e24b481bSBarry Smith }
12217adad957SLisandro Dalcin #endif
1222e24b481bSBarry Smith 
12239b94acceSBarry Smith /* -----------------------------------------------------------*/
12244a2ae208SSatish Balay #undef __FUNCT__
12254a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
122652baeb72SSatish Balay /*@
12279b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
12289b94acceSBarry Smith 
1229c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1230c7afd0dbSLois Curfman McInnes 
1231c7afd0dbSLois Curfman McInnes    Input Parameters:
1232906ed7ccSBarry Smith .  comm - MPI communicator
12339b94acceSBarry Smith 
12349b94acceSBarry Smith    Output Parameter:
12359b94acceSBarry Smith .  outsnes - the new SNES context
12369b94acceSBarry Smith 
1237c7afd0dbSLois Curfman McInnes    Options Database Keys:
1238c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1239c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1240c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1241c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1242c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1243c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1244c1f60f51SBarry Smith 
124536851e7fSLois Curfman McInnes    Level: beginner
124636851e7fSLois Curfman McInnes 
12479b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
12489b94acceSBarry Smith 
1249a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1250a8054027SBarry Smith 
12519b94acceSBarry Smith @*/
12527087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
12539b94acceSBarry Smith {
1254dfbe8321SBarry Smith   PetscErrorCode      ierr;
12559b94acceSBarry Smith   SNES                snes;
1256fa9f3622SBarry Smith   SNESKSPEW           *kctx;
125737fcc0dbSBarry Smith 
12583a40ed3dSBarry Smith   PetscFunctionBegin;
1259ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
12608ba1e511SMatthew Knepley   *outsnes = PETSC_NULL;
12618ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
12628ba1e511SMatthew Knepley   ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr);
12638ba1e511SMatthew Knepley #endif
12648ba1e511SMatthew Knepley 
12653194b578SJed Brown   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
12667adad957SLisandro Dalcin 
126785385478SLisandro Dalcin   snes->ops->converged    = SNESDefaultConverged;
12682c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
12699b94acceSBarry Smith   snes->max_its           = 50;
12709750a799SBarry Smith   snes->max_funcs	  = 10000;
12719b94acceSBarry Smith   snes->norm		  = 0.0;
1272b4874afaSBarry Smith   snes->rtol		  = 1.e-8;
1273b4874afaSBarry Smith   snes->ttol              = 0.0;
127470441072SBarry Smith   snes->abstol		  = 1.e-50;
1275*c60f73f4SPeter Brune   snes->stol		  = 1.e-8;
12764b27c08aSLois Curfman McInnes   snes->deltatol	  = 1.e-12;
12779b94acceSBarry Smith   snes->nfuncs            = 0;
127850ffb88aSMatthew Knepley   snes->numFailures       = 0;
127950ffb88aSMatthew Knepley   snes->maxFailures       = 1;
12807a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1281e35cf81dSBarry Smith   snes->lagjacobian       = 1;
1282a8054027SBarry Smith   snes->lagpreconditioner = 1;
1283639f9d9dSBarry Smith   snes->numbermonitors    = 0;
12849b94acceSBarry Smith   snes->data              = 0;
12854dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1286186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
12876f24a144SLois Curfman McInnes   snes->nwork             = 0;
128858c9b817SLisandro Dalcin   snes->work              = 0;
128958c9b817SLisandro Dalcin   snes->nvwork            = 0;
129058c9b817SLisandro Dalcin   snes->vwork             = 0;
1291758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1292758f92a0SBarry Smith   snes->conv_hist_max     = 0;
1293758f92a0SBarry Smith   snes->conv_hist         = PETSC_NULL;
1294758f92a0SBarry Smith   snes->conv_hist_its     = PETSC_NULL;
1295758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1296184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
129789b92e6fSPeter Brune   snes->gssweeps          = 1;
12989b94acceSBarry Smith 
12993d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
13003d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
13013d4c4710SBarry Smith 
13029b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
130338f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr);
13049b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
13059b94acceSBarry Smith   kctx->version     = 2;
13069b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
13079b94acceSBarry Smith                              this was too large for some test cases */
130875567043SBarry Smith   kctx->rtol_last   = 0.0;
13099b94acceSBarry Smith   kctx->rtol_max    = .9;
13109b94acceSBarry Smith   kctx->gamma       = 1.0;
131162d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
131271f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
13139b94acceSBarry Smith   kctx->threshold   = .1;
131475567043SBarry Smith   kctx->lresid_last = 0.0;
131575567043SBarry Smith   kctx->norm_last   = 0.0;
13169b94acceSBarry Smith 
13179b94acceSBarry Smith   *outsnes = snes;
13183a40ed3dSBarry Smith   PetscFunctionReturn(0);
13199b94acceSBarry Smith }
13209b94acceSBarry Smith 
13214a2ae208SSatish Balay #undef __FUNCT__
13224a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
13239b94acceSBarry Smith /*@C
13249b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
13259b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
13269b94acceSBarry Smith    equations.
13279b94acceSBarry Smith 
13283f9fe445SBarry Smith    Logically Collective on SNES
1329fee21e36SBarry Smith 
1330c7afd0dbSLois Curfman McInnes    Input Parameters:
1331c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1332c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1333de044059SHong Zhang .  func - function evaluation routine
1334c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1335c7afd0dbSLois Curfman McInnes          function evaluation routine (may be PETSC_NULL)
13369b94acceSBarry Smith 
1337c7afd0dbSLois Curfman McInnes    Calling sequence of func:
13388d76a1e5SLois Curfman McInnes $    func (SNES snes,Vec x,Vec f,void *ctx);
1339c7afd0dbSLois Curfman McInnes 
1340c586c404SJed Brown +  snes - the SNES context
1341c586c404SJed Brown .  x - state at which to evaluate residual
1342c586c404SJed Brown .  f - vector to put residual
1343c7afd0dbSLois Curfman McInnes -  ctx - optional user-defined function context
13449b94acceSBarry Smith 
13459b94acceSBarry Smith    Notes:
13469b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
13479b94acceSBarry Smith $      f'(x) x = -f(x),
1348c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
13499b94acceSBarry Smith 
135036851e7fSLois Curfman McInnes    Level: beginner
135136851e7fSLois Curfman McInnes 
13529b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
13539b94acceSBarry Smith 
13548b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard()
13559b94acceSBarry Smith @*/
13567087cfbeSBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
13579b94acceSBarry Smith {
135885385478SLisandro Dalcin   PetscErrorCode ierr;
13596cab3a1bSJed Brown   DM             dm;
13606cab3a1bSJed Brown 
13613a40ed3dSBarry Smith   PetscFunctionBegin;
13620700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1363d2a683ecSLisandro Dalcin   if (r) {
1364d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1365d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
136685385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
13676bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
136885385478SLisandro Dalcin     snes->vec_func = r;
1369d2a683ecSLisandro Dalcin   }
13706cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
13716cab3a1bSJed Brown   ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr);
13723a40ed3dSBarry Smith   PetscFunctionReturn(0);
13739b94acceSBarry Smith }
13749b94acceSBarry Smith 
1375646217ecSPeter Brune 
1376646217ecSPeter Brune #undef __FUNCT__
1377646217ecSPeter Brune #define __FUNCT__ "SNESSetGS"
1378c79ef259SPeter Brune /*@C
1379c79ef259SPeter Brune    SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for
1380c79ef259SPeter Brune    use with composed nonlinear solvers.
1381c79ef259SPeter Brune 
1382c79ef259SPeter Brune    Input Parameters:
1383c79ef259SPeter Brune +  snes   - the SNES context
1384c79ef259SPeter Brune .  gsfunc - function evaluation routine
1385c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
1386c79ef259SPeter Brune             smoother evaluation routine (may be PETSC_NULL)
1387c79ef259SPeter Brune 
1388c79ef259SPeter Brune    Calling sequence of func:
1389c79ef259SPeter Brune $    func (SNES snes,Vec x,Vec b,void *ctx);
1390c79ef259SPeter Brune 
1391c79ef259SPeter Brune +  X   - solution vector
1392c79ef259SPeter Brune .  B   - RHS vector
1393d28543b3SPeter Brune -  ctx - optional user-defined Gauss-Seidel context
1394c79ef259SPeter Brune 
1395c79ef259SPeter Brune    Notes:
1396c79ef259SPeter Brune    The GS routines are used by the composed nonlinear solver to generate
1397c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
1398c79ef259SPeter Brune 
1399d28543b3SPeter Brune    Level: intermediate
1400c79ef259SPeter Brune 
1401d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel
1402c79ef259SPeter Brune 
1403c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS()
1404c79ef259SPeter Brune @*/
14056cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx)
14066cab3a1bSJed Brown {
14076cab3a1bSJed Brown   PetscErrorCode ierr;
14086cab3a1bSJed Brown   DM dm;
14096cab3a1bSJed Brown 
1410646217ecSPeter Brune   PetscFunctionBegin;
14116cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
14126cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
14136cab3a1bSJed Brown   ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr);
1414646217ecSPeter Brune   PetscFunctionReturn(0);
1415646217ecSPeter Brune }
1416646217ecSPeter Brune 
1417d25893d9SBarry Smith #undef __FUNCT__
141889b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps"
141989b92e6fSPeter Brune /*@
142089b92e6fSPeter Brune    SNESSetGSSweeps - Sets the number of sweeps of GS to use.
142189b92e6fSPeter Brune 
142289b92e6fSPeter Brune    Input Parameters:
142389b92e6fSPeter Brune +  snes   - the SNES context
142489b92e6fSPeter Brune -  sweeps  - the number of sweeps of GS to perform.
142589b92e6fSPeter Brune 
142689b92e6fSPeter Brune    Level: intermediate
142789b92e6fSPeter Brune 
142889b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
142989b92e6fSPeter Brune 
143089b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps()
143189b92e6fSPeter Brune @*/
143289b92e6fSPeter Brune 
143389b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) {
143489b92e6fSPeter Brune   PetscFunctionBegin;
143589b92e6fSPeter Brune   snes->gssweeps = sweeps;
143689b92e6fSPeter Brune   PetscFunctionReturn(0);
143789b92e6fSPeter Brune }
143889b92e6fSPeter Brune 
143989b92e6fSPeter Brune 
144089b92e6fSPeter Brune #undef __FUNCT__
144189b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps"
144289b92e6fSPeter Brune /*@
144389b92e6fSPeter Brune    SNESGetGSSweeps - Gets the number of sweeps GS will use.
144489b92e6fSPeter Brune 
144589b92e6fSPeter Brune    Input Parameters:
144689b92e6fSPeter Brune .  snes   - the SNES context
144789b92e6fSPeter Brune 
144889b92e6fSPeter Brune    Output Parameters:
144989b92e6fSPeter Brune .  sweeps  - the number of sweeps of GS to perform.
145089b92e6fSPeter Brune 
145189b92e6fSPeter Brune    Level: intermediate
145289b92e6fSPeter Brune 
145389b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
145489b92e6fSPeter Brune 
145589b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps()
145689b92e6fSPeter Brune @*/
145789b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) {
145889b92e6fSPeter Brune   PetscFunctionBegin;
145989b92e6fSPeter Brune   *sweeps = snes->gssweeps;
146089b92e6fSPeter Brune   PetscFunctionReturn(0);
146189b92e6fSPeter Brune }
146289b92e6fSPeter Brune 
146389b92e6fSPeter Brune #undef __FUNCT__
14648b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction"
14658b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
14668b0a5094SBarry Smith {
14678b0a5094SBarry Smith   PetscErrorCode ierr;
14686cab3a1bSJed Brown   void *functx,*jacctx;
14696cab3a1bSJed Brown 
14708b0a5094SBarry Smith   PetscFunctionBegin;
14716cab3a1bSJed Brown   ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
14726cab3a1bSJed Brown   ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr);
14738b0a5094SBarry Smith   /*  A(x)*x - b(x) */
14746cab3a1bSJed Brown   ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr);
14756cab3a1bSJed Brown   ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr);
14768b0a5094SBarry Smith   ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
14778b0a5094SBarry Smith   ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
14788b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
14798b0a5094SBarry Smith   ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr);
14808b0a5094SBarry Smith   PetscFunctionReturn(0);
14818b0a5094SBarry Smith }
14828b0a5094SBarry Smith 
14838b0a5094SBarry Smith #undef __FUNCT__
14848b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian"
14858b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
14868b0a5094SBarry Smith {
14878b0a5094SBarry Smith   PetscFunctionBegin;
14888b0a5094SBarry Smith   *flag = snes->matstruct;
14898b0a5094SBarry Smith   PetscFunctionReturn(0);
14908b0a5094SBarry Smith }
14918b0a5094SBarry Smith 
14928b0a5094SBarry Smith #undef __FUNCT__
14938b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard"
14948b0a5094SBarry Smith /*@C
14950d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
14968b0a5094SBarry Smith 
14978b0a5094SBarry Smith    Logically Collective on SNES
14988b0a5094SBarry Smith 
14998b0a5094SBarry Smith    Input Parameters:
15008b0a5094SBarry Smith +  snes - the SNES context
15018b0a5094SBarry Smith .  r - vector to store function value
15028b0a5094SBarry Smith .  func - function evaluation routine
15038b0a5094SBarry 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)
15048b0a5094SBarry Smith .  mat - matrix to store A
15058b0a5094SBarry Smith .  mfunc  - function to compute matrix value
15068b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
15078b0a5094SBarry Smith          function evaluation routine (may be PETSC_NULL)
15088b0a5094SBarry Smith 
15098b0a5094SBarry Smith    Calling sequence of func:
15108b0a5094SBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
15118b0a5094SBarry Smith 
15128b0a5094SBarry Smith +  f - function vector
15138b0a5094SBarry Smith -  ctx - optional user-defined function context
15148b0a5094SBarry Smith 
15158b0a5094SBarry Smith    Calling sequence of mfunc:
15168b0a5094SBarry Smith $     mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx);
15178b0a5094SBarry Smith 
15188b0a5094SBarry Smith +  x - input vector
15198b0a5094SBarry 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(),
15208b0a5094SBarry Smith           normally just pass mat in this location
15218b0a5094SBarry Smith .  mat - form A(x) matrix
15228b0a5094SBarry Smith .  flag - flag indicating information about the preconditioner matrix
15238b0a5094SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
15248b0a5094SBarry Smith -  ctx - [optional] user-defined Jacobian context
15258b0a5094SBarry Smith 
15268b0a5094SBarry Smith    Notes:
15278b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
15288b0a5094SBarry Smith 
15298b0a5094SBarry 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}
15308b0a5094SBarry 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.
15318b0a5094SBarry Smith 
15328b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
15338b0a5094SBarry Smith 
15340d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
15350d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
15368b0a5094SBarry Smith 
15378b0a5094SBarry 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
15388b0a5094SBarry 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
15398b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
15408b0a5094SBarry Smith 
15418b0a5094SBarry Smith    Level: beginner
15428b0a5094SBarry Smith 
15438b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function
15448b0a5094SBarry Smith 
15450d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard()
15468b0a5094SBarry Smith @*/
15478b0a5094SBarry 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)
15488b0a5094SBarry Smith {
15498b0a5094SBarry Smith   PetscErrorCode ierr;
15508b0a5094SBarry Smith   PetscFunctionBegin;
15518b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15528b0a5094SBarry Smith   snes->ops->computepfunction = func;
15538b0a5094SBarry Smith   snes->ops->computepjacobian = mfunc;
15548b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
15558b0a5094SBarry Smith   ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
15568b0a5094SBarry Smith   PetscFunctionReturn(0);
15578b0a5094SBarry Smith }
15588b0a5094SBarry Smith 
15598b0a5094SBarry Smith #undef __FUNCT__
1560d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess"
1561d25893d9SBarry Smith /*@C
1562d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1563d25893d9SBarry Smith 
1564d25893d9SBarry Smith    Logically Collective on SNES
1565d25893d9SBarry Smith 
1566d25893d9SBarry Smith    Input Parameters:
1567d25893d9SBarry Smith +  snes - the SNES context
1568d25893d9SBarry Smith .  func - function evaluation routine
1569d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
1570d25893d9SBarry Smith          function evaluation routine (may be PETSC_NULL)
1571d25893d9SBarry Smith 
1572d25893d9SBarry Smith    Calling sequence of func:
1573d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
1574d25893d9SBarry Smith 
1575d25893d9SBarry Smith .  f - function vector
1576d25893d9SBarry Smith -  ctx - optional user-defined function context
1577d25893d9SBarry Smith 
1578d25893d9SBarry Smith    Level: intermediate
1579d25893d9SBarry Smith 
1580d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
1581d25893d9SBarry Smith 
1582d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1583d25893d9SBarry Smith @*/
1584d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1585d25893d9SBarry Smith {
1586d25893d9SBarry Smith   PetscFunctionBegin;
1587d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1588d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
1589d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
1590d25893d9SBarry Smith   PetscFunctionReturn(0);
1591d25893d9SBarry Smith }
1592d25893d9SBarry Smith 
15933ab0aad5SBarry Smith /* --------------------------------------------------------------- */
15943ab0aad5SBarry Smith #undef __FUNCT__
15951096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
15961096aae1SMatthew Knepley /*@C
15971096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
15981096aae1SMatthew Knepley    it assumes a zero right hand side.
15991096aae1SMatthew Knepley 
16003f9fe445SBarry Smith    Logically Collective on SNES
16011096aae1SMatthew Knepley 
16021096aae1SMatthew Knepley    Input Parameter:
16031096aae1SMatthew Knepley .  snes - the SNES context
16041096aae1SMatthew Knepley 
16051096aae1SMatthew Knepley    Output Parameter:
1606bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
16071096aae1SMatthew Knepley 
16081096aae1SMatthew Knepley    Level: intermediate
16091096aae1SMatthew Knepley 
16101096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
16111096aae1SMatthew Knepley 
161285385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
16131096aae1SMatthew Knepley @*/
16147087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
16151096aae1SMatthew Knepley {
16161096aae1SMatthew Knepley   PetscFunctionBegin;
16170700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
16181096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
161985385478SLisandro Dalcin   *rhs = snes->vec_rhs;
16201096aae1SMatthew Knepley   PetscFunctionReturn(0);
16211096aae1SMatthew Knepley }
16221096aae1SMatthew Knepley 
16231096aae1SMatthew Knepley #undef __FUNCT__
16244a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
16259b94acceSBarry Smith /*@
162636851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
16279b94acceSBarry Smith                          SNESSetFunction().
16289b94acceSBarry Smith 
1629c7afd0dbSLois Curfman McInnes    Collective on SNES
1630c7afd0dbSLois Curfman McInnes 
16319b94acceSBarry Smith    Input Parameters:
1632c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1633c7afd0dbSLois Curfman McInnes -  x - input vector
16349b94acceSBarry Smith 
16359b94acceSBarry Smith    Output Parameter:
16363638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
16379b94acceSBarry Smith 
16381bffabb2SLois Curfman McInnes    Notes:
163936851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
164036851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
164136851e7fSLois Curfman McInnes    themselves.
164236851e7fSLois Curfman McInnes 
164336851e7fSLois Curfman McInnes    Level: developer
164436851e7fSLois Curfman McInnes 
16459b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
16469b94acceSBarry Smith 
1647a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
16489b94acceSBarry Smith @*/
16497087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
16509b94acceSBarry Smith {
1651dfbe8321SBarry Smith   PetscErrorCode ierr;
16526cab3a1bSJed Brown   DM             dm;
16536cab3a1bSJed Brown   SNESDM         sdm;
16549b94acceSBarry Smith 
16553a40ed3dSBarry Smith   PetscFunctionBegin;
16560700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
16570700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
16580700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
1659c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
1660c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
16614ec14c9cSBarry Smith   VecValidValues(x,2,PETSC_TRUE);
1662184914b5SBarry Smith 
16636cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
16646cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
1665d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
16666cab3a1bSJed Brown   if (sdm->computefunction) {
1667d64ed03dSBarry Smith     PetscStackPush("SNES user function");
16686cab3a1bSJed Brown     ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
1669d64ed03dSBarry Smith     PetscStackPop;
167073250ac0SBarry Smith   } else if (snes->dm) {
1671644e2e5bSBarry Smith     ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr);
1672c90fad12SPeter Brune   } else if (snes->vec_rhs) {
1673c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
1674644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
167585385478SLisandro Dalcin   if (snes->vec_rhs) {
167685385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
16773ab0aad5SBarry Smith   }
1678ae3c334cSLois Curfman McInnes   snes->nfuncs++;
1679d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
16804ec14c9cSBarry Smith   VecValidValues(y,3,PETSC_FALSE);
16813a40ed3dSBarry Smith   PetscFunctionReturn(0);
16829b94acceSBarry Smith }
16839b94acceSBarry Smith 
16844a2ae208SSatish Balay #undef __FUNCT__
1685646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS"
1686c79ef259SPeter Brune /*@
1687c79ef259SPeter Brune    SNESComputeGS - Calls the Gauss-Seidel function that has been set with
1688c79ef259SPeter Brune                    SNESSetGS().
1689c79ef259SPeter Brune 
1690c79ef259SPeter Brune    Collective on SNES
1691c79ef259SPeter Brune 
1692c79ef259SPeter Brune    Input Parameters:
1693c79ef259SPeter Brune +  snes - the SNES context
1694c79ef259SPeter Brune .  x - input vector
1695c79ef259SPeter Brune -  b - rhs vector
1696c79ef259SPeter Brune 
1697c79ef259SPeter Brune    Output Parameter:
1698c79ef259SPeter Brune .  x - new solution vector
1699c79ef259SPeter Brune 
1700c79ef259SPeter Brune    Notes:
1701c79ef259SPeter Brune    SNESComputeGS() is typically used within composed nonlinear solver
1702c79ef259SPeter Brune    implementations, so most users would not generally call this routine
1703c79ef259SPeter Brune    themselves.
1704c79ef259SPeter Brune 
1705c79ef259SPeter Brune    Level: developer
1706c79ef259SPeter Brune 
1707c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function
1708c79ef259SPeter Brune 
1709c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction()
1710c79ef259SPeter Brune @*/
1711646217ecSPeter Brune PetscErrorCode  SNESComputeGS(SNES snes,Vec b,Vec x)
1712646217ecSPeter Brune {
1713646217ecSPeter Brune   PetscErrorCode ierr;
171489b92e6fSPeter Brune   PetscInt i;
17156cab3a1bSJed Brown   DM dm;
17166cab3a1bSJed Brown   SNESDM sdm;
1717646217ecSPeter Brune 
1718646217ecSPeter Brune   PetscFunctionBegin;
1719646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1720646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
1721646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
1722646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
1723646217ecSPeter Brune   if(b) PetscCheckSameComm(snes,1,b,3);
17244ec14c9cSBarry Smith   if (b) VecValidValues(b,2,PETSC_TRUE);
1725701cf23dSPeter Brune   ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
17266cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
17276cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
17286cab3a1bSJed Brown   if (sdm->computegs) {
172989b92e6fSPeter Brune     for (i = 0; i < snes->gssweeps; i++) {
1730646217ecSPeter Brune       PetscStackPush("SNES user GS");
17316cab3a1bSJed Brown       ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
1732646217ecSPeter Brune       PetscStackPop;
173389b92e6fSPeter Brune     }
1734646217ecSPeter Brune   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve().");
1735701cf23dSPeter Brune   ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
17364ec14c9cSBarry Smith   VecValidValues(x,3,PETSC_FALSE);
1737646217ecSPeter Brune   PetscFunctionReturn(0);
1738646217ecSPeter Brune }
1739646217ecSPeter Brune 
1740646217ecSPeter Brune 
1741646217ecSPeter Brune #undef __FUNCT__
17424a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
174362fef451SLois Curfman McInnes /*@
174462fef451SLois Curfman McInnes    SNESComputeJacobian - Computes the Jacobian matrix that has been
174562fef451SLois Curfman McInnes    set with SNESSetJacobian().
174662fef451SLois Curfman McInnes 
1747c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
1748c7afd0dbSLois Curfman McInnes 
174962fef451SLois Curfman McInnes    Input Parameters:
1750c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1751c7afd0dbSLois Curfman McInnes -  x - input vector
175262fef451SLois Curfman McInnes 
175362fef451SLois Curfman McInnes    Output Parameters:
1754c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
175562fef451SLois Curfman McInnes .  B - optional preconditioning matrix
17562b668275SBarry Smith -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1757fee21e36SBarry Smith 
1758e35cf81dSBarry Smith   Options Database Keys:
1759e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
1760693365a8SJed Brown .    -snes_lag_jacobian <lag>
1761693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
1762693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
1763693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
17644c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
1765c01495d3SJed Brown .    -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference
1766c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
1767c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
1768c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
1769c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
17704c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
1771c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
1772c01495d3SJed Brown 
1773e35cf81dSBarry Smith 
177462fef451SLois Curfman McInnes    Notes:
177562fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
177662fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
177762fef451SLois Curfman McInnes 
177894b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the
1779dc5a77f8SLois Curfman McInnes    flag parameter.
178062fef451SLois Curfman McInnes 
178136851e7fSLois Curfman McInnes    Level: developer
178236851e7fSLois Curfman McInnes 
178362fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
178462fef451SLois Curfman McInnes 
1785e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
178662fef451SLois Curfman McInnes @*/
17877087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
17889b94acceSBarry Smith {
1789dfbe8321SBarry Smith   PetscErrorCode ierr;
1790ace3abfcSBarry Smith   PetscBool      flag;
17916cab3a1bSJed Brown   DM             dm;
17926cab3a1bSJed Brown   SNESDM         sdm;
17933a40ed3dSBarry Smith 
17943a40ed3dSBarry Smith   PetscFunctionBegin;
17950700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
17960700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
17974482741eSBarry Smith   PetscValidPointer(flg,5);
1798c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
17994ec14c9cSBarry Smith   VecValidValues(X,2,PETSC_TRUE);
18006cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
18016cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
18026cab3a1bSJed Brown   if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
1803ebd3b9afSBarry Smith 
1804ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
1805ebd3b9afSBarry Smith 
1806fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
1807fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
1808fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
1809fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
1810e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1811e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
1812ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1813ebd3b9afSBarry Smith     if (flag) {
1814ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1815ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1816ebd3b9afSBarry Smith     }
1817e35cf81dSBarry Smith     PetscFunctionReturn(0);
1818e35cf81dSBarry Smith   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
1819e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1820e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
1821ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1822ebd3b9afSBarry Smith     if (flag) {
1823ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1824ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1825ebd3b9afSBarry Smith     }
1826e35cf81dSBarry Smith     PetscFunctionReturn(0);
1827e35cf81dSBarry Smith   }
1828e35cf81dSBarry Smith 
1829c4fc05e7SBarry Smith   *flg = DIFFERENT_NONZERO_PATTERN;
1830e35cf81dSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1831d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
18326cab3a1bSJed Brown   ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr);
1833d64ed03dSBarry Smith   PetscStackPop;
1834d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1835a8054027SBarry Smith 
18363b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
18373b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
18383b4f5425SBarry Smith     snes->lagpreconditioner = -1;
18393b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
1840a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1841a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
1842a8054027SBarry Smith   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
1843a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1844a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
1845a8054027SBarry Smith   }
1846a8054027SBarry Smith 
18476d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
18480700a824SBarry Smith   /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
18490700a824SBarry Smith     PetscValidHeaderSpecific(*B,MAT_CLASSID,4);   */
1850693365a8SJed Brown   {
1851693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
1852693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr);
1853693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
1854693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
1855693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr);
1856693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
1857693365a8SJed Brown       Mat Bexp_mine = PETSC_NULL,Bexp,FDexp;
1858693365a8SJed Brown       MatStructure mstruct;
1859693365a8SJed Brown       PetscViewer vdraw,vstdout;
18606b3a5b13SJed Brown       PetscBool flg;
1861693365a8SJed Brown       if (flag_operator) {
1862693365a8SJed Brown         ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr);
1863693365a8SJed Brown         Bexp = Bexp_mine;
1864693365a8SJed Brown       } else {
1865693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
1866693365a8SJed Brown         ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
1867693365a8SJed Brown         if (flg) Bexp = *B;
1868693365a8SJed Brown         else {
1869693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
1870693365a8SJed Brown           ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr);
1871693365a8SJed Brown           Bexp = Bexp_mine;
1872693365a8SJed Brown         }
1873693365a8SJed Brown       }
1874693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
1875693365a8SJed Brown       ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr);
1876693365a8SJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
1877693365a8SJed Brown       if (flag_draw || flag_contour) {
1878693365a8SJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
1879693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
1880693365a8SJed Brown       } else vdraw = PETSC_NULL;
1881693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr);
1882693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
1883693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
1884693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
1885693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
1886693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
1887693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
1888693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
1889693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
1890693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
1891693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
1892693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
1893693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
1894693365a8SJed Brown       }
1895693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
1896693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
1897693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
1898693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
1899693365a8SJed Brown     }
1900693365a8SJed Brown   }
19014c30e9fbSJed Brown   {
19026719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
19036719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
19044c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr);
19056719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr);
19064c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
19074c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
19086719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr);
19096719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr);
19106719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr);
19116719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
19124c30e9fbSJed Brown       Mat Bfd;
19134c30e9fbSJed Brown       MatStructure mstruct;
19144c30e9fbSJed Brown       PetscViewer vdraw,vstdout;
19154c30e9fbSJed Brown       ISColoring iscoloring;
19164c30e9fbSJed Brown       MatFDColoring matfdcoloring;
19174c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
19184c30e9fbSJed Brown       void *funcctx;
19196719d8e4SJed Brown       PetscReal norm1,norm2,normmax;
19204c30e9fbSJed Brown 
19214c30e9fbSJed Brown       ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
19224c30e9fbSJed Brown       ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
19234c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
19244c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
19254c30e9fbSJed Brown 
19264c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
19274c30e9fbSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr);
19284c30e9fbSJed Brown       ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr);
19294c30e9fbSJed Brown       ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
19304c30e9fbSJed Brown       ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
19314c30e9fbSJed Brown       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
19324c30e9fbSJed Brown       ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr);
19334c30e9fbSJed Brown       ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
19344c30e9fbSJed Brown 
19354c30e9fbSJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
19364c30e9fbSJed Brown       if (flag_draw || flag_contour) {
19374c30e9fbSJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
19384c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
19394c30e9fbSJed Brown       } else vdraw = PETSC_NULL;
19404c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
19416719d8e4SJed Brown       if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);}
19424c30e9fbSJed Brown       if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);}
19434c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
19446719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
19454c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
19464c30e9fbSJed Brown       ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
19474c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
19486719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
19494c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
19506719d8e4SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr);
19516719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
19524c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
19534c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
19544c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
19554c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
19564c30e9fbSJed Brown       }
19574c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
19586719d8e4SJed Brown 
19596719d8e4SJed Brown       if (flag_threshold) {
19606719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
19616719d8e4SJed Brown         ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr);
19626719d8e4SJed Brown         ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr);
19636719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
19646719d8e4SJed Brown           const PetscScalar *ba,*ca;
19656719d8e4SJed Brown           const PetscInt *bj,*cj;
19666719d8e4SJed Brown           PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
19676719d8e4SJed Brown           PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0;
19686719d8e4SJed Brown           ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
19696719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
19706719d8e4SJed Brown           if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
19716719d8e4SJed Brown           for (j=0; j<bn; j++) {
19726719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
19736719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
19746719d8e4SJed Brown               maxentrycol = bj[j];
19756719d8e4SJed Brown               maxentry = PetscRealPart(ba[j]);
19766719d8e4SJed Brown             }
19776719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
19786719d8e4SJed Brown               maxdiffcol = bj[j];
19796719d8e4SJed Brown               maxdiff = PetscRealPart(ca[j]);
19806719d8e4SJed Brown             }
19816719d8e4SJed Brown             if (rdiff > maxrdiff) {
19826719d8e4SJed Brown               maxrdiffcol = bj[j];
19836719d8e4SJed Brown               maxrdiff = rdiff;
19846719d8e4SJed Brown             }
19856719d8e4SJed Brown           }
19866719d8e4SJed Brown           if (maxrdiff > 1) {
19876719d8e4SJed 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);
19886719d8e4SJed Brown             for (j=0; j<bn; j++) {
19896719d8e4SJed Brown               PetscReal rdiff;
19906719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
19916719d8e4SJed Brown               if (rdiff > 1) {
19926719d8e4SJed Brown                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr);
19936719d8e4SJed Brown               }
19946719d8e4SJed Brown             }
19956719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
19966719d8e4SJed Brown           }
19976719d8e4SJed Brown           ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
19986719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
19996719d8e4SJed Brown         }
20006719d8e4SJed Brown       }
20014c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
20024c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
20034c30e9fbSJed Brown     }
20044c30e9fbSJed Brown   }
20053a40ed3dSBarry Smith   PetscFunctionReturn(0);
20069b94acceSBarry Smith }
20079b94acceSBarry Smith 
20084a2ae208SSatish Balay #undef __FUNCT__
20094a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
20109b94acceSBarry Smith /*@C
20119b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2012044dda88SLois Curfman McInnes    location to store the matrix.
20139b94acceSBarry Smith 
20143f9fe445SBarry Smith    Logically Collective on SNES and Mat
2015c7afd0dbSLois Curfman McInnes 
20169b94acceSBarry Smith    Input Parameters:
2017c7afd0dbSLois Curfman McInnes +  snes - the SNES context
20189b94acceSBarry Smith .  A - Jacobian matrix
20199b94acceSBarry Smith .  B - preconditioner matrix (usually same as the Jacobian)
2020efd51863SBarry Smith .  func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value)
2021c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
2022efd51863SBarry Smith          Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value)
20239b94acceSBarry Smith 
20249b94acceSBarry Smith    Calling sequence of func:
20258d76a1e5SLois Curfman McInnes $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
20269b94acceSBarry Smith 
2027c7afd0dbSLois Curfman McInnes +  x - input vector
20289b94acceSBarry Smith .  A - Jacobian matrix
20299b94acceSBarry Smith .  B - preconditioner matrix, usually the same as A
2030ac21db08SLois Curfman McInnes .  flag - flag indicating information about the preconditioner matrix
20312b668275SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
2032c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined Jacobian context
20339b94acceSBarry Smith 
20349b94acceSBarry Smith    Notes:
203594b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the flag
20362cd2dfdcSLois Curfman McInnes    output parameter in the routine func().  Be sure to read this information!
2037ac21db08SLois Curfman McInnes 
2038ac21db08SLois Curfman McInnes    The routine func() takes Mat * as the matrix arguments rather than Mat.
20399b94acceSBarry Smith    This allows the Jacobian evaluation routine to replace A and/or B with a
20409b94acceSBarry Smith    completely new new matrix structure (not just different matrix elements)
20419b94acceSBarry Smith    when appropriate, for instance, if the nonzero structure is changing
20429b94acceSBarry Smith    throughout the global iterations.
20439b94acceSBarry Smith 
204416913363SBarry Smith    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
204516913363SBarry Smith    each matrix.
204616913363SBarry Smith 
2047a8a26c1eSJed Brown    If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument
2048a8a26c1eSJed Brown    must be a MatFDColoring.
2049a8a26c1eSJed Brown 
2050c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2051c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2052c3cc8fd1SJed Brown 
205336851e7fSLois Curfman McInnes    Level: beginner
205436851e7fSLois Curfman McInnes 
20559b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
20569b94acceSBarry Smith 
20573ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
20589b94acceSBarry Smith @*/
20597087cfbeSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
20609b94acceSBarry Smith {
2061dfbe8321SBarry Smith   PetscErrorCode ierr;
20626cab3a1bSJed Brown   DM             dm;
20633a7fca6bSBarry Smith 
20643a40ed3dSBarry Smith   PetscFunctionBegin;
20650700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
20660700a824SBarry Smith   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
20670700a824SBarry Smith   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
2068c9780b6fSBarry Smith   if (A) PetscCheckSameComm(snes,1,A,2);
206906975374SJed Brown   if (B) PetscCheckSameComm(snes,1,B,3);
20706cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
20716cab3a1bSJed Brown   ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr);
20723a7fca6bSBarry Smith   if (A) {
20737dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
20746bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
20759b94acceSBarry Smith     snes->jacobian = A;
20763a7fca6bSBarry Smith   }
20773a7fca6bSBarry Smith   if (B) {
20787dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
20796bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
20809b94acceSBarry Smith     snes->jacobian_pre = B;
20813a7fca6bSBarry Smith   }
20823a40ed3dSBarry Smith   PetscFunctionReturn(0);
20839b94acceSBarry Smith }
208462fef451SLois Curfman McInnes 
20854a2ae208SSatish Balay #undef __FUNCT__
20864a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
2087c2aafc4cSSatish Balay /*@C
2088b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2089b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2090b4fd4287SBarry Smith 
2091c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2092c7afd0dbSLois Curfman McInnes 
2093b4fd4287SBarry Smith    Input Parameter:
2094b4fd4287SBarry Smith .  snes - the nonlinear solver context
2095b4fd4287SBarry Smith 
2096b4fd4287SBarry Smith    Output Parameters:
2097c7afd0dbSLois Curfman McInnes +  A - location to stash Jacobian matrix (or PETSC_NULL)
2098b4fd4287SBarry Smith .  B - location to stash preconditioner matrix (or PETSC_NULL)
209970e92668SMatthew Knepley .  func - location to put Jacobian function (or PETSC_NULL)
210070e92668SMatthew Knepley -  ctx - location to stash Jacobian ctx (or PETSC_NULL)
2101fee21e36SBarry Smith 
210236851e7fSLois Curfman McInnes    Level: advanced
210336851e7fSLois Curfman McInnes 
2104b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian()
2105b4fd4287SBarry Smith @*/
21067087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
2107b4fd4287SBarry Smith {
21086cab3a1bSJed Brown   PetscErrorCode ierr;
21096cab3a1bSJed Brown   DM             dm;
21106cab3a1bSJed Brown   SNESDM         sdm;
21116cab3a1bSJed Brown 
21123a40ed3dSBarry Smith   PetscFunctionBegin;
21130700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2114b4fd4287SBarry Smith   if (A)    *A    = snes->jacobian;
2115b4fd4287SBarry Smith   if (B)    *B    = snes->jacobian_pre;
21166cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
21176cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
21186cab3a1bSJed Brown   if (func) *func = sdm->computejacobian;
21196cab3a1bSJed Brown   if (ctx)  *ctx  = sdm->jacobianctx;
21203a40ed3dSBarry Smith   PetscFunctionReturn(0);
2121b4fd4287SBarry Smith }
2122b4fd4287SBarry Smith 
21239b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
21249b94acceSBarry Smith 
21254a2ae208SSatish Balay #undef __FUNCT__
21264a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
21279b94acceSBarry Smith /*@
21289b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
2129272ac6f2SLois Curfman McInnes    of a nonlinear solver.
21309b94acceSBarry Smith 
2131fee21e36SBarry Smith    Collective on SNES
2132fee21e36SBarry Smith 
2133c7afd0dbSLois Curfman McInnes    Input Parameters:
213470e92668SMatthew Knepley .  snes - the SNES context
2135c7afd0dbSLois Curfman McInnes 
2136272ac6f2SLois Curfman McInnes    Notes:
2137272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
2138272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
2139272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
2140272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
2141272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
2142272ac6f2SLois Curfman McInnes 
214336851e7fSLois Curfman McInnes    Level: advanced
214436851e7fSLois Curfman McInnes 
21459b94acceSBarry Smith .keywords: SNES, nonlinear, setup
21469b94acceSBarry Smith 
21479b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
21489b94acceSBarry Smith @*/
21497087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
21509b94acceSBarry Smith {
2151dfbe8321SBarry Smith   PetscErrorCode ierr;
21526cab3a1bSJed Brown   DM             dm;
21536cab3a1bSJed Brown   SNESDM         sdm;
21543a40ed3dSBarry Smith 
21553a40ed3dSBarry Smith   PetscFunctionBegin;
21560700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
21574dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
21589b94acceSBarry Smith 
21597adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
216085385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
216185385478SLisandro Dalcin   }
216285385478SLisandro Dalcin 
2163a63bb30eSJed Brown   ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
216417186662SBarry Smith   if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
216558c9b817SLisandro Dalcin   if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
216658c9b817SLisandro Dalcin 
216758c9b817SLisandro Dalcin   if (!snes->vec_sol_update /* && snes->vec_sol */) {
216858c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
216958c9b817SLisandro Dalcin     ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr);
217058c9b817SLisandro Dalcin   }
217158c9b817SLisandro Dalcin 
21726cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
21736cab3a1bSJed Brown   ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */
21746cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
21756cab3a1bSJed Brown   if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc");
21766cab3a1bSJed Brown   if (!snes->vec_func) {
21776cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2178214df951SJed Brown   }
2179efd51863SBarry Smith 
2180b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
2181b710008aSBarry Smith 
2182f1c6b773SPeter Brune   if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);}
21839e764e56SPeter Brune 
2184d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
2185d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
2186d25893d9SBarry Smith   }
2187d25893d9SBarry Smith 
2188410397dcSLisandro Dalcin   if (snes->ops->setup) {
2189410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2190410397dcSLisandro Dalcin   }
219158c9b817SLisandro Dalcin 
21927aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
21933a40ed3dSBarry Smith   PetscFunctionReturn(0);
21949b94acceSBarry Smith }
21959b94acceSBarry Smith 
21964a2ae208SSatish Balay #undef __FUNCT__
219737596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
219837596af1SLisandro Dalcin /*@
219937596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
220037596af1SLisandro Dalcin 
220137596af1SLisandro Dalcin    Collective on SNES
220237596af1SLisandro Dalcin 
220337596af1SLisandro Dalcin    Input Parameter:
220437596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
220537596af1SLisandro Dalcin 
2206d25893d9SBarry Smith    Level: intermediate
2207d25893d9SBarry Smith 
2208d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
220937596af1SLisandro Dalcin 
221037596af1SLisandro Dalcin .keywords: SNES, destroy
221137596af1SLisandro Dalcin 
221237596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
221337596af1SLisandro Dalcin @*/
221437596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
221537596af1SLisandro Dalcin {
221637596af1SLisandro Dalcin   PetscErrorCode ierr;
221737596af1SLisandro Dalcin 
221837596af1SLisandro Dalcin   PetscFunctionBegin;
221937596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2220d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
2221d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
2222d25893d9SBarry Smith     snes->user = PETSC_NULL;
2223d25893d9SBarry Smith   }
22248a23116dSBarry Smith   if (snes->pc) {
22258a23116dSBarry Smith     ierr = SNESReset(snes->pc);CHKERRQ(ierr);
22268a23116dSBarry Smith   }
22278a23116dSBarry Smith 
222837596af1SLisandro Dalcin   if (snes->ops->reset) {
222937596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
223037596af1SLisandro Dalcin   }
22319e764e56SPeter Brune   if (snes->ksp) {
22329e764e56SPeter Brune     ierr = KSPReset(snes->ksp);CHKERRQ(ierr);
22339e764e56SPeter Brune   }
22349e764e56SPeter Brune 
22359e764e56SPeter Brune   if (snes->linesearch) {
2236f1c6b773SPeter Brune     ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr);
22379e764e56SPeter Brune   }
22389e764e56SPeter Brune 
22396bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
22406bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
22416bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
22426bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
22436bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
22446bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2245c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
2246c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
224737596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
224837596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
224937596af1SLisandro Dalcin   PetscFunctionReturn(0);
225037596af1SLisandro Dalcin }
225137596af1SLisandro Dalcin 
225237596af1SLisandro Dalcin #undef __FUNCT__
22534a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
225452baeb72SSatish Balay /*@
22559b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
22569b94acceSBarry Smith    with SNESCreate().
22579b94acceSBarry Smith 
2258c7afd0dbSLois Curfman McInnes    Collective on SNES
2259c7afd0dbSLois Curfman McInnes 
22609b94acceSBarry Smith    Input Parameter:
22619b94acceSBarry Smith .  snes - the SNES context
22629b94acceSBarry Smith 
226336851e7fSLois Curfman McInnes    Level: beginner
226436851e7fSLois Curfman McInnes 
22659b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
22669b94acceSBarry Smith 
226763a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
22689b94acceSBarry Smith @*/
22696bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
22709b94acceSBarry Smith {
22716849ba73SBarry Smith   PetscErrorCode ierr;
22723a40ed3dSBarry Smith 
22733a40ed3dSBarry Smith   PetscFunctionBegin;
22746bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
22756bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
22766bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2277d4bb536fSBarry Smith 
22786bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
22798a23116dSBarry Smith   ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr);
22806b8b9a38SLisandro Dalcin 
2281be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
22826bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
22836bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
22846d4c513bSLisandro Dalcin 
22856bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
22866bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
2287f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr);
22886b8b9a38SLisandro Dalcin 
22896bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
22906bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
22916bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
22926b8b9a38SLisandro Dalcin   }
22936bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
22946bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
22956bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
229658c9b817SLisandro Dalcin   }
22976bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2298a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
22993a40ed3dSBarry Smith  PetscFunctionReturn(0);
23009b94acceSBarry Smith }
23019b94acceSBarry Smith 
23029b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
23039b94acceSBarry Smith 
23044a2ae208SSatish Balay #undef __FUNCT__
2305a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
2306a8054027SBarry Smith /*@
2307a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2308a8054027SBarry Smith 
23093f9fe445SBarry Smith    Logically Collective on SNES
2310a8054027SBarry Smith 
2311a8054027SBarry Smith    Input Parameters:
2312a8054027SBarry Smith +  snes - the SNES context
2313a8054027SBarry 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
23143b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2315a8054027SBarry Smith 
2316a8054027SBarry Smith    Options Database Keys:
2317a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2318a8054027SBarry Smith 
2319a8054027SBarry Smith    Notes:
2320a8054027SBarry Smith    The default is 1
2321a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2322a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2323a8054027SBarry Smith 
2324a8054027SBarry Smith    Level: intermediate
2325a8054027SBarry Smith 
2326a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2327a8054027SBarry Smith 
2328e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2329a8054027SBarry Smith 
2330a8054027SBarry Smith @*/
23317087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2332a8054027SBarry Smith {
2333a8054027SBarry Smith   PetscFunctionBegin;
23340700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2335e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2336e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2337c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2338a8054027SBarry Smith   snes->lagpreconditioner = lag;
2339a8054027SBarry Smith   PetscFunctionReturn(0);
2340a8054027SBarry Smith }
2341a8054027SBarry Smith 
2342a8054027SBarry Smith #undef __FUNCT__
2343efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
2344efd51863SBarry Smith /*@
2345efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2346efd51863SBarry Smith 
2347efd51863SBarry Smith    Logically Collective on SNES
2348efd51863SBarry Smith 
2349efd51863SBarry Smith    Input Parameters:
2350efd51863SBarry Smith +  snes - the SNES context
2351efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
2352efd51863SBarry Smith 
2353efd51863SBarry Smith    Options Database Keys:
2354efd51863SBarry Smith .    -snes_grid_sequence <steps>
2355efd51863SBarry Smith 
2356efd51863SBarry Smith    Level: intermediate
2357efd51863SBarry Smith 
2358c0df2a02SJed Brown    Notes:
2359c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2360c0df2a02SJed Brown 
2361efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2362efd51863SBarry Smith 
2363efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2364efd51863SBarry Smith 
2365efd51863SBarry Smith @*/
2366efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2367efd51863SBarry Smith {
2368efd51863SBarry Smith   PetscFunctionBegin;
2369efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2370efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
2371efd51863SBarry Smith   snes->gridsequence = steps;
2372efd51863SBarry Smith   PetscFunctionReturn(0);
2373efd51863SBarry Smith }
2374efd51863SBarry Smith 
2375efd51863SBarry Smith #undef __FUNCT__
2376a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
2377a8054027SBarry Smith /*@
2378a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
2379a8054027SBarry Smith 
23803f9fe445SBarry Smith    Not Collective
2381a8054027SBarry Smith 
2382a8054027SBarry Smith    Input Parameter:
2383a8054027SBarry Smith .  snes - the SNES context
2384a8054027SBarry Smith 
2385a8054027SBarry Smith    Output Parameter:
2386a8054027SBarry 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
23873b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2388a8054027SBarry Smith 
2389a8054027SBarry Smith    Options Database Keys:
2390a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2391a8054027SBarry Smith 
2392a8054027SBarry Smith    Notes:
2393a8054027SBarry Smith    The default is 1
2394a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2395a8054027SBarry Smith 
2396a8054027SBarry Smith    Level: intermediate
2397a8054027SBarry Smith 
2398a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2399a8054027SBarry Smith 
2400a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
2401a8054027SBarry Smith 
2402a8054027SBarry Smith @*/
24037087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
2404a8054027SBarry Smith {
2405a8054027SBarry Smith   PetscFunctionBegin;
24060700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2407a8054027SBarry Smith   *lag = snes->lagpreconditioner;
2408a8054027SBarry Smith   PetscFunctionReturn(0);
2409a8054027SBarry Smith }
2410a8054027SBarry Smith 
2411a8054027SBarry Smith #undef __FUNCT__
2412e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
2413e35cf81dSBarry Smith /*@
2414e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
2415e35cf81dSBarry Smith      often the preconditioner is rebuilt.
2416e35cf81dSBarry Smith 
24173f9fe445SBarry Smith    Logically Collective on SNES
2418e35cf81dSBarry Smith 
2419e35cf81dSBarry Smith    Input Parameters:
2420e35cf81dSBarry Smith +  snes - the SNES context
2421e35cf81dSBarry 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
2422fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
2423e35cf81dSBarry Smith 
2424e35cf81dSBarry Smith    Options Database Keys:
2425e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2426e35cf81dSBarry Smith 
2427e35cf81dSBarry Smith    Notes:
2428e35cf81dSBarry Smith    The default is 1
2429e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2430fe3ffe1eSBarry 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
2431fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
2432e35cf81dSBarry Smith 
2433e35cf81dSBarry Smith    Level: intermediate
2434e35cf81dSBarry Smith 
2435e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2436e35cf81dSBarry Smith 
2437e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
2438e35cf81dSBarry Smith 
2439e35cf81dSBarry Smith @*/
24407087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
2441e35cf81dSBarry Smith {
2442e35cf81dSBarry Smith   PetscFunctionBegin;
24430700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2444e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2445e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2446c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2447e35cf81dSBarry Smith   snes->lagjacobian = lag;
2448e35cf81dSBarry Smith   PetscFunctionReturn(0);
2449e35cf81dSBarry Smith }
2450e35cf81dSBarry Smith 
2451e35cf81dSBarry Smith #undef __FUNCT__
2452e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
2453e35cf81dSBarry Smith /*@
2454e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
2455e35cf81dSBarry Smith 
24563f9fe445SBarry Smith    Not Collective
2457e35cf81dSBarry Smith 
2458e35cf81dSBarry Smith    Input Parameter:
2459e35cf81dSBarry Smith .  snes - the SNES context
2460e35cf81dSBarry Smith 
2461e35cf81dSBarry Smith    Output Parameter:
2462e35cf81dSBarry 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
2463e35cf81dSBarry Smith          the Jacobian is built etc.
2464e35cf81dSBarry Smith 
2465e35cf81dSBarry Smith    Options Database Keys:
2466e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2467e35cf81dSBarry Smith 
2468e35cf81dSBarry Smith    Notes:
2469e35cf81dSBarry Smith    The default is 1
2470e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2471e35cf81dSBarry Smith 
2472e35cf81dSBarry Smith    Level: intermediate
2473e35cf81dSBarry Smith 
2474e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2475e35cf81dSBarry Smith 
2476e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
2477e35cf81dSBarry Smith 
2478e35cf81dSBarry Smith @*/
24797087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
2480e35cf81dSBarry Smith {
2481e35cf81dSBarry Smith   PetscFunctionBegin;
24820700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2483e35cf81dSBarry Smith   *lag = snes->lagjacobian;
2484e35cf81dSBarry Smith   PetscFunctionReturn(0);
2485e35cf81dSBarry Smith }
2486e35cf81dSBarry Smith 
2487e35cf81dSBarry Smith #undef __FUNCT__
24884a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
24899b94acceSBarry Smith /*@
2490d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
24919b94acceSBarry Smith 
24923f9fe445SBarry Smith    Logically Collective on SNES
2493c7afd0dbSLois Curfman McInnes 
24949b94acceSBarry Smith    Input Parameters:
2495c7afd0dbSLois Curfman McInnes +  snes - the SNES context
249670441072SBarry Smith .  abstol - absolute convergence tolerance
249733174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
249833174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
249933174efeSLois Curfman McInnes            of the change in the solution between steps
250033174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2501c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2502fee21e36SBarry Smith 
250333174efeSLois Curfman McInnes    Options Database Keys:
250470441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
2505c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
2506c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
2507c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
2508c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
25099b94acceSBarry Smith 
2510d7a720efSLois Curfman McInnes    Notes:
25119b94acceSBarry Smith    The default maximum number of iterations is 50.
25129b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
25139b94acceSBarry Smith 
251436851e7fSLois Curfman McInnes    Level: intermediate
251536851e7fSLois Curfman McInnes 
251633174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
25179b94acceSBarry Smith 
25182492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
25199b94acceSBarry Smith @*/
25207087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
25219b94acceSBarry Smith {
25223a40ed3dSBarry Smith   PetscFunctionBegin;
25230700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2524c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
2525c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
2526c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
2527c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
2528c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
2529c5eb9154SBarry Smith 
2530ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
2531ab54825eSJed Brown     if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol);
2532ab54825eSJed Brown     snes->abstol = abstol;
2533ab54825eSJed Brown   }
2534ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
2535ab54825eSJed 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);
2536ab54825eSJed Brown     snes->rtol = rtol;
2537ab54825eSJed Brown   }
2538ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
2539ab54825eSJed Brown     if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol);
2540*c60f73f4SPeter Brune     snes->stol = stol;
2541ab54825eSJed Brown   }
2542ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
2543ab54825eSJed Brown     if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
2544ab54825eSJed Brown     snes->max_its = maxit;
2545ab54825eSJed Brown   }
2546ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
2547ab54825eSJed Brown     if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
2548ab54825eSJed Brown     snes->max_funcs = maxf;
2549ab54825eSJed Brown   }
25503a40ed3dSBarry Smith   PetscFunctionReturn(0);
25519b94acceSBarry Smith }
25529b94acceSBarry Smith 
25534a2ae208SSatish Balay #undef __FUNCT__
25544a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
25559b94acceSBarry Smith /*@
255633174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
255733174efeSLois Curfman McInnes 
2558c7afd0dbSLois Curfman McInnes    Not Collective
2559c7afd0dbSLois Curfman McInnes 
256033174efeSLois Curfman McInnes    Input Parameters:
2561c7afd0dbSLois Curfman McInnes +  snes - the SNES context
256285385478SLisandro Dalcin .  atol - absolute convergence tolerance
256333174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
256433174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
256533174efeSLois Curfman McInnes            of the change in the solution between steps
256633174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2567c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2568fee21e36SBarry Smith 
256933174efeSLois Curfman McInnes    Notes:
257033174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
257133174efeSLois Curfman McInnes 
257236851e7fSLois Curfman McInnes    Level: intermediate
257336851e7fSLois Curfman McInnes 
257433174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
257533174efeSLois Curfman McInnes 
257633174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
257733174efeSLois Curfman McInnes @*/
25787087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
257933174efeSLois Curfman McInnes {
25803a40ed3dSBarry Smith   PetscFunctionBegin;
25810700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
258285385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
258333174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
2584*c60f73f4SPeter Brune   if (stol)  *stol  = snes->stol;
258533174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
258633174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
25873a40ed3dSBarry Smith   PetscFunctionReturn(0);
258833174efeSLois Curfman McInnes }
258933174efeSLois Curfman McInnes 
25904a2ae208SSatish Balay #undef __FUNCT__
25914a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
259233174efeSLois Curfman McInnes /*@
25939b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
25949b94acceSBarry Smith 
25953f9fe445SBarry Smith    Logically Collective on SNES
2596fee21e36SBarry Smith 
2597c7afd0dbSLois Curfman McInnes    Input Parameters:
2598c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2599c7afd0dbSLois Curfman McInnes -  tol - tolerance
2600c7afd0dbSLois Curfman McInnes 
26019b94acceSBarry Smith    Options Database Key:
2602c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
26039b94acceSBarry Smith 
260436851e7fSLois Curfman McInnes    Level: intermediate
260536851e7fSLois Curfman McInnes 
26069b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
26079b94acceSBarry Smith 
26082492ecdbSBarry Smith .seealso: SNESSetTolerances()
26099b94acceSBarry Smith @*/
26107087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
26119b94acceSBarry Smith {
26123a40ed3dSBarry Smith   PetscFunctionBegin;
26130700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2614c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
26159b94acceSBarry Smith   snes->deltatol = tol;
26163a40ed3dSBarry Smith   PetscFunctionReturn(0);
26179b94acceSBarry Smith }
26189b94acceSBarry Smith 
2619df9fa365SBarry Smith /*
2620df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
2621df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
2622df9fa365SBarry Smith    macros instead of functions
2623df9fa365SBarry Smith */
26244a2ae208SSatish Balay #undef __FUNCT__
2625a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
26267087cfbeSBarry Smith PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2627ce1608b8SBarry Smith {
2628dfbe8321SBarry Smith   PetscErrorCode ierr;
2629ce1608b8SBarry Smith 
2630ce1608b8SBarry Smith   PetscFunctionBegin;
26310700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2632a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
2633ce1608b8SBarry Smith   PetscFunctionReturn(0);
2634ce1608b8SBarry Smith }
2635ce1608b8SBarry Smith 
26364a2ae208SSatish Balay #undef __FUNCT__
2637a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
26387087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2639df9fa365SBarry Smith {
2640dfbe8321SBarry Smith   PetscErrorCode ierr;
2641df9fa365SBarry Smith 
2642df9fa365SBarry Smith   PetscFunctionBegin;
2643a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2644df9fa365SBarry Smith   PetscFunctionReturn(0);
2645df9fa365SBarry Smith }
2646df9fa365SBarry Smith 
26474a2ae208SSatish Balay #undef __FUNCT__
2648a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
26496bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
2650df9fa365SBarry Smith {
2651dfbe8321SBarry Smith   PetscErrorCode ierr;
2652df9fa365SBarry Smith 
2653df9fa365SBarry Smith   PetscFunctionBegin;
2654a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2655df9fa365SBarry Smith   PetscFunctionReturn(0);
2656df9fa365SBarry Smith }
2657df9fa365SBarry Smith 
26587087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
2659b271bb04SBarry Smith #undef __FUNCT__
2660b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
26617087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2662b271bb04SBarry Smith {
2663b271bb04SBarry Smith   PetscDrawLG      lg;
2664b271bb04SBarry Smith   PetscErrorCode   ierr;
2665b271bb04SBarry Smith   PetscReal        x,y,per;
2666b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
2667b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
2668b271bb04SBarry Smith   PetscDraw        draw;
2669b271bb04SBarry Smith   PetscFunctionBegin;
2670b271bb04SBarry Smith   if (!monctx) {
2671b271bb04SBarry Smith     MPI_Comm    comm;
2672b271bb04SBarry Smith 
2673b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2674b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
2675b271bb04SBarry Smith   }
2676b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
2677b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2678b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2679b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
2680b271bb04SBarry Smith   x = (PetscReal) n;
2681b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
2682b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2683b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2684b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2685b271bb04SBarry Smith   }
2686b271bb04SBarry Smith 
2687b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
2688b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2689b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2690b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
2691b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
2692b271bb04SBarry Smith   x = (PetscReal) n;
2693b271bb04SBarry Smith   y = 100.0*per;
2694b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2695b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2696b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2697b271bb04SBarry Smith   }
2698b271bb04SBarry Smith 
2699b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
2700b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2701b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2702b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
2703b271bb04SBarry Smith   x = (PetscReal) n;
2704b271bb04SBarry Smith   y = (prev - rnorm)/prev;
2705b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2706b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2707b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2708b271bb04SBarry Smith   }
2709b271bb04SBarry Smith 
2710b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
2711b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2712b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2713b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
2714b271bb04SBarry Smith   x = (PetscReal) n;
2715b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
2716b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
2717b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2718b271bb04SBarry Smith   }
2719b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2720b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2721b271bb04SBarry Smith   }
2722b271bb04SBarry Smith   prev = rnorm;
2723b271bb04SBarry Smith   PetscFunctionReturn(0);
2724b271bb04SBarry Smith }
2725b271bb04SBarry Smith 
2726b271bb04SBarry Smith #undef __FUNCT__
2727b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
27287087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2729b271bb04SBarry Smith {
2730b271bb04SBarry Smith   PetscErrorCode ierr;
2731b271bb04SBarry Smith 
2732b271bb04SBarry Smith   PetscFunctionBegin;
2733b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2734b271bb04SBarry Smith   PetscFunctionReturn(0);
2735b271bb04SBarry Smith }
2736b271bb04SBarry Smith 
2737b271bb04SBarry Smith #undef __FUNCT__
2738b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
27396bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG *draw)
2740b271bb04SBarry Smith {
2741b271bb04SBarry Smith   PetscErrorCode ierr;
2742b271bb04SBarry Smith 
2743b271bb04SBarry Smith   PetscFunctionBegin;
2744b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2745b271bb04SBarry Smith   PetscFunctionReturn(0);
2746b271bb04SBarry Smith }
2747b271bb04SBarry Smith 
27487a03ce2fSLisandro Dalcin #undef __FUNCT__
27497a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
2750228d79bcSJed Brown /*@
2751228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
2752228d79bcSJed Brown 
2753228d79bcSJed Brown    Collective on SNES
2754228d79bcSJed Brown 
2755228d79bcSJed Brown    Input Parameters:
2756228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
2757228d79bcSJed Brown .  iter - iteration number
2758228d79bcSJed Brown -  rnorm - relative norm of the residual
2759228d79bcSJed Brown 
2760228d79bcSJed Brown    Notes:
2761228d79bcSJed Brown    This routine is called by the SNES implementations.
2762228d79bcSJed Brown    It does not typically need to be called by the user.
2763228d79bcSJed Brown 
2764228d79bcSJed Brown    Level: developer
2765228d79bcSJed Brown 
2766228d79bcSJed Brown .seealso: SNESMonitorSet()
2767228d79bcSJed Brown @*/
27687a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
27697a03ce2fSLisandro Dalcin {
27707a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
27717a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
27727a03ce2fSLisandro Dalcin 
27737a03ce2fSLisandro Dalcin   PetscFunctionBegin;
27747a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
27757a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
27767a03ce2fSLisandro Dalcin   }
27777a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
27787a03ce2fSLisandro Dalcin }
27797a03ce2fSLisandro Dalcin 
27809b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
27819b94acceSBarry Smith 
27824a2ae208SSatish Balay #undef __FUNCT__
2783a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
27849b94acceSBarry Smith /*@C
2785a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
27869b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
27879b94acceSBarry Smith    progress.
27889b94acceSBarry Smith 
27893f9fe445SBarry Smith    Logically Collective on SNES
2790fee21e36SBarry Smith 
2791c7afd0dbSLois Curfman McInnes    Input Parameters:
2792c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2793c7afd0dbSLois Curfman McInnes .  func - monitoring routine
2794b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
2795e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
2796b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
2797b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
27989b94acceSBarry Smith 
2799c7afd0dbSLois Curfman McInnes    Calling sequence of func:
2800a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
2801c7afd0dbSLois Curfman McInnes 
2802c7afd0dbSLois Curfman McInnes +    snes - the SNES context
2803c7afd0dbSLois Curfman McInnes .    its - iteration number
2804c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
280540a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
28069b94acceSBarry Smith 
28079665c990SLois Curfman McInnes    Options Database Keys:
2808a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
2809a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
2810a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
2811cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
2812c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
2813a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
2814c7afd0dbSLois Curfman McInnes                             does not cancel those set via
2815c7afd0dbSLois Curfman McInnes                             the options database.
28169665c990SLois Curfman McInnes 
2817639f9d9dSBarry Smith    Notes:
28186bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
2819a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
28206bc08f3fSLois Curfman McInnes    order in which they were set.
2821639f9d9dSBarry Smith 
2822025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
2823025f1a04SBarry Smith 
282436851e7fSLois Curfman McInnes    Level: intermediate
282536851e7fSLois Curfman McInnes 
28269b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
28279b94acceSBarry Smith 
2828a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
28299b94acceSBarry Smith @*/
2830c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
28319b94acceSBarry Smith {
2832b90d0a6eSBarry Smith   PetscInt       i;
2833649052a6SBarry Smith   PetscErrorCode ierr;
2834b90d0a6eSBarry Smith 
28353a40ed3dSBarry Smith   PetscFunctionBegin;
28360700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
283717186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
2838b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
2839649052a6SBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
2840649052a6SBarry Smith       if (monitordestroy) {
2841c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
2842649052a6SBarry Smith       }
2843b90d0a6eSBarry Smith       PetscFunctionReturn(0);
2844b90d0a6eSBarry Smith     }
2845b90d0a6eSBarry Smith   }
2846b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
2847b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
2848639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
28493a40ed3dSBarry Smith   PetscFunctionReturn(0);
28509b94acceSBarry Smith }
28519b94acceSBarry Smith 
28524a2ae208SSatish Balay #undef __FUNCT__
2853a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
28545cd90555SBarry Smith /*@C
2855a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
28565cd90555SBarry Smith 
28573f9fe445SBarry Smith    Logically Collective on SNES
2858c7afd0dbSLois Curfman McInnes 
28595cd90555SBarry Smith    Input Parameters:
28605cd90555SBarry Smith .  snes - the SNES context
28615cd90555SBarry Smith 
28621a480d89SAdministrator    Options Database Key:
2863a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
2864a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
2865c7afd0dbSLois Curfman McInnes     set via the options database
28665cd90555SBarry Smith 
28675cd90555SBarry Smith    Notes:
28685cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
28695cd90555SBarry Smith 
287036851e7fSLois Curfman McInnes    Level: intermediate
287136851e7fSLois Curfman McInnes 
28725cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
28735cd90555SBarry Smith 
2874a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
28755cd90555SBarry Smith @*/
28767087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
28775cd90555SBarry Smith {
2878d952e501SBarry Smith   PetscErrorCode ierr;
2879d952e501SBarry Smith   PetscInt       i;
2880d952e501SBarry Smith 
28815cd90555SBarry Smith   PetscFunctionBegin;
28820700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2883d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
2884d952e501SBarry Smith     if (snes->monitordestroy[i]) {
28853c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
2886d952e501SBarry Smith     }
2887d952e501SBarry Smith   }
28885cd90555SBarry Smith   snes->numbermonitors = 0;
28895cd90555SBarry Smith   PetscFunctionReturn(0);
28905cd90555SBarry Smith }
28915cd90555SBarry Smith 
28924a2ae208SSatish Balay #undef __FUNCT__
28934a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
28949b94acceSBarry Smith /*@C
28959b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
28969b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
28979b94acceSBarry Smith 
28983f9fe445SBarry Smith    Logically Collective on SNES
2899fee21e36SBarry Smith 
2900c7afd0dbSLois Curfman McInnes    Input Parameters:
2901c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2902c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
29037f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
29047f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
29059b94acceSBarry Smith 
2906c7afd0dbSLois Curfman McInnes    Calling sequence of func:
290706ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
2908c7afd0dbSLois Curfman McInnes 
2909c7afd0dbSLois Curfman McInnes +    snes - the SNES context
291006ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
2911c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
2912184914b5SBarry Smith .    reason - reason for convergence/divergence
2913c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
29144b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
29154b27c08aSLois Curfman McInnes -    f - 2-norm of function
29169b94acceSBarry Smith 
291736851e7fSLois Curfman McInnes    Level: advanced
291836851e7fSLois Curfman McInnes 
29199b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
29209b94acceSBarry Smith 
292185385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
29229b94acceSBarry Smith @*/
29237087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
29249b94acceSBarry Smith {
29257f7931b9SBarry Smith   PetscErrorCode ierr;
29267f7931b9SBarry Smith 
29273a40ed3dSBarry Smith   PetscFunctionBegin;
29280700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
292985385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
29307f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
29317f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
29327f7931b9SBarry Smith   }
293385385478SLisandro Dalcin   snes->ops->converged        = func;
29347f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
293585385478SLisandro Dalcin   snes->cnvP                  = cctx;
29363a40ed3dSBarry Smith   PetscFunctionReturn(0);
29379b94acceSBarry Smith }
29389b94acceSBarry Smith 
29394a2ae208SSatish Balay #undef __FUNCT__
29404a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
294152baeb72SSatish Balay /*@
2942184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
2943184914b5SBarry Smith 
2944184914b5SBarry Smith    Not Collective
2945184914b5SBarry Smith 
2946184914b5SBarry Smith    Input Parameter:
2947184914b5SBarry Smith .  snes - the SNES context
2948184914b5SBarry Smith 
2949184914b5SBarry Smith    Output Parameter:
29504d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
2951184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
2952184914b5SBarry Smith 
2953184914b5SBarry Smith    Level: intermediate
2954184914b5SBarry Smith 
2955184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
2956184914b5SBarry Smith 
2957184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
2958184914b5SBarry Smith 
295985385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
2960184914b5SBarry Smith @*/
29617087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
2962184914b5SBarry Smith {
2963184914b5SBarry Smith   PetscFunctionBegin;
29640700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
29654482741eSBarry Smith   PetscValidPointer(reason,2);
2966184914b5SBarry Smith   *reason = snes->reason;
2967184914b5SBarry Smith   PetscFunctionReturn(0);
2968184914b5SBarry Smith }
2969184914b5SBarry Smith 
29704a2ae208SSatish Balay #undef __FUNCT__
29714a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
2972c9005455SLois Curfman McInnes /*@
2973c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
2974c9005455SLois Curfman McInnes 
29753f9fe445SBarry Smith    Logically Collective on SNES
2976fee21e36SBarry Smith 
2977c7afd0dbSLois Curfman McInnes    Input Parameters:
2978c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
29798c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
2980cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
2981758f92a0SBarry Smith .  na  - size of a and its
298264731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
2983758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
2984c7afd0dbSLois Curfman McInnes 
2985308dcc3eSBarry Smith    Notes:
2986308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
2987308dcc3eSBarry Smith    default array of length 10000 is allocated.
2988308dcc3eSBarry Smith 
2989c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
2990c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
2991c9005455SLois Curfman McInnes    during the section of code that is being timed.
2992c9005455SLois Curfman McInnes 
299336851e7fSLois Curfman McInnes    Level: intermediate
299436851e7fSLois Curfman McInnes 
2995c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
2996758f92a0SBarry Smith 
299708405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
2998758f92a0SBarry Smith 
2999c9005455SLois Curfman McInnes @*/
30007087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
3001c9005455SLois Curfman McInnes {
3002308dcc3eSBarry Smith   PetscErrorCode ierr;
3003308dcc3eSBarry Smith 
30043a40ed3dSBarry Smith   PetscFunctionBegin;
30050700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
30064482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
3007a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
3008308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
3009308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
3010308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
3011308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
3012308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
3013308dcc3eSBarry Smith   }
3014c9005455SLois Curfman McInnes   snes->conv_hist       = a;
3015758f92a0SBarry Smith   snes->conv_hist_its   = its;
3016758f92a0SBarry Smith   snes->conv_hist_max   = na;
3017a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
3018758f92a0SBarry Smith   snes->conv_hist_reset = reset;
3019758f92a0SBarry Smith   PetscFunctionReturn(0);
3020758f92a0SBarry Smith }
3021758f92a0SBarry Smith 
3022308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3023c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
3024c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
3025308dcc3eSBarry Smith EXTERN_C_BEGIN
3026308dcc3eSBarry Smith #undef __FUNCT__
3027308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
3028308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
3029308dcc3eSBarry Smith {
3030308dcc3eSBarry Smith   mxArray        *mat;
3031308dcc3eSBarry Smith   PetscInt       i;
3032308dcc3eSBarry Smith   PetscReal      *ar;
3033308dcc3eSBarry Smith 
3034308dcc3eSBarry Smith   PetscFunctionBegin;
3035308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
3036308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
3037308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
3038308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
3039308dcc3eSBarry Smith   }
3040308dcc3eSBarry Smith   PetscFunctionReturn(mat);
3041308dcc3eSBarry Smith }
3042308dcc3eSBarry Smith EXTERN_C_END
3043308dcc3eSBarry Smith #endif
3044308dcc3eSBarry Smith 
3045308dcc3eSBarry Smith 
30464a2ae208SSatish Balay #undef __FUNCT__
30474a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
30480c4c9dddSBarry Smith /*@C
3049758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
3050758f92a0SBarry Smith 
30513f9fe445SBarry Smith    Not Collective
3052758f92a0SBarry Smith 
3053758f92a0SBarry Smith    Input Parameter:
3054758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
3055758f92a0SBarry Smith 
3056758f92a0SBarry Smith    Output Parameters:
3057758f92a0SBarry Smith .  a   - array to hold history
3058758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
3059758f92a0SBarry Smith          negative if not converged) for each solve.
3060758f92a0SBarry Smith -  na  - size of a and its
3061758f92a0SBarry Smith 
3062758f92a0SBarry Smith    Notes:
3063758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
3064758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
3065758f92a0SBarry Smith 
3066758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
3067758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
3068758f92a0SBarry Smith    during the section of code that is being timed.
3069758f92a0SBarry Smith 
3070758f92a0SBarry Smith    Level: intermediate
3071758f92a0SBarry Smith 
3072758f92a0SBarry Smith .keywords: SNES, get, convergence, history
3073758f92a0SBarry Smith 
3074758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
3075758f92a0SBarry Smith 
3076758f92a0SBarry Smith @*/
30777087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3078758f92a0SBarry Smith {
3079758f92a0SBarry Smith   PetscFunctionBegin;
30800700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3081758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
3082758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
3083758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
30843a40ed3dSBarry Smith   PetscFunctionReturn(0);
3085c9005455SLois Curfman McInnes }
3086c9005455SLois Curfman McInnes 
3087e74ef692SMatthew Knepley #undef __FUNCT__
3088e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
3089ac226902SBarry Smith /*@C
309076b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
3091eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
30927e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
309376b2cf59SMatthew Knepley 
30943f9fe445SBarry Smith   Logically Collective on SNES
309576b2cf59SMatthew Knepley 
309676b2cf59SMatthew Knepley   Input Parameters:
309776b2cf59SMatthew Knepley . snes - The nonlinear solver context
309876b2cf59SMatthew Knepley . func - The function
309976b2cf59SMatthew Knepley 
310076b2cf59SMatthew Knepley   Calling sequence of func:
3101b5d30489SBarry Smith . func (SNES snes, PetscInt step);
310276b2cf59SMatthew Knepley 
310376b2cf59SMatthew Knepley . step - The current step of the iteration
310476b2cf59SMatthew Knepley 
3105fe97e370SBarry Smith   Level: advanced
3106fe97e370SBarry Smith 
3107fe97e370SBarry 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()
3108fe97e370SBarry Smith         This is not used by most users.
310976b2cf59SMatthew Knepley 
311076b2cf59SMatthew Knepley .keywords: SNES, update
3111b5d30489SBarry Smith 
311285385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
311376b2cf59SMatthew Knepley @*/
31147087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
311576b2cf59SMatthew Knepley {
311676b2cf59SMatthew Knepley   PetscFunctionBegin;
31170700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
3118e7788613SBarry Smith   snes->ops->update = func;
311976b2cf59SMatthew Knepley   PetscFunctionReturn(0);
312076b2cf59SMatthew Knepley }
312176b2cf59SMatthew Knepley 
3122e74ef692SMatthew Knepley #undef __FUNCT__
3123e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
312476b2cf59SMatthew Knepley /*@
312576b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
312676b2cf59SMatthew Knepley 
312776b2cf59SMatthew Knepley   Not collective
312876b2cf59SMatthew Knepley 
312976b2cf59SMatthew Knepley   Input Parameters:
313076b2cf59SMatthew Knepley . snes - The nonlinear solver context
313176b2cf59SMatthew Knepley . step - The current step of the iteration
313276b2cf59SMatthew Knepley 
3133205452f4SMatthew Knepley   Level: intermediate
3134205452f4SMatthew Knepley 
313576b2cf59SMatthew Knepley .keywords: SNES, update
3136a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
313776b2cf59SMatthew Knepley @*/
31387087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
313976b2cf59SMatthew Knepley {
314076b2cf59SMatthew Knepley   PetscFunctionBegin;
314176b2cf59SMatthew Knepley   PetscFunctionReturn(0);
314276b2cf59SMatthew Knepley }
314376b2cf59SMatthew Knepley 
31444a2ae208SSatish Balay #undef __FUNCT__
31454a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
31469b94acceSBarry Smith /*
31479b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
31489b94acceSBarry Smith    positive parameter delta.
31499b94acceSBarry Smith 
31509b94acceSBarry Smith     Input Parameters:
3151c7afd0dbSLois Curfman McInnes +   snes - the SNES context
31529b94acceSBarry Smith .   y - approximate solution of linear system
31539b94acceSBarry Smith .   fnorm - 2-norm of current function
3154c7afd0dbSLois Curfman McInnes -   delta - trust region size
31559b94acceSBarry Smith 
31569b94acceSBarry Smith     Output Parameters:
3157c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
31589b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
31599b94acceSBarry Smith     region, and exceeds zero otherwise.
3160c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
31619b94acceSBarry Smith 
31629b94acceSBarry Smith     Note:
31634b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
31649b94acceSBarry Smith     is set to be the maximum allowable step size.
31659b94acceSBarry Smith 
31669b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
31679b94acceSBarry Smith */
3168dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
31699b94acceSBarry Smith {
3170064f8208SBarry Smith   PetscReal      nrm;
3171ea709b57SSatish Balay   PetscScalar    cnorm;
3172dfbe8321SBarry Smith   PetscErrorCode ierr;
31733a40ed3dSBarry Smith 
31743a40ed3dSBarry Smith   PetscFunctionBegin;
31750700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
31760700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3177c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
3178184914b5SBarry Smith 
3179064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
3180064f8208SBarry Smith   if (nrm > *delta) {
3181064f8208SBarry Smith      nrm = *delta/nrm;
3182064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
3183064f8208SBarry Smith      cnorm = nrm;
31842dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
31859b94acceSBarry Smith      *ynorm = *delta;
31869b94acceSBarry Smith   } else {
31879b94acceSBarry Smith      *gpnorm = 0.0;
3188064f8208SBarry Smith      *ynorm = nrm;
31899b94acceSBarry Smith   }
31903a40ed3dSBarry Smith   PetscFunctionReturn(0);
31919b94acceSBarry Smith }
31929b94acceSBarry Smith 
31934a2ae208SSatish Balay #undef __FUNCT__
31944a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
31956ce558aeSBarry Smith /*@C
3196f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
3197f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
31989b94acceSBarry Smith 
3199c7afd0dbSLois Curfman McInnes    Collective on SNES
3200c7afd0dbSLois Curfman McInnes 
3201b2002411SLois Curfman McInnes    Input Parameters:
3202c7afd0dbSLois Curfman McInnes +  snes - the SNES context
32033cebf274SJed Brown .  b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero.
320485385478SLisandro Dalcin -  x - the solution vector.
32059b94acceSBarry Smith 
3206b2002411SLois Curfman McInnes    Notes:
32078ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
32088ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
32098ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
32108ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
32118ddd3da0SLois Curfman McInnes 
321236851e7fSLois Curfman McInnes    Level: beginner
321336851e7fSLois Curfman McInnes 
32149b94acceSBarry Smith .keywords: SNES, nonlinear, solve
32159b94acceSBarry Smith 
3216c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
32179b94acceSBarry Smith @*/
32187087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
32199b94acceSBarry Smith {
3220dfbe8321SBarry Smith   PetscErrorCode ierr;
3221ace3abfcSBarry Smith   PetscBool      flg;
3222eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
3223eabae89aSBarry Smith   PetscViewer    viewer;
3224efd51863SBarry Smith   PetscInt       grid;
3225a69afd8bSBarry Smith   Vec            xcreated = PETSC_NULL;
3226caa4e7f2SJed Brown   DM             dm;
3227052efed2SBarry Smith 
32283a40ed3dSBarry Smith   PetscFunctionBegin;
32290700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3230a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3231a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
32320700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
323385385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
323485385478SLisandro Dalcin 
3235caa4e7f2SJed Brown   if (!x) {
3236caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3237caa4e7f2SJed Brown     ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr);
3238a69afd8bSBarry Smith     x    = xcreated;
3239a69afd8bSBarry Smith   }
3240a69afd8bSBarry Smith 
3241a8248277SBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);}
3242efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
3243efd51863SBarry Smith 
324485385478SLisandro Dalcin     /* set solution vector */
3245efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
32466bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
324785385478SLisandro Dalcin     snes->vec_sol = x;
3248caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3249caa4e7f2SJed Brown     ierr = DMSNESSetSolution(snes->dm,snes->vec_sol);CHKERRQ(ierr); /* Post the solution vector so that it can be restricted to coarse levels for KSP */
3250caa4e7f2SJed Brown 
3251caa4e7f2SJed Brown     /* set affine vector if provided */
325285385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
32536bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
325485385478SLisandro Dalcin     snes->vec_rhs = b;
325585385478SLisandro Dalcin 
325670e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
32573f149594SLisandro Dalcin 
32587eee914bSBarry Smith     if (!grid) {
32597eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
3260d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
3261dd568438SSatish Balay       } else if (snes->dm) {
3262dd568438SSatish Balay         PetscBool ig;
3263dd568438SSatish Balay         ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr);
3264dd568438SSatish Balay         if (ig) {
32657eee914bSBarry Smith           ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr);
32667eee914bSBarry Smith         }
3267d25893d9SBarry Smith       }
3268dd568438SSatish Balay     }
3269d25893d9SBarry Smith 
3270abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
327150ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
3272d5e45103SBarry Smith 
32733f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
32744936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
327585385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
32764936397dSBarry Smith     if (snes->domainerror){
32774936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
32784936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
32794936397dSBarry Smith     }
328017186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
3281caa4e7f2SJed Brown     ierr = DMSNESSetSolution(snes->dm,PETSC_NULL);CHKERRQ(ierr); /* Un-post solution because inner contexts are done using it */
32823f149594SLisandro Dalcin 
32837adad957SLisandro Dalcin     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
3284eabae89aSBarry Smith     if (flg && !PetscPreLoadingOn) {
32857adad957SLisandro Dalcin       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
3286eabae89aSBarry Smith       ierr = SNESView(snes,viewer);CHKERRQ(ierr);
32876bf464f9SBarry Smith       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3288eabae89aSBarry Smith     }
3289eabae89aSBarry Smith 
329090d69ab7SBarry Smith     flg  = PETSC_FALSE;
3291acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
3292da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
32935968eb51SBarry Smith     if (snes->printreason) {
3294a8248277SBarry Smith       ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
32955968eb51SBarry Smith       if (snes->reason > 0) {
3296c7e7b494SJed 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);
32975968eb51SBarry Smith       } else {
3298c7e7b494SJed 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);
32995968eb51SBarry Smith       }
3300a8248277SBarry Smith       ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
33015968eb51SBarry Smith     }
33025968eb51SBarry Smith 
33038501fc72SJed Brown     flg = PETSC_FALSE;
33048501fc72SJed Brown     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
33058501fc72SJed Brown     if (flg) {
33068501fc72SJed Brown       PetscViewer viewer;
33078501fc72SJed Brown       ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
33088501fc72SJed Brown       ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr);
33098501fc72SJed Brown       ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr);
33108501fc72SJed Brown       ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr);
33118501fc72SJed Brown       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
33128501fc72SJed Brown     }
33138501fc72SJed Brown 
3314e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
3315efd51863SBarry Smith     if (grid <  snes->gridsequence) {
3316efd51863SBarry Smith       DM  fine;
3317efd51863SBarry Smith       Vec xnew;
3318efd51863SBarry Smith       Mat interp;
3319efd51863SBarry Smith 
3320efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
3321e727c939SJed Brown       ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
3322efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
3323efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
3324efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
3325efd51863SBarry Smith       x    = xnew;
3326efd51863SBarry Smith 
3327efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
3328efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
3329efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
3330a8248277SBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);
3331efd51863SBarry Smith     }
3332efd51863SBarry Smith   }
3333a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
33343a40ed3dSBarry Smith   PetscFunctionReturn(0);
33359b94acceSBarry Smith }
33369b94acceSBarry Smith 
33379b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
33389b94acceSBarry Smith 
33394a2ae208SSatish Balay #undef __FUNCT__
33404a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
334182bf6240SBarry Smith /*@C
33424b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
33439b94acceSBarry Smith 
3344fee21e36SBarry Smith    Collective on SNES
3345fee21e36SBarry Smith 
3346c7afd0dbSLois Curfman McInnes    Input Parameters:
3347c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3348454a90a3SBarry Smith -  type - a known method
3349c7afd0dbSLois Curfman McInnes 
3350c7afd0dbSLois Curfman McInnes    Options Database Key:
3351454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
3352c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
3353ae12b187SLois Curfman McInnes 
33549b94acceSBarry Smith    Notes:
3355e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
33564b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
3357c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
33584b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
3359c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
33609b94acceSBarry Smith 
3361ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
3362ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
3363ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
3364ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
3365ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
3366ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
3367ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
3368ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
3369ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
3370b0a32e0cSBarry Smith   appropriate method.
337136851e7fSLois Curfman McInnes 
337236851e7fSLois Curfman McInnes   Level: intermediate
3373a703fe33SLois Curfman McInnes 
3374454a90a3SBarry Smith .keywords: SNES, set, type
3375435da068SBarry Smith 
3376435da068SBarry Smith .seealso: SNESType, SNESCreate()
3377435da068SBarry Smith 
33789b94acceSBarry Smith @*/
33797087cfbeSBarry Smith PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
33809b94acceSBarry Smith {
3381dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
3382ace3abfcSBarry Smith   PetscBool      match;
33833a40ed3dSBarry Smith 
33843a40ed3dSBarry Smith   PetscFunctionBegin;
33850700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
33864482741eSBarry Smith   PetscValidCharPointer(type,2);
338782bf6240SBarry Smith 
33886831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
33890f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
339092ff6ae8SBarry Smith 
33914b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
3392e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
339375396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
3394b5c23020SJed Brown   if (snes->ops->destroy) {
3395b5c23020SJed Brown     ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
3396b5c23020SJed Brown     snes->ops->destroy = PETSC_NULL;
3397b5c23020SJed Brown   }
339875396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
339975396ef9SLisandro Dalcin   snes->ops->setup          = 0;
340075396ef9SLisandro Dalcin   snes->ops->solve          = 0;
340175396ef9SLisandro Dalcin   snes->ops->view           = 0;
340275396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
340375396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
340475396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
340575396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
3406454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
340703bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
34089fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
34099fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
34109fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
34119fb22e1aSBarry Smith   }
34129fb22e1aSBarry Smith #endif
34133a40ed3dSBarry Smith   PetscFunctionReturn(0);
34149b94acceSBarry Smith }
34159b94acceSBarry Smith 
3416a847f771SSatish Balay 
34179b94acceSBarry Smith /* --------------------------------------------------------------------- */
34184a2ae208SSatish Balay #undef __FUNCT__
34194a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
342052baeb72SSatish Balay /*@
34219b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
3422f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
34239b94acceSBarry Smith 
3424fee21e36SBarry Smith    Not Collective
3425fee21e36SBarry Smith 
342636851e7fSLois Curfman McInnes    Level: advanced
342736851e7fSLois Curfman McInnes 
34289b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
34299b94acceSBarry Smith 
34309b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
34319b94acceSBarry Smith @*/
34327087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
34339b94acceSBarry Smith {
3434dfbe8321SBarry Smith   PetscErrorCode ierr;
343582bf6240SBarry Smith 
34363a40ed3dSBarry Smith   PetscFunctionBegin;
34371441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
34384c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
34393a40ed3dSBarry Smith   PetscFunctionReturn(0);
34409b94acceSBarry Smith }
34419b94acceSBarry Smith 
34424a2ae208SSatish Balay #undef __FUNCT__
34434a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
34449b94acceSBarry Smith /*@C
34459a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
34469b94acceSBarry Smith 
3447c7afd0dbSLois Curfman McInnes    Not Collective
3448c7afd0dbSLois Curfman McInnes 
34499b94acceSBarry Smith    Input Parameter:
34504b0e389bSBarry Smith .  snes - nonlinear solver context
34519b94acceSBarry Smith 
34529b94acceSBarry Smith    Output Parameter:
34533a7fca6bSBarry Smith .  type - SNES method (a character string)
34549b94acceSBarry Smith 
345536851e7fSLois Curfman McInnes    Level: intermediate
345636851e7fSLois Curfman McInnes 
3457454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
34589b94acceSBarry Smith @*/
34597087cfbeSBarry Smith PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
34609b94acceSBarry Smith {
34613a40ed3dSBarry Smith   PetscFunctionBegin;
34620700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
34634482741eSBarry Smith   PetscValidPointer(type,2);
34647adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
34653a40ed3dSBarry Smith   PetscFunctionReturn(0);
34669b94acceSBarry Smith }
34679b94acceSBarry Smith 
34684a2ae208SSatish Balay #undef __FUNCT__
34694a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
347052baeb72SSatish Balay /*@
34719b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
3472c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
34739b94acceSBarry Smith 
3474c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3475c7afd0dbSLois Curfman McInnes 
34769b94acceSBarry Smith    Input Parameter:
34779b94acceSBarry Smith .  snes - the SNES context
34789b94acceSBarry Smith 
34799b94acceSBarry Smith    Output Parameter:
34809b94acceSBarry Smith .  x - the solution
34819b94acceSBarry Smith 
348270e92668SMatthew Knepley    Level: intermediate
348336851e7fSLois Curfman McInnes 
34849b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
34859b94acceSBarry Smith 
348685385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
34879b94acceSBarry Smith @*/
34887087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
34899b94acceSBarry Smith {
34903a40ed3dSBarry Smith   PetscFunctionBegin;
34910700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
34924482741eSBarry Smith   PetscValidPointer(x,2);
349385385478SLisandro Dalcin   *x = snes->vec_sol;
349470e92668SMatthew Knepley   PetscFunctionReturn(0);
349570e92668SMatthew Knepley }
349670e92668SMatthew Knepley 
349770e92668SMatthew Knepley #undef __FUNCT__
34984a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
349952baeb72SSatish Balay /*@
35009b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
35019b94acceSBarry Smith    stored.
35029b94acceSBarry Smith 
3503c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3504c7afd0dbSLois Curfman McInnes 
35059b94acceSBarry Smith    Input Parameter:
35069b94acceSBarry Smith .  snes - the SNES context
35079b94acceSBarry Smith 
35089b94acceSBarry Smith    Output Parameter:
35099b94acceSBarry Smith .  x - the solution update
35109b94acceSBarry Smith 
351136851e7fSLois Curfman McInnes    Level: advanced
351236851e7fSLois Curfman McInnes 
35139b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
35149b94acceSBarry Smith 
351585385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
35169b94acceSBarry Smith @*/
35177087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
35189b94acceSBarry Smith {
35193a40ed3dSBarry Smith   PetscFunctionBegin;
35200700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35214482741eSBarry Smith   PetscValidPointer(x,2);
352285385478SLisandro Dalcin   *x = snes->vec_sol_update;
35233a40ed3dSBarry Smith   PetscFunctionReturn(0);
35249b94acceSBarry Smith }
35259b94acceSBarry Smith 
35264a2ae208SSatish Balay #undef __FUNCT__
35274a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
35289b94acceSBarry Smith /*@C
35293638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
35309b94acceSBarry Smith 
3531a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
3532c7afd0dbSLois Curfman McInnes 
35339b94acceSBarry Smith    Input Parameter:
35349b94acceSBarry Smith .  snes - the SNES context
35359b94acceSBarry Smith 
35369b94acceSBarry Smith    Output Parameter:
35377bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
353870e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
353970e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
35409b94acceSBarry Smith 
354136851e7fSLois Curfman McInnes    Level: advanced
354236851e7fSLois Curfman McInnes 
3543a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
35449b94acceSBarry Smith 
35454b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
35469b94acceSBarry Smith @*/
35477087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
35489b94acceSBarry Smith {
3549a63bb30eSJed Brown   PetscErrorCode ierr;
35506cab3a1bSJed Brown   DM             dm;
3551a63bb30eSJed Brown 
35523a40ed3dSBarry Smith   PetscFunctionBegin;
35530700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3554a63bb30eSJed Brown   if (r) {
3555a63bb30eSJed Brown     if (!snes->vec_func) {
3556a63bb30eSJed Brown       if (snes->vec_rhs) {
3557a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
3558a63bb30eSJed Brown       } else if (snes->vec_sol) {
3559a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
3560a63bb30eSJed Brown       } else if (snes->dm) {
3561a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
3562a63bb30eSJed Brown       }
3563a63bb30eSJed Brown     }
3564a63bb30eSJed Brown     *r = snes->vec_func;
3565a63bb30eSJed Brown   }
35666cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
35676cab3a1bSJed Brown   ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr);
35683a40ed3dSBarry Smith   PetscFunctionReturn(0);
35699b94acceSBarry Smith }
35709b94acceSBarry Smith 
3571c79ef259SPeter Brune /*@C
3572c79ef259SPeter Brune    SNESGetGS - Returns the GS function and context.
3573c79ef259SPeter Brune 
3574c79ef259SPeter Brune    Input Parameter:
3575c79ef259SPeter Brune .  snes - the SNES context
3576c79ef259SPeter Brune 
3577c79ef259SPeter Brune    Output Parameter:
3578c79ef259SPeter Brune +  gsfunc - the function (or PETSC_NULL)
3579c79ef259SPeter Brune -  ctx    - the function context (or PETSC_NULL)
3580c79ef259SPeter Brune 
3581c79ef259SPeter Brune    Level: advanced
3582c79ef259SPeter Brune 
3583c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
3584c79ef259SPeter Brune 
3585c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction()
3586c79ef259SPeter Brune @*/
3587c79ef259SPeter Brune 
35884a2ae208SSatish Balay #undef __FUNCT__
3589646217ecSPeter Brune #define __FUNCT__ "SNESGetGS"
3590646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx)
3591646217ecSPeter Brune {
35926cab3a1bSJed Brown   PetscErrorCode ierr;
35936cab3a1bSJed Brown   DM             dm;
35946cab3a1bSJed Brown 
3595646217ecSPeter Brune   PetscFunctionBegin;
3596646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35976cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
35986cab3a1bSJed Brown   ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr);
3599646217ecSPeter Brune   PetscFunctionReturn(0);
3600646217ecSPeter Brune }
3601646217ecSPeter Brune 
36024a2ae208SSatish Balay #undef __FUNCT__
36034a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
36043c7409f5SSatish Balay /*@C
36053c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
3606d850072dSLois Curfman McInnes    SNES options in the database.
36073c7409f5SSatish Balay 
36083f9fe445SBarry Smith    Logically Collective on SNES
3609fee21e36SBarry Smith 
3610c7afd0dbSLois Curfman McInnes    Input Parameter:
3611c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3612c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3613c7afd0dbSLois Curfman McInnes 
3614d850072dSLois Curfman McInnes    Notes:
3615a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3616c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3617d850072dSLois Curfman McInnes 
361836851e7fSLois Curfman McInnes    Level: advanced
361936851e7fSLois Curfman McInnes 
36203c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
3621a86d99e1SLois Curfman McInnes 
3622a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
36233c7409f5SSatish Balay @*/
36247087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
36253c7409f5SSatish Balay {
3626dfbe8321SBarry Smith   PetscErrorCode ierr;
36273c7409f5SSatish Balay 
36283a40ed3dSBarry Smith   PetscFunctionBegin;
36290700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3630639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
36311cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
363294b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
36333a40ed3dSBarry Smith   PetscFunctionReturn(0);
36343c7409f5SSatish Balay }
36353c7409f5SSatish Balay 
36364a2ae208SSatish Balay #undef __FUNCT__
36374a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
36383c7409f5SSatish Balay /*@C
3639f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
3640d850072dSLois Curfman McInnes    SNES options in the database.
36413c7409f5SSatish Balay 
36423f9fe445SBarry Smith    Logically Collective on SNES
3643fee21e36SBarry Smith 
3644c7afd0dbSLois Curfman McInnes    Input Parameters:
3645c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3646c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3647c7afd0dbSLois Curfman McInnes 
3648d850072dSLois Curfman McInnes    Notes:
3649a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3650c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3651d850072dSLois Curfman McInnes 
365236851e7fSLois Curfman McInnes    Level: advanced
365336851e7fSLois Curfman McInnes 
36543c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
3655a86d99e1SLois Curfman McInnes 
3656a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
36573c7409f5SSatish Balay @*/
36587087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
36593c7409f5SSatish Balay {
3660dfbe8321SBarry Smith   PetscErrorCode ierr;
36613c7409f5SSatish Balay 
36623a40ed3dSBarry Smith   PetscFunctionBegin;
36630700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3664639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
36651cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
366694b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
36673a40ed3dSBarry Smith   PetscFunctionReturn(0);
36683c7409f5SSatish Balay }
36693c7409f5SSatish Balay 
36704a2ae208SSatish Balay #undef __FUNCT__
36714a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
36729ab63eb5SSatish Balay /*@C
36733c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
36743c7409f5SSatish Balay    SNES options in the database.
36753c7409f5SSatish Balay 
3676c7afd0dbSLois Curfman McInnes    Not Collective
3677c7afd0dbSLois Curfman McInnes 
36783c7409f5SSatish Balay    Input Parameter:
36793c7409f5SSatish Balay .  snes - the SNES context
36803c7409f5SSatish Balay 
36813c7409f5SSatish Balay    Output Parameter:
36823c7409f5SSatish Balay .  prefix - pointer to the prefix string used
36833c7409f5SSatish Balay 
36844ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
36859ab63eb5SSatish Balay    sufficient length to hold the prefix.
36869ab63eb5SSatish Balay 
368736851e7fSLois Curfman McInnes    Level: advanced
368836851e7fSLois Curfman McInnes 
36893c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
3690a86d99e1SLois Curfman McInnes 
3691a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
36923c7409f5SSatish Balay @*/
36937087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
36943c7409f5SSatish Balay {
3695dfbe8321SBarry Smith   PetscErrorCode ierr;
36963c7409f5SSatish Balay 
36973a40ed3dSBarry Smith   PetscFunctionBegin;
36980700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3699639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
37003a40ed3dSBarry Smith   PetscFunctionReturn(0);
37013c7409f5SSatish Balay }
37023c7409f5SSatish Balay 
3703b2002411SLois Curfman McInnes 
37044a2ae208SSatish Balay #undef __FUNCT__
37054a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
37063cea93caSBarry Smith /*@C
37073cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
37083cea93caSBarry Smith 
37097f6c08e0SMatthew Knepley   Level: advanced
37103cea93caSBarry Smith @*/
37117087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
3712b2002411SLois Curfman McInnes {
3713e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
3714dfbe8321SBarry Smith   PetscErrorCode ierr;
3715b2002411SLois Curfman McInnes 
3716b2002411SLois Curfman McInnes   PetscFunctionBegin;
3717b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3718c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3719b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
3720b2002411SLois Curfman McInnes }
3721da9b6338SBarry Smith 
3722da9b6338SBarry Smith #undef __FUNCT__
3723da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
37247087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
3725da9b6338SBarry Smith {
3726dfbe8321SBarry Smith   PetscErrorCode ierr;
372777431f27SBarry Smith   PetscInt       N,i,j;
3728da9b6338SBarry Smith   Vec            u,uh,fh;
3729da9b6338SBarry Smith   PetscScalar    value;
3730da9b6338SBarry Smith   PetscReal      norm;
3731da9b6338SBarry Smith 
3732da9b6338SBarry Smith   PetscFunctionBegin;
3733da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
3734da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
3735da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
3736da9b6338SBarry Smith 
3737da9b6338SBarry Smith   /* currently only works for sequential */
3738da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
3739da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
3740da9b6338SBarry Smith   for (i=0; i<N; i++) {
3741da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
374277431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
3743da9b6338SBarry Smith     for (j=-10; j<11; j++) {
3744ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
3745da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
37463ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
3747da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
374877431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
3749da9b6338SBarry Smith       value = -value;
3750da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
3751da9b6338SBarry Smith     }
3752da9b6338SBarry Smith   }
37536bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
37546bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
3755da9b6338SBarry Smith   PetscFunctionReturn(0);
3756da9b6338SBarry Smith }
375771f87433Sdalcinl 
375871f87433Sdalcinl #undef __FUNCT__
3759fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
376071f87433Sdalcinl /*@
3761fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
376271f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
376371f87433Sdalcinl    Newton method.
376471f87433Sdalcinl 
37653f9fe445SBarry Smith    Logically Collective on SNES
376671f87433Sdalcinl 
376771f87433Sdalcinl    Input Parameters:
376871f87433Sdalcinl +  snes - SNES context
376971f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
377071f87433Sdalcinl 
377164ba62caSBarry Smith     Options Database:
377264ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
377364ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
377464ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
377564ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
377664ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
377764ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
377864ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
377964ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
378064ba62caSBarry Smith 
378171f87433Sdalcinl    Notes:
378271f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
378371f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
378471f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
378571f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
378671f87433Sdalcinl    solver.
378771f87433Sdalcinl 
378871f87433Sdalcinl    Level: advanced
378971f87433Sdalcinl 
379071f87433Sdalcinl    Reference:
379171f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
379271f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
379371f87433Sdalcinl 
379471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
379571f87433Sdalcinl 
3796fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
379771f87433Sdalcinl @*/
37987087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
379971f87433Sdalcinl {
380071f87433Sdalcinl   PetscFunctionBegin;
38010700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3802acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
380371f87433Sdalcinl   snes->ksp_ewconv = flag;
380471f87433Sdalcinl   PetscFunctionReturn(0);
380571f87433Sdalcinl }
380671f87433Sdalcinl 
380771f87433Sdalcinl #undef __FUNCT__
3808fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
380971f87433Sdalcinl /*@
3810fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
381171f87433Sdalcinl    for computing relative tolerance for linear solvers within an
381271f87433Sdalcinl    inexact Newton method.
381371f87433Sdalcinl 
381471f87433Sdalcinl    Not Collective
381571f87433Sdalcinl 
381671f87433Sdalcinl    Input Parameter:
381771f87433Sdalcinl .  snes - SNES context
381871f87433Sdalcinl 
381971f87433Sdalcinl    Output Parameter:
382071f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
382171f87433Sdalcinl 
382271f87433Sdalcinl    Notes:
382371f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
382471f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
382571f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
382671f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
382771f87433Sdalcinl    solver.
382871f87433Sdalcinl 
382971f87433Sdalcinl    Level: advanced
383071f87433Sdalcinl 
383171f87433Sdalcinl    Reference:
383271f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
383371f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
383471f87433Sdalcinl 
383571f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
383671f87433Sdalcinl 
3837fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
383871f87433Sdalcinl @*/
38397087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
384071f87433Sdalcinl {
384171f87433Sdalcinl   PetscFunctionBegin;
38420700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
384371f87433Sdalcinl   PetscValidPointer(flag,2);
384471f87433Sdalcinl   *flag = snes->ksp_ewconv;
384571f87433Sdalcinl   PetscFunctionReturn(0);
384671f87433Sdalcinl }
384771f87433Sdalcinl 
384871f87433Sdalcinl #undef __FUNCT__
3849fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
385071f87433Sdalcinl /*@
3851fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
385271f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
385371f87433Sdalcinl    Newton method.
385471f87433Sdalcinl 
38553f9fe445SBarry Smith    Logically Collective on SNES
385671f87433Sdalcinl 
385771f87433Sdalcinl    Input Parameters:
385871f87433Sdalcinl +    snes - SNES context
385971f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
386071f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
386171f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
386271f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
386371f87433Sdalcinl              (0 <= gamma2 <= 1)
386471f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
386571f87433Sdalcinl .    alpha2 - power for safeguard
386671f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
386771f87433Sdalcinl 
386871f87433Sdalcinl    Note:
386971f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
387071f87433Sdalcinl 
387171f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
387271f87433Sdalcinl 
387371f87433Sdalcinl    Level: advanced
387471f87433Sdalcinl 
387571f87433Sdalcinl    Reference:
387671f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
387771f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
387871f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
387971f87433Sdalcinl 
388071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
388171f87433Sdalcinl 
3882fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
388371f87433Sdalcinl @*/
38847087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
388571f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
388671f87433Sdalcinl {
3887fa9f3622SBarry Smith   SNESKSPEW *kctx;
388871f87433Sdalcinl   PetscFunctionBegin;
38890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3890fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3891e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
3892c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
3893c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
3894c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
3895c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
3896c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
3897c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
3898c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
389971f87433Sdalcinl 
390071f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
390171f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
390271f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
390371f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
390471f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
390571f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
390671f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
390771f87433Sdalcinl 
390871f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
3909e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
391071f87433Sdalcinl   }
391171f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
3912e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
391371f87433Sdalcinl   }
391471f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
3915e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
391671f87433Sdalcinl   }
391771f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
3918e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
391971f87433Sdalcinl   }
392071f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
3921e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
392271f87433Sdalcinl   }
392371f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
3924e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
392571f87433Sdalcinl   }
392671f87433Sdalcinl   PetscFunctionReturn(0);
392771f87433Sdalcinl }
392871f87433Sdalcinl 
392971f87433Sdalcinl #undef __FUNCT__
3930fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
393171f87433Sdalcinl /*@
3932fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
393371f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
393471f87433Sdalcinl    Newton method.
393571f87433Sdalcinl 
393671f87433Sdalcinl    Not Collective
393771f87433Sdalcinl 
393871f87433Sdalcinl    Input Parameters:
393971f87433Sdalcinl      snes - SNES context
394071f87433Sdalcinl 
394171f87433Sdalcinl    Output Parameters:
394271f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
394371f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
394471f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
394571f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
394671f87433Sdalcinl              (0 <= gamma2 <= 1)
394771f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
394871f87433Sdalcinl .    alpha2 - power for safeguard
394971f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
395071f87433Sdalcinl 
395171f87433Sdalcinl    Level: advanced
395271f87433Sdalcinl 
395371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
395471f87433Sdalcinl 
3955fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
395671f87433Sdalcinl @*/
39577087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
395871f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
395971f87433Sdalcinl {
3960fa9f3622SBarry Smith   SNESKSPEW *kctx;
396171f87433Sdalcinl   PetscFunctionBegin;
39620700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3963fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3964e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
396571f87433Sdalcinl   if(version)   *version   = kctx->version;
396671f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
396771f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
396871f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
396971f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
397071f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
397171f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
397271f87433Sdalcinl   PetscFunctionReturn(0);
397371f87433Sdalcinl }
397471f87433Sdalcinl 
397571f87433Sdalcinl #undef __FUNCT__
3976fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
3977fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
397871f87433Sdalcinl {
397971f87433Sdalcinl   PetscErrorCode ierr;
3980fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
398171f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
398271f87433Sdalcinl 
398371f87433Sdalcinl   PetscFunctionBegin;
3984e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
398571f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
398671f87433Sdalcinl     rtol = kctx->rtol_0;
398771f87433Sdalcinl   } else {
398871f87433Sdalcinl     if (kctx->version == 1) {
398971f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
399071f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
399171f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
399271f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
399371f87433Sdalcinl     } else if (kctx->version == 2) {
399471f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
399571f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
399671f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
399771f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
399871f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
399971f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
400071f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
400171f87433Sdalcinl       stol = PetscMax(rtol,stol);
400271f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
400371f87433Sdalcinl       /* safeguard: avoid oversolving */
400471f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
400571f87433Sdalcinl       stol = PetscMax(rtol,stol);
400671f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
4007e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
400871f87433Sdalcinl   }
400971f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
401071f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
401171f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
401271f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
401371f87433Sdalcinl   PetscFunctionReturn(0);
401471f87433Sdalcinl }
401571f87433Sdalcinl 
401671f87433Sdalcinl #undef __FUNCT__
4017fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
4018fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
401971f87433Sdalcinl {
402071f87433Sdalcinl   PetscErrorCode ierr;
4021fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
402271f87433Sdalcinl   PCSide         pcside;
402371f87433Sdalcinl   Vec            lres;
402471f87433Sdalcinl 
402571f87433Sdalcinl   PetscFunctionBegin;
4026e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
402771f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
402871f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
402971f87433Sdalcinl   if (kctx->version == 1) {
4030b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
403171f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
403271f87433Sdalcinl       /* KSP residual is true linear residual */
403371f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
403471f87433Sdalcinl     } else {
403571f87433Sdalcinl       /* KSP residual is preconditioned residual */
403671f87433Sdalcinl       /* compute true linear residual norm */
403771f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
403871f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
403971f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
404071f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
40416bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
404271f87433Sdalcinl     }
404371f87433Sdalcinl   }
404471f87433Sdalcinl   PetscFunctionReturn(0);
404571f87433Sdalcinl }
404671f87433Sdalcinl 
404771f87433Sdalcinl #undef __FUNCT__
404871f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
404971f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
405071f87433Sdalcinl {
405171f87433Sdalcinl   PetscErrorCode ierr;
405271f87433Sdalcinl 
405371f87433Sdalcinl   PetscFunctionBegin;
4054fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
405571f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
4056fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
405771f87433Sdalcinl   PetscFunctionReturn(0);
405871f87433Sdalcinl }
40596c699258SBarry Smith 
40606c699258SBarry Smith #undef __FUNCT__
40616c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
40626c699258SBarry Smith /*@
40636c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
40646c699258SBarry Smith 
40653f9fe445SBarry Smith    Logically Collective on SNES
40666c699258SBarry Smith 
40676c699258SBarry Smith    Input Parameters:
40686c699258SBarry Smith +  snes - the preconditioner context
40696c699258SBarry Smith -  dm - the dm
40706c699258SBarry Smith 
40716c699258SBarry Smith    Level: intermediate
40726c699258SBarry Smith 
40736c699258SBarry Smith 
40746c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
40756c699258SBarry Smith @*/
40767087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
40776c699258SBarry Smith {
40786c699258SBarry Smith   PetscErrorCode ierr;
4079345fed2cSBarry Smith   KSP            ksp;
40806cab3a1bSJed Brown   SNESDM         sdm;
40816c699258SBarry Smith 
40826c699258SBarry Smith   PetscFunctionBegin;
40830700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4084d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
40856cab3a1bSJed Brown   if (snes->dm) {               /* Move the SNESDM context over to the new DM unless the new DM already has one */
40866cab3a1bSJed Brown     PetscContainer oldcontainer,container;
40876cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr);
40886cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr);
40896cab3a1bSJed Brown     if (oldcontainer && !container) {
40906cab3a1bSJed Brown       ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr);
40916cab3a1bSJed Brown       ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr);
40926cab3a1bSJed Brown       if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */
40936cab3a1bSJed Brown         sdm->originaldm = dm;
40946cab3a1bSJed Brown       }
40956cab3a1bSJed Brown     }
40966bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
40976cab3a1bSJed Brown   }
40986c699258SBarry Smith   snes->dm = dm;
4099345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4100345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4101f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
41022c155ee1SBarry Smith   if (snes->pc) {
41032c155ee1SBarry Smith     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
41042c155ee1SBarry Smith   }
41056c699258SBarry Smith   PetscFunctionReturn(0);
41066c699258SBarry Smith }
41076c699258SBarry Smith 
41086c699258SBarry Smith #undef __FUNCT__
41096c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
41106c699258SBarry Smith /*@
41116c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
41126c699258SBarry Smith 
41133f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
41146c699258SBarry Smith 
41156c699258SBarry Smith    Input Parameter:
41166c699258SBarry Smith . snes - the preconditioner context
41176c699258SBarry Smith 
41186c699258SBarry Smith    Output Parameter:
41196c699258SBarry Smith .  dm - the dm
41206c699258SBarry Smith 
41216c699258SBarry Smith    Level: intermediate
41226c699258SBarry Smith 
41236c699258SBarry Smith 
41246c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
41256c699258SBarry Smith @*/
41267087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
41276c699258SBarry Smith {
41286cab3a1bSJed Brown   PetscErrorCode ierr;
41296cab3a1bSJed Brown 
41306c699258SBarry Smith   PetscFunctionBegin;
41310700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
41326cab3a1bSJed Brown   if (!snes->dm) {
41336cab3a1bSJed Brown     ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr);
41346cab3a1bSJed Brown   }
41356c699258SBarry Smith   *dm = snes->dm;
41366c699258SBarry Smith   PetscFunctionReturn(0);
41376c699258SBarry Smith }
41380807856dSBarry Smith 
413931823bd8SMatthew G Knepley #undef __FUNCT__
414031823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
414131823bd8SMatthew G Knepley /*@
4142fd4b34e9SJed Brown   SNESSetPC - Sets the nonlinear preconditioner to be used.
414331823bd8SMatthew G Knepley 
414431823bd8SMatthew G Knepley   Collective on SNES
414531823bd8SMatthew G Knepley 
414631823bd8SMatthew G Knepley   Input Parameters:
414731823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
414831823bd8SMatthew G Knepley - pc   - the preconditioner object
414931823bd8SMatthew G Knepley 
415031823bd8SMatthew G Knepley   Notes:
415131823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
415231823bd8SMatthew G Knepley   to configure it using the API).
415331823bd8SMatthew G Knepley 
415431823bd8SMatthew G Knepley   Level: developer
415531823bd8SMatthew G Knepley 
415631823bd8SMatthew G Knepley .keywords: SNES, set, precondition
415731823bd8SMatthew G Knepley .seealso: SNESGetPC()
415831823bd8SMatthew G Knepley @*/
415931823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
416031823bd8SMatthew G Knepley {
416131823bd8SMatthew G Knepley   PetscErrorCode ierr;
416231823bd8SMatthew G Knepley 
416331823bd8SMatthew G Knepley   PetscFunctionBegin;
416431823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
416531823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
416631823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
416731823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4168bf11d3b6SBarry Smith   ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr);
416931823bd8SMatthew G Knepley   snes->pc = pc;
417031823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
417131823bd8SMatthew G Knepley   PetscFunctionReturn(0);
417231823bd8SMatthew G Knepley }
417331823bd8SMatthew G Knepley 
417431823bd8SMatthew G Knepley #undef __FUNCT__
417531823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
417631823bd8SMatthew G Knepley /*@
4177fd4b34e9SJed Brown   SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().
417831823bd8SMatthew G Knepley 
417931823bd8SMatthew G Knepley   Not Collective
418031823bd8SMatthew G Knepley 
418131823bd8SMatthew G Knepley   Input Parameter:
418231823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
418331823bd8SMatthew G Knepley 
418431823bd8SMatthew G Knepley   Output Parameter:
418531823bd8SMatthew G Knepley . pc - preconditioner context
418631823bd8SMatthew G Knepley 
418731823bd8SMatthew G Knepley   Level: developer
418831823bd8SMatthew G Knepley 
418931823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
419031823bd8SMatthew G Knepley .seealso: SNESSetPC()
419131823bd8SMatthew G Knepley @*/
419231823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
419331823bd8SMatthew G Knepley {
419431823bd8SMatthew G Knepley   PetscErrorCode ierr;
419531823bd8SMatthew G Knepley 
419631823bd8SMatthew G Knepley   PetscFunctionBegin;
419731823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
419831823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
419931823bd8SMatthew G Knepley   if (!snes->pc) {
420031823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr);
42014a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr);
420231823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
420331823bd8SMatthew G Knepley   }
420431823bd8SMatthew G Knepley   *pc = snes->pc;
420531823bd8SMatthew G Knepley   PetscFunctionReturn(0);
420631823bd8SMatthew G Knepley }
420731823bd8SMatthew G Knepley 
42089e764e56SPeter Brune #undef __FUNCT__
4209f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch"
42109e764e56SPeter Brune /*@
4211f1c6b773SPeter Brune   SNESSetSNESLineSearch - Sets the linesearch.
42129e764e56SPeter Brune 
42139e764e56SPeter Brune   Collective on SNES
42149e764e56SPeter Brune 
42159e764e56SPeter Brune   Input Parameters:
42169e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
42179e764e56SPeter Brune - linesearch   - the linesearch object
42189e764e56SPeter Brune 
42199e764e56SPeter Brune   Notes:
4220f1c6b773SPeter Brune   Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example,
42219e764e56SPeter Brune   to configure it using the API).
42229e764e56SPeter Brune 
42239e764e56SPeter Brune   Level: developer
42249e764e56SPeter Brune 
42259e764e56SPeter Brune .keywords: SNES, set, linesearch
4226f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch()
42279e764e56SPeter Brune @*/
4228f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch)
42299e764e56SPeter Brune {
42309e764e56SPeter Brune   PetscErrorCode ierr;
42319e764e56SPeter Brune 
42329e764e56SPeter Brune   PetscFunctionBegin;
42339e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4234f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
42359e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
42369e764e56SPeter Brune   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
4237f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
42389e764e56SPeter Brune   snes->linesearch = linesearch;
42399e764e56SPeter Brune   ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
42409e764e56SPeter Brune   PetscFunctionReturn(0);
42419e764e56SPeter Brune }
42429e764e56SPeter Brune 
42439e764e56SPeter Brune #undef __FUNCT__
4244f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch"
4245ea5d4fccSPeter Brune /*@C
4246f1c6b773SPeter Brune   SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch().
42479e764e56SPeter Brune 
42489e764e56SPeter Brune   Not Collective
42499e764e56SPeter Brune 
42509e764e56SPeter Brune   Input Parameter:
42519e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
42529e764e56SPeter Brune 
42539e764e56SPeter Brune   Output Parameter:
42549e764e56SPeter Brune . linesearch - linesearch context
42559e764e56SPeter Brune 
42569e764e56SPeter Brune   Level: developer
42579e764e56SPeter Brune 
42589e764e56SPeter Brune .keywords: SNES, get, linesearch
4259f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch()
42609e764e56SPeter Brune @*/
4261f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch)
42629e764e56SPeter Brune {
42639e764e56SPeter Brune   PetscErrorCode ierr;
42649e764e56SPeter Brune   const char     *optionsprefix;
42659e764e56SPeter Brune 
42669e764e56SPeter Brune   PetscFunctionBegin;
42679e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
42689e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
42699e764e56SPeter Brune   if (!snes->linesearch) {
42709e764e56SPeter Brune     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
4271f1c6b773SPeter Brune     ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr);
4272f1c6b773SPeter Brune     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
42739e764e56SPeter Brune     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
42749e764e56SPeter Brune     ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
42759e764e56SPeter Brune   }
42769e764e56SPeter Brune   *linesearch = snes->linesearch;
42779e764e56SPeter Brune   PetscFunctionReturn(0);
42789e764e56SPeter Brune }
42799e764e56SPeter Brune 
428069b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4281c6db04a5SJed Brown #include <mex.h>
428269b4f73cSBarry Smith 
42838f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
42848f6e6473SBarry Smith 
42850807856dSBarry Smith #undef __FUNCT__
42860807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
42870807856dSBarry Smith /*
42880807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
42890807856dSBarry Smith                          SNESSetFunctionMatlab().
42900807856dSBarry Smith 
42910807856dSBarry Smith    Collective on SNES
42920807856dSBarry Smith 
42930807856dSBarry Smith    Input Parameters:
42940807856dSBarry Smith +  snes - the SNES context
42950807856dSBarry Smith -  x - input vector
42960807856dSBarry Smith 
42970807856dSBarry Smith    Output Parameter:
42980807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
42990807856dSBarry Smith 
43000807856dSBarry Smith    Notes:
43010807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
43020807856dSBarry Smith    implementations, so most users would not generally call this routine
43030807856dSBarry Smith    themselves.
43040807856dSBarry Smith 
43050807856dSBarry Smith    Level: developer
43060807856dSBarry Smith 
43070807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
43080807856dSBarry Smith 
43090807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
431061b2408cSBarry Smith */
43117087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
43120807856dSBarry Smith {
4313e650e774SBarry Smith   PetscErrorCode    ierr;
43148f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
43158f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
43168f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
431791621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
4318e650e774SBarry Smith 
43190807856dSBarry Smith   PetscFunctionBegin;
43200807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
43210807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
43220807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
43230807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
43240807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
43250807856dSBarry Smith 
43260807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
4327e650e774SBarry Smith 
432891621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4329e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4330e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
433191621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
433291621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
433391621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
43348f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
43358f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
4336b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
4337e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4338e650e774SBarry Smith   mxDestroyArray(prhs[0]);
4339e650e774SBarry Smith   mxDestroyArray(prhs[1]);
4340e650e774SBarry Smith   mxDestroyArray(prhs[2]);
43418f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
4342e650e774SBarry Smith   mxDestroyArray(plhs[0]);
43430807856dSBarry Smith   PetscFunctionReturn(0);
43440807856dSBarry Smith }
43450807856dSBarry Smith 
43460807856dSBarry Smith 
43470807856dSBarry Smith #undef __FUNCT__
43480807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
434961b2408cSBarry Smith /*
43500807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
43510807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4352e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
43530807856dSBarry Smith 
43540807856dSBarry Smith    Logically Collective on SNES
43550807856dSBarry Smith 
43560807856dSBarry Smith    Input Parameters:
43570807856dSBarry Smith +  snes - the SNES context
43580807856dSBarry Smith .  r - vector to store function value
43590807856dSBarry Smith -  func - function evaluation routine
43600807856dSBarry Smith 
43610807856dSBarry Smith    Calling sequence of func:
436261b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
43630807856dSBarry Smith 
43640807856dSBarry Smith 
43650807856dSBarry Smith    Notes:
43660807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
43670807856dSBarry Smith $      f'(x) x = -f(x),
43680807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
43690807856dSBarry Smith 
43700807856dSBarry Smith    Level: beginner
43710807856dSBarry Smith 
43720807856dSBarry Smith .keywords: SNES, nonlinear, set, function
43730807856dSBarry Smith 
43740807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
437561b2408cSBarry Smith */
43767087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
43770807856dSBarry Smith {
43780807856dSBarry Smith   PetscErrorCode    ierr;
43798f6e6473SBarry Smith   SNESMatlabContext *sctx;
43800807856dSBarry Smith 
43810807856dSBarry Smith   PetscFunctionBegin;
43828f6e6473SBarry Smith   /* currently sctx is memory bleed */
43838f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
43848f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
43858f6e6473SBarry Smith   /*
43868f6e6473SBarry Smith      This should work, but it doesn't
43878f6e6473SBarry Smith   sctx->ctx = ctx;
43888f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
43898f6e6473SBarry Smith   */
43908f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
43918f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
43920807856dSBarry Smith   PetscFunctionReturn(0);
43930807856dSBarry Smith }
439469b4f73cSBarry Smith 
439561b2408cSBarry Smith #undef __FUNCT__
439661b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
439761b2408cSBarry Smith /*
439861b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
439961b2408cSBarry Smith                          SNESSetJacobianMatlab().
440061b2408cSBarry Smith 
440161b2408cSBarry Smith    Collective on SNES
440261b2408cSBarry Smith 
440361b2408cSBarry Smith    Input Parameters:
440461b2408cSBarry Smith +  snes - the SNES context
440561b2408cSBarry Smith .  x - input vector
440661b2408cSBarry Smith .  A, B - the matrices
440761b2408cSBarry Smith -  ctx - user context
440861b2408cSBarry Smith 
440961b2408cSBarry Smith    Output Parameter:
441061b2408cSBarry Smith .  flag - structure of the matrix
441161b2408cSBarry Smith 
441261b2408cSBarry Smith    Level: developer
441361b2408cSBarry Smith 
441461b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
441561b2408cSBarry Smith 
441661b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
441761b2408cSBarry Smith @*/
44187087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
441961b2408cSBarry Smith {
442061b2408cSBarry Smith   PetscErrorCode    ierr;
442161b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
442261b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
442361b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
442461b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
442561b2408cSBarry Smith 
442661b2408cSBarry Smith   PetscFunctionBegin;
442761b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
442861b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
442961b2408cSBarry Smith 
443061b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
443161b2408cSBarry Smith 
443261b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
443361b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
443461b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
443561b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
443661b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
443761b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
443861b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
443961b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
444061b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
444161b2408cSBarry Smith   prhs[5] =  sctx->ctx;
4442b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
444361b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
444461b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
444561b2408cSBarry Smith   mxDestroyArray(prhs[0]);
444661b2408cSBarry Smith   mxDestroyArray(prhs[1]);
444761b2408cSBarry Smith   mxDestroyArray(prhs[2]);
444861b2408cSBarry Smith   mxDestroyArray(prhs[3]);
444961b2408cSBarry Smith   mxDestroyArray(prhs[4]);
445061b2408cSBarry Smith   mxDestroyArray(plhs[0]);
445161b2408cSBarry Smith   mxDestroyArray(plhs[1]);
445261b2408cSBarry Smith   PetscFunctionReturn(0);
445361b2408cSBarry Smith }
445461b2408cSBarry Smith 
445561b2408cSBarry Smith 
445661b2408cSBarry Smith #undef __FUNCT__
445761b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
445861b2408cSBarry Smith /*
445961b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
446061b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4461e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
446261b2408cSBarry Smith 
446361b2408cSBarry Smith    Logically Collective on SNES
446461b2408cSBarry Smith 
446561b2408cSBarry Smith    Input Parameters:
446661b2408cSBarry Smith +  snes - the SNES context
446761b2408cSBarry Smith .  A,B - Jacobian matrices
446861b2408cSBarry Smith .  func - function evaluation routine
446961b2408cSBarry Smith -  ctx - user context
447061b2408cSBarry Smith 
447161b2408cSBarry Smith    Calling sequence of func:
447261b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
447361b2408cSBarry Smith 
447461b2408cSBarry Smith 
447561b2408cSBarry Smith    Level: developer
447661b2408cSBarry Smith 
447761b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
447861b2408cSBarry Smith 
447961b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
448061b2408cSBarry Smith */
44817087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
448261b2408cSBarry Smith {
448361b2408cSBarry Smith   PetscErrorCode    ierr;
448461b2408cSBarry Smith   SNESMatlabContext *sctx;
448561b2408cSBarry Smith 
448661b2408cSBarry Smith   PetscFunctionBegin;
448761b2408cSBarry Smith   /* currently sctx is memory bleed */
448861b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
448961b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
449061b2408cSBarry Smith   /*
449161b2408cSBarry Smith      This should work, but it doesn't
449261b2408cSBarry Smith   sctx->ctx = ctx;
449361b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
449461b2408cSBarry Smith   */
449561b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
449661b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
449761b2408cSBarry Smith   PetscFunctionReturn(0);
449861b2408cSBarry Smith }
449969b4f73cSBarry Smith 
4500f9eb7ae2SShri Abhyankar #undef __FUNCT__
4501f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
4502f9eb7ae2SShri Abhyankar /*
4503f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
4504f9eb7ae2SShri Abhyankar 
4505f9eb7ae2SShri Abhyankar    Collective on SNES
4506f9eb7ae2SShri Abhyankar 
4507f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
4508f9eb7ae2SShri Abhyankar @*/
45097087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
4510f9eb7ae2SShri Abhyankar {
4511f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
451248f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
4513f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
4514f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
4515f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
4516f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
4517f9eb7ae2SShri Abhyankar 
4518f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4519f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4520f9eb7ae2SShri Abhyankar 
4521f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4522f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4523f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
4524f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
4525f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
4526f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
4527f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
4528f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
4529f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
4530f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4531f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
4532f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
4533f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
4534f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
4535f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
4536f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
4537f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4538f9eb7ae2SShri Abhyankar }
4539f9eb7ae2SShri Abhyankar 
4540f9eb7ae2SShri Abhyankar 
4541f9eb7ae2SShri Abhyankar #undef __FUNCT__
4542f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
4543f9eb7ae2SShri Abhyankar /*
4544e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
4545f9eb7ae2SShri Abhyankar 
4546f9eb7ae2SShri Abhyankar    Level: developer
4547f9eb7ae2SShri Abhyankar 
4548f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
4549f9eb7ae2SShri Abhyankar 
4550f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
4551f9eb7ae2SShri Abhyankar */
45527087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
4553f9eb7ae2SShri Abhyankar {
4554f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
4555f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
4556f9eb7ae2SShri Abhyankar 
4557f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4558f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
4559f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
4560f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4561f9eb7ae2SShri Abhyankar   /*
4562f9eb7ae2SShri Abhyankar      This should work, but it doesn't
4563f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
4564f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
4565f9eb7ae2SShri Abhyankar   */
4566f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
4567f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4568f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4569f9eb7ae2SShri Abhyankar }
4570f9eb7ae2SShri Abhyankar 
457169b4f73cSBarry Smith #endif
4572