xref: /petsc/src/snes/interface/snes.c (revision 88976e7148bb891b38778b9a5d5ae4c2b2cf44bf)
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",
205c60f73f4SPeter Brune                  snes->rtol,snes->abstol,snes->stol);CHKERRQ(ierr);
20677431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr);
20777431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr);
2089b94acceSBarry Smith     if (snes->ksp_ewconv) {
209fa9f3622SBarry Smith       kctx = (SNESKSPEW *)snes->kspconvctx;
2109b94acceSBarry Smith       if (kctx) {
21177431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr);
212a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr);
213a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr);
2149b94acceSBarry Smith       }
2159b94acceSBarry Smith     }
216eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
217eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");CHKERRQ(ierr);
218eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
219eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr);
220eb1f6c34SBarry Smith     }
221eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
222eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");CHKERRQ(ierr);
223eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
22442f4f86dSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr);
225eb1f6c34SBarry Smith     }
2260f5bd95cSBarry Smith   } else if (isstring) {
227317d6ea6SBarry Smith     const char *type;
228454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
229b0a32e0cSBarry Smith     ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr);
23019bcc07fSBarry Smith   }
23142f4f86dSBarry Smith   if (snes->pc && snes->usespc) {
2324a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2334a0c5b0cSMatthew G Knepley     ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr);
2344a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2354a0c5b0cSMatthew G Knepley   }
2362c155ee1SBarry Smith   if (snes->usesksp) {
2372c155ee1SBarry Smith     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
238b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
23994b7f48cSBarry Smith     ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
240b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2412c155ee1SBarry Smith   }
2427f1410a3SPeter Brune   if (snes->linesearch) {
2437f1410a3SPeter Brune     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2447f1410a3SPeter Brune     ierr = SNESGetSNESLineSearch(snes, &linesearch);CHKERRQ(ierr);
2457f1410a3SPeter Brune     ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr);
2467f1410a3SPeter Brune     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2477f1410a3SPeter Brune   }
2483a40ed3dSBarry Smith   PetscFunctionReturn(0);
2499b94acceSBarry Smith }
2509b94acceSBarry Smith 
25176b2cf59SMatthew Knepley /*
25276b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
25376b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
25476b2cf59SMatthew Knepley */
25576b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
256a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
2576849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
25876b2cf59SMatthew Knepley 
259e74ef692SMatthew Knepley #undef __FUNCT__
260e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker"
261ac226902SBarry Smith /*@C
26276b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
26376b2cf59SMatthew Knepley 
26476b2cf59SMatthew Knepley   Not Collective
26576b2cf59SMatthew Knepley 
26676b2cf59SMatthew Knepley   Input Parameter:
26776b2cf59SMatthew Knepley . snescheck - function that checks for options
26876b2cf59SMatthew Knepley 
26976b2cf59SMatthew Knepley   Level: developer
27076b2cf59SMatthew Knepley 
27176b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
27276b2cf59SMatthew Knepley @*/
2737087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
27476b2cf59SMatthew Knepley {
27576b2cf59SMatthew Knepley   PetscFunctionBegin;
27676b2cf59SMatthew Knepley   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
277e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
27876b2cf59SMatthew Knepley   }
27976b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
28076b2cf59SMatthew Knepley   PetscFunctionReturn(0);
28176b2cf59SMatthew Knepley }
28276b2cf59SMatthew Knepley 
2837087cfbeSBarry Smith extern PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
284aa3661deSLisandro Dalcin 
285aa3661deSLisandro Dalcin #undef __FUNCT__
286aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private"
287ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool  hasOperator, PetscInt version)
288aa3661deSLisandro Dalcin {
289aa3661deSLisandro Dalcin   Mat            J;
290aa3661deSLisandro Dalcin   KSP            ksp;
291aa3661deSLisandro Dalcin   PC             pc;
292ace3abfcSBarry Smith   PetscBool      match;
293aa3661deSLisandro Dalcin   PetscErrorCode ierr;
294aa3661deSLisandro Dalcin 
295aa3661deSLisandro Dalcin   PetscFunctionBegin;
2960700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
297aa3661deSLisandro Dalcin 
29898613b67SLisandro Dalcin   if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
29998613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
30098613b67SLisandro Dalcin     ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr);
30198613b67SLisandro Dalcin   }
30298613b67SLisandro Dalcin 
303aa3661deSLisandro Dalcin   if (version == 1) {
304aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
30598613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
3069c6ac3b3SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
307aa3661deSLisandro Dalcin   } else if (version == 2) {
308e32f2f54SBarry Smith     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
30982a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
310aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
311aa3661deSLisandro Dalcin #else
312e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
313aa3661deSLisandro Dalcin #endif
314a8248277SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
315aa3661deSLisandro Dalcin 
316aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
317d3462f78SMatthew Knepley   if (hasOperator) {
318aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
319aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
320aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
321aa3661deSLisandro Dalcin   } else {
322aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
323aa3661deSLisandro Dalcin        provided preconditioner matrix with the default matrix free version. */
3246cab3a1bSJed Brown     void *functx;
3256cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
3266cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
327aa3661deSLisandro Dalcin     /* Force no preconditioner */
328aa3661deSLisandro Dalcin     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
329aa3661deSLisandro Dalcin     ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
330aa3661deSLisandro Dalcin     ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
331aa3661deSLisandro Dalcin     if (!match) {
332aa3661deSLisandro Dalcin       ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
333aa3661deSLisandro Dalcin       ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
334aa3661deSLisandro Dalcin     }
335aa3661deSLisandro Dalcin   }
3366bf464f9SBarry Smith   ierr = MatDestroy(&J);CHKERRQ(ierr);
337aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
338aa3661deSLisandro Dalcin }
339aa3661deSLisandro Dalcin 
3404a2ae208SSatish Balay #undef __FUNCT__
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 
515c60f73f4SPeter 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);
666*88976e71SPeter Brune     /* default to 1 iteration */
667*88976e71SPeter Brune     ierr = SNESSetTolerances(snes->pc, snes->pc->abstol, snes->pc->rtol, snes->pc->stol, 1, snes->pc->max_funcs);CHKERRQ(ierr);
6684a0c5b0cSMatthew G Knepley     ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr);
6694a0c5b0cSMatthew G Knepley   }
6703a40ed3dSBarry Smith   PetscFunctionReturn(0);
6719b94acceSBarry Smith }
6729b94acceSBarry Smith 
673d25893d9SBarry Smith #undef __FUNCT__
674d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext"
675d25893d9SBarry Smith /*@
676d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
677d25893d9SBarry Smith    the nonlinear solvers.
678d25893d9SBarry Smith 
679d25893d9SBarry Smith    Logically Collective on SNES
680d25893d9SBarry Smith 
681d25893d9SBarry Smith    Input Parameters:
682d25893d9SBarry Smith +  snes - the SNES context
683d25893d9SBarry Smith .  compute - function to compute the context
684d25893d9SBarry Smith -  destroy - function to destroy the context
685d25893d9SBarry Smith 
686d25893d9SBarry Smith    Level: intermediate
687d25893d9SBarry Smith 
688d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
689d25893d9SBarry Smith 
690d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
691d25893d9SBarry Smith @*/
692d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
693d25893d9SBarry Smith {
694d25893d9SBarry Smith   PetscFunctionBegin;
695d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
696d25893d9SBarry Smith   snes->ops->usercompute = compute;
697d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
698d25893d9SBarry Smith   PetscFunctionReturn(0);
699d25893d9SBarry Smith }
700a847f771SSatish Balay 
7014a2ae208SSatish Balay #undef __FUNCT__
7024a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
703b07ff414SBarry Smith /*@
7049b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
7059b94acceSBarry Smith    the nonlinear solvers.
7069b94acceSBarry Smith 
7073f9fe445SBarry Smith    Logically Collective on SNES
708fee21e36SBarry Smith 
709c7afd0dbSLois Curfman McInnes    Input Parameters:
710c7afd0dbSLois Curfman McInnes +  snes - the SNES context
711c7afd0dbSLois Curfman McInnes -  usrP - optional user context
712c7afd0dbSLois Curfman McInnes 
71336851e7fSLois Curfman McInnes    Level: intermediate
71436851e7fSLois Curfman McInnes 
7159b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
7169b94acceSBarry Smith 
717d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext()
7189b94acceSBarry Smith @*/
7197087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
7209b94acceSBarry Smith {
7211b2093e4SBarry Smith   PetscErrorCode ierr;
722b07ff414SBarry Smith   KSP            ksp;
7231b2093e4SBarry Smith 
7243a40ed3dSBarry Smith   PetscFunctionBegin;
7250700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
726b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
727b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
7289b94acceSBarry Smith   snes->user = usrP;
7293a40ed3dSBarry Smith   PetscFunctionReturn(0);
7309b94acceSBarry Smith }
73174679c65SBarry Smith 
7324a2ae208SSatish Balay #undef __FUNCT__
7334a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
734b07ff414SBarry Smith /*@
7359b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
7369b94acceSBarry Smith    nonlinear solvers.
7379b94acceSBarry Smith 
738c7afd0dbSLois Curfman McInnes    Not Collective
739c7afd0dbSLois Curfman McInnes 
7409b94acceSBarry Smith    Input Parameter:
7419b94acceSBarry Smith .  snes - SNES context
7429b94acceSBarry Smith 
7439b94acceSBarry Smith    Output Parameter:
7449b94acceSBarry Smith .  usrP - user context
7459b94acceSBarry Smith 
74636851e7fSLois Curfman McInnes    Level: intermediate
74736851e7fSLois Curfman McInnes 
7489b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
7499b94acceSBarry Smith 
7509b94acceSBarry Smith .seealso: SNESSetApplicationContext()
7519b94acceSBarry Smith @*/
752e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
7539b94acceSBarry Smith {
7543a40ed3dSBarry Smith   PetscFunctionBegin;
7550700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
756e71120c6SJed Brown   *(void**)usrP = snes->user;
7573a40ed3dSBarry Smith   PetscFunctionReturn(0);
7589b94acceSBarry Smith }
75974679c65SBarry Smith 
7604a2ae208SSatish Balay #undef __FUNCT__
7614a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
7629b94acceSBarry Smith /*@
763c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
764c8228a4eSBarry Smith    at this time.
7659b94acceSBarry Smith 
766c7afd0dbSLois Curfman McInnes    Not Collective
767c7afd0dbSLois Curfman McInnes 
7689b94acceSBarry Smith    Input Parameter:
7699b94acceSBarry Smith .  snes - SNES context
7709b94acceSBarry Smith 
7719b94acceSBarry Smith    Output Parameter:
7729b94acceSBarry Smith .  iter - iteration number
7739b94acceSBarry Smith 
774c8228a4eSBarry Smith    Notes:
775c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
776c8228a4eSBarry Smith 
777c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
77808405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
77908405cd6SLois Curfman McInnes .vb
78008405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
78108405cd6SLois Curfman McInnes       if (!(it % 2)) {
78208405cd6SLois Curfman McInnes         [compute Jacobian here]
78308405cd6SLois Curfman McInnes       }
78408405cd6SLois Curfman McInnes .ve
785c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
78608405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
787c8228a4eSBarry Smith 
78836851e7fSLois Curfman McInnes    Level: intermediate
78936851e7fSLois Curfman McInnes 
7902b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
7912b668275SBarry Smith 
792b850b91aSLisandro Dalcin .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
7939b94acceSBarry Smith @*/
7947087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
7959b94acceSBarry Smith {
7963a40ed3dSBarry Smith   PetscFunctionBegin;
7970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7984482741eSBarry Smith   PetscValidIntPointer(iter,2);
7999b94acceSBarry Smith   *iter = snes->iter;
8003a40ed3dSBarry Smith   PetscFunctionReturn(0);
8019b94acceSBarry Smith }
80274679c65SBarry Smith 
8034a2ae208SSatish Balay #undef __FUNCT__
804360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber"
805360c497dSPeter Brune /*@
806360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
807360c497dSPeter Brune 
808360c497dSPeter Brune    Not Collective
809360c497dSPeter Brune 
810360c497dSPeter Brune    Input Parameter:
811360c497dSPeter Brune .  snes - SNES context
812360c497dSPeter Brune .  iter - iteration number
813360c497dSPeter Brune 
814360c497dSPeter Brune    Level: developer
815360c497dSPeter Brune 
816360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number,
817360c497dSPeter Brune 
818360c497dSPeter Brune .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
819360c497dSPeter Brune @*/
820360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
821360c497dSPeter Brune {
822360c497dSPeter Brune   PetscErrorCode ierr;
823360c497dSPeter Brune 
824360c497dSPeter Brune   PetscFunctionBegin;
825360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
826360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
827360c497dSPeter Brune   snes->iter = iter;
828360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
829360c497dSPeter Brune   PetscFunctionReturn(0);
830360c497dSPeter Brune }
831360c497dSPeter Brune 
832360c497dSPeter Brune #undef __FUNCT__
8334a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm"
8349b94acceSBarry Smith /*@
8359b94acceSBarry Smith    SNESGetFunctionNorm - Gets the norm of the current function that was set
8369b94acceSBarry Smith    with SNESSSetFunction().
8379b94acceSBarry Smith 
838c7afd0dbSLois Curfman McInnes    Collective on SNES
839c7afd0dbSLois Curfman McInnes 
8409b94acceSBarry Smith    Input Parameter:
8419b94acceSBarry Smith .  snes - SNES context
8429b94acceSBarry Smith 
8439b94acceSBarry Smith    Output Parameter:
8449b94acceSBarry Smith .  fnorm - 2-norm of function
8459b94acceSBarry Smith 
84636851e7fSLois Curfman McInnes    Level: intermediate
84736851e7fSLois Curfman McInnes 
8489b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm
849a86d99e1SLois Curfman McInnes 
850b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
8519b94acceSBarry Smith @*/
8527087cfbeSBarry Smith PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
8539b94acceSBarry Smith {
8543a40ed3dSBarry Smith   PetscFunctionBegin;
8550700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8564482741eSBarry Smith   PetscValidScalarPointer(fnorm,2);
8579b94acceSBarry Smith   *fnorm = snes->norm;
8583a40ed3dSBarry Smith   PetscFunctionReturn(0);
8599b94acceSBarry Smith }
86074679c65SBarry Smith 
861360c497dSPeter Brune 
862360c497dSPeter Brune #undef __FUNCT__
863360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm"
864360c497dSPeter Brune /*@
865360c497dSPeter Brune    SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm().
866360c497dSPeter Brune 
867360c497dSPeter Brune    Collective on SNES
868360c497dSPeter Brune 
869360c497dSPeter Brune    Input Parameter:
870360c497dSPeter Brune .  snes - SNES context
871360c497dSPeter Brune .  fnorm - 2-norm of function
872360c497dSPeter Brune 
873360c497dSPeter Brune    Level: developer
874360c497dSPeter Brune 
875360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm
876360c497dSPeter Brune 
877360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm().
878360c497dSPeter Brune @*/
879360c497dSPeter Brune PetscErrorCode  SNESSetFunctionNorm(SNES snes,PetscReal fnorm)
880360c497dSPeter Brune {
881360c497dSPeter Brune 
882360c497dSPeter Brune   PetscErrorCode ierr;
883360c497dSPeter Brune 
884360c497dSPeter Brune   PetscFunctionBegin;
885360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
886360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
887360c497dSPeter Brune   snes->norm = fnorm;
888360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
889360c497dSPeter Brune   PetscFunctionReturn(0);
890360c497dSPeter Brune }
891360c497dSPeter Brune 
8924a2ae208SSatish Balay #undef __FUNCT__
893b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
8949b94acceSBarry Smith /*@
895b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
8969b94acceSBarry Smith    attempted by the nonlinear solver.
8979b94acceSBarry Smith 
898c7afd0dbSLois Curfman McInnes    Not Collective
899c7afd0dbSLois Curfman McInnes 
9009b94acceSBarry Smith    Input Parameter:
9019b94acceSBarry Smith .  snes - SNES context
9029b94acceSBarry Smith 
9039b94acceSBarry Smith    Output Parameter:
9049b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
9059b94acceSBarry Smith 
906c96a6f78SLois Curfman McInnes    Notes:
907c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
908c96a6f78SLois Curfman McInnes 
90936851e7fSLois Curfman McInnes    Level: intermediate
91036851e7fSLois Curfman McInnes 
9119b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
91258ebbce7SBarry Smith 
913e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
91458ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
9159b94acceSBarry Smith @*/
9167087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
9179b94acceSBarry Smith {
9183a40ed3dSBarry Smith   PetscFunctionBegin;
9190700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9204482741eSBarry Smith   PetscValidIntPointer(nfails,2);
92150ffb88aSMatthew Knepley   *nfails = snes->numFailures;
92250ffb88aSMatthew Knepley   PetscFunctionReturn(0);
92350ffb88aSMatthew Knepley }
92450ffb88aSMatthew Knepley 
92550ffb88aSMatthew Knepley #undef __FUNCT__
926b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
92750ffb88aSMatthew Knepley /*@
928b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
92950ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
93050ffb88aSMatthew Knepley 
93150ffb88aSMatthew Knepley    Not Collective
93250ffb88aSMatthew Knepley 
93350ffb88aSMatthew Knepley    Input Parameters:
93450ffb88aSMatthew Knepley +  snes     - SNES context
93550ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
93650ffb88aSMatthew Knepley 
93750ffb88aSMatthew Knepley    Level: intermediate
93850ffb88aSMatthew Knepley 
93950ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
94058ebbce7SBarry Smith 
941e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
94258ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
94350ffb88aSMatthew Knepley @*/
9447087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
94550ffb88aSMatthew Knepley {
94650ffb88aSMatthew Knepley   PetscFunctionBegin;
9470700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
94850ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
94950ffb88aSMatthew Knepley   PetscFunctionReturn(0);
95050ffb88aSMatthew Knepley }
95150ffb88aSMatthew Knepley 
95250ffb88aSMatthew Knepley #undef __FUNCT__
953b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
95450ffb88aSMatthew Knepley /*@
955b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
95650ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
95750ffb88aSMatthew Knepley 
95850ffb88aSMatthew Knepley    Not Collective
95950ffb88aSMatthew Knepley 
96050ffb88aSMatthew Knepley    Input Parameter:
96150ffb88aSMatthew Knepley .  snes     - SNES context
96250ffb88aSMatthew Knepley 
96350ffb88aSMatthew Knepley    Output Parameter:
96450ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
96550ffb88aSMatthew Knepley 
96650ffb88aSMatthew Knepley    Level: intermediate
96750ffb88aSMatthew Knepley 
96850ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
96958ebbce7SBarry Smith 
970e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
97158ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
97258ebbce7SBarry Smith 
97350ffb88aSMatthew Knepley @*/
9747087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
97550ffb88aSMatthew Knepley {
97650ffb88aSMatthew Knepley   PetscFunctionBegin;
9770700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9784482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
97950ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
9803a40ed3dSBarry Smith   PetscFunctionReturn(0);
9819b94acceSBarry Smith }
982a847f771SSatish Balay 
9834a2ae208SSatish Balay #undef __FUNCT__
9842541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
9852541af92SBarry Smith /*@
9862541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
9872541af92SBarry Smith      done by SNES.
9882541af92SBarry Smith 
9892541af92SBarry Smith    Not Collective
9902541af92SBarry Smith 
9912541af92SBarry Smith    Input Parameter:
9922541af92SBarry Smith .  snes     - SNES context
9932541af92SBarry Smith 
9942541af92SBarry Smith    Output Parameter:
9952541af92SBarry Smith .  nfuncs - number of evaluations
9962541af92SBarry Smith 
9972541af92SBarry Smith    Level: intermediate
9982541af92SBarry Smith 
9992541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
100058ebbce7SBarry Smith 
1001e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
10022541af92SBarry Smith @*/
10037087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
10042541af92SBarry Smith {
10052541af92SBarry Smith   PetscFunctionBegin;
10060700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10072541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
10082541af92SBarry Smith   *nfuncs = snes->nfuncs;
10092541af92SBarry Smith   PetscFunctionReturn(0);
10102541af92SBarry Smith }
10112541af92SBarry Smith 
10122541af92SBarry Smith #undef __FUNCT__
10133d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
10143d4c4710SBarry Smith /*@
10153d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
10163d4c4710SBarry Smith    linear solvers.
10173d4c4710SBarry Smith 
10183d4c4710SBarry Smith    Not Collective
10193d4c4710SBarry Smith 
10203d4c4710SBarry Smith    Input Parameter:
10213d4c4710SBarry Smith .  snes - SNES context
10223d4c4710SBarry Smith 
10233d4c4710SBarry Smith    Output Parameter:
10243d4c4710SBarry Smith .  nfails - number of failed solves
10253d4c4710SBarry Smith 
10263d4c4710SBarry Smith    Notes:
10273d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
10283d4c4710SBarry Smith 
10293d4c4710SBarry Smith    Level: intermediate
10303d4c4710SBarry Smith 
10313d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
103258ebbce7SBarry Smith 
1033e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
10343d4c4710SBarry Smith @*/
10357087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
10363d4c4710SBarry Smith {
10373d4c4710SBarry Smith   PetscFunctionBegin;
10380700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10393d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
10403d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
10413d4c4710SBarry Smith   PetscFunctionReturn(0);
10423d4c4710SBarry Smith }
10433d4c4710SBarry Smith 
10443d4c4710SBarry Smith #undef __FUNCT__
10453d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
10463d4c4710SBarry Smith /*@
10473d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
10483d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
10493d4c4710SBarry Smith 
10503f9fe445SBarry Smith    Logically Collective on SNES
10513d4c4710SBarry Smith 
10523d4c4710SBarry Smith    Input Parameters:
10533d4c4710SBarry Smith +  snes     - SNES context
10543d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
10553d4c4710SBarry Smith 
10563d4c4710SBarry Smith    Level: intermediate
10573d4c4710SBarry Smith 
1058a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
10593d4c4710SBarry Smith 
10603d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
10613d4c4710SBarry Smith 
106258ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
10633d4c4710SBarry Smith @*/
10647087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
10653d4c4710SBarry Smith {
10663d4c4710SBarry Smith   PetscFunctionBegin;
10670700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1068c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
10693d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
10703d4c4710SBarry Smith   PetscFunctionReturn(0);
10713d4c4710SBarry Smith }
10723d4c4710SBarry Smith 
10733d4c4710SBarry Smith #undef __FUNCT__
10743d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
10753d4c4710SBarry Smith /*@
10763d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
10773d4c4710SBarry Smith      are allowed before SNES terminates
10783d4c4710SBarry Smith 
10793d4c4710SBarry Smith    Not Collective
10803d4c4710SBarry Smith 
10813d4c4710SBarry Smith    Input Parameter:
10823d4c4710SBarry Smith .  snes     - SNES context
10833d4c4710SBarry Smith 
10843d4c4710SBarry Smith    Output Parameter:
10853d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
10863d4c4710SBarry Smith 
10873d4c4710SBarry Smith    Level: intermediate
10883d4c4710SBarry Smith 
10893d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
10903d4c4710SBarry Smith 
10913d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
10923d4c4710SBarry Smith 
1093e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
10943d4c4710SBarry Smith @*/
10957087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
10963d4c4710SBarry Smith {
10973d4c4710SBarry Smith   PetscFunctionBegin;
10980700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10993d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
11003d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
11013d4c4710SBarry Smith   PetscFunctionReturn(0);
11023d4c4710SBarry Smith }
11033d4c4710SBarry Smith 
11043d4c4710SBarry Smith #undef __FUNCT__
1105b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
1106c96a6f78SLois Curfman McInnes /*@
1107b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1108c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1109c96a6f78SLois Curfman McInnes 
1110c7afd0dbSLois Curfman McInnes    Not Collective
1111c7afd0dbSLois Curfman McInnes 
1112c96a6f78SLois Curfman McInnes    Input Parameter:
1113c96a6f78SLois Curfman McInnes .  snes - SNES context
1114c96a6f78SLois Curfman McInnes 
1115c96a6f78SLois Curfman McInnes    Output Parameter:
1116c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1117c96a6f78SLois Curfman McInnes 
1118c96a6f78SLois Curfman McInnes    Notes:
1119c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1120c96a6f78SLois Curfman McInnes 
112136851e7fSLois Curfman McInnes    Level: intermediate
112236851e7fSLois Curfman McInnes 
1123c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
11242b668275SBarry Smith 
11258c7482ecSBarry Smith .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
1126c96a6f78SLois Curfman McInnes @*/
11277087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
1128c96a6f78SLois Curfman McInnes {
11293a40ed3dSBarry Smith   PetscFunctionBegin;
11300700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11314482741eSBarry Smith   PetscValidIntPointer(lits,2);
1132c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
11333a40ed3dSBarry Smith   PetscFunctionReturn(0);
1134c96a6f78SLois Curfman McInnes }
1135c96a6f78SLois Curfman McInnes 
11364a2ae208SSatish Balay #undef __FUNCT__
113794b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP"
113852baeb72SSatish Balay /*@
113994b7f48cSBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
11409b94acceSBarry Smith 
114194b7f48cSBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
1142c7afd0dbSLois Curfman McInnes 
11439b94acceSBarry Smith    Input Parameter:
11449b94acceSBarry Smith .  snes - the SNES context
11459b94acceSBarry Smith 
11469b94acceSBarry Smith    Output Parameter:
114794b7f48cSBarry Smith .  ksp - the KSP context
11489b94acceSBarry Smith 
11499b94acceSBarry Smith    Notes:
115094b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
11519b94acceSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
11522999313aSBarry Smith    PC contexts as well.
11539b94acceSBarry Smith 
115436851e7fSLois Curfman McInnes    Level: beginner
115536851e7fSLois Curfman McInnes 
115694b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
11579b94acceSBarry Smith 
11582999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
11599b94acceSBarry Smith @*/
11607087cfbeSBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
11619b94acceSBarry Smith {
11621cee3971SBarry Smith   PetscErrorCode ierr;
11631cee3971SBarry Smith 
11643a40ed3dSBarry Smith   PetscFunctionBegin;
11650700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11664482741eSBarry Smith   PetscValidPointer(ksp,2);
11671cee3971SBarry Smith 
11681cee3971SBarry Smith   if (!snes->ksp) {
11691cee3971SBarry Smith     ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr);
11701cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
11711cee3971SBarry Smith     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
11721cee3971SBarry Smith   }
117394b7f48cSBarry Smith   *ksp = snes->ksp;
11743a40ed3dSBarry Smith   PetscFunctionReturn(0);
11759b94acceSBarry Smith }
117682bf6240SBarry Smith 
11774a2ae208SSatish Balay #undef __FUNCT__
11782999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
11792999313aSBarry Smith /*@
11802999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
11812999313aSBarry Smith 
11822999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
11832999313aSBarry Smith 
11842999313aSBarry Smith    Input Parameters:
11852999313aSBarry Smith +  snes - the SNES context
11862999313aSBarry Smith -  ksp - the KSP context
11872999313aSBarry Smith 
11882999313aSBarry Smith    Notes:
11892999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
11902999313aSBarry Smith    so this routine is rarely needed.
11912999313aSBarry Smith 
11922999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
11932999313aSBarry Smith    decreased by one.
11942999313aSBarry Smith 
11952999313aSBarry Smith    Level: developer
11962999313aSBarry Smith 
11972999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
11982999313aSBarry Smith 
11992999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
12002999313aSBarry Smith @*/
12017087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
12022999313aSBarry Smith {
12032999313aSBarry Smith   PetscErrorCode ierr;
12042999313aSBarry Smith 
12052999313aSBarry Smith   PetscFunctionBegin;
12060700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12070700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
12082999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
12097dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1210906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
12112999313aSBarry Smith   snes->ksp = ksp;
12122999313aSBarry Smith   PetscFunctionReturn(0);
12132999313aSBarry Smith }
12142999313aSBarry Smith 
12157adad957SLisandro Dalcin #if 0
12162999313aSBarry Smith #undef __FUNCT__
12174a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc"
12186849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
1219e24b481bSBarry Smith {
1220e24b481bSBarry Smith   PetscFunctionBegin;
1221e24b481bSBarry Smith   PetscFunctionReturn(0);
1222e24b481bSBarry Smith }
12237adad957SLisandro Dalcin #endif
1224e24b481bSBarry Smith 
12259b94acceSBarry Smith /* -----------------------------------------------------------*/
12264a2ae208SSatish Balay #undef __FUNCT__
12274a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
122852baeb72SSatish Balay /*@
12299b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
12309b94acceSBarry Smith 
1231c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1232c7afd0dbSLois Curfman McInnes 
1233c7afd0dbSLois Curfman McInnes    Input Parameters:
1234906ed7ccSBarry Smith .  comm - MPI communicator
12359b94acceSBarry Smith 
12369b94acceSBarry Smith    Output Parameter:
12379b94acceSBarry Smith .  outsnes - the new SNES context
12389b94acceSBarry Smith 
1239c7afd0dbSLois Curfman McInnes    Options Database Keys:
1240c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1241c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1242c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1243c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1244c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1245c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1246c1f60f51SBarry Smith 
124736851e7fSLois Curfman McInnes    Level: beginner
124836851e7fSLois Curfman McInnes 
12499b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
12509b94acceSBarry Smith 
1251a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1252a8054027SBarry Smith 
12539b94acceSBarry Smith @*/
12547087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
12559b94acceSBarry Smith {
1256dfbe8321SBarry Smith   PetscErrorCode      ierr;
12579b94acceSBarry Smith   SNES                snes;
1258fa9f3622SBarry Smith   SNESKSPEW           *kctx;
125937fcc0dbSBarry Smith 
12603a40ed3dSBarry Smith   PetscFunctionBegin;
1261ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
12628ba1e511SMatthew Knepley   *outsnes = PETSC_NULL;
12638ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
12648ba1e511SMatthew Knepley   ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr);
12658ba1e511SMatthew Knepley #endif
12668ba1e511SMatthew Knepley 
12673194b578SJed Brown   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
12687adad957SLisandro Dalcin 
126985385478SLisandro Dalcin   snes->ops->converged    = SNESDefaultConverged;
12702c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
1271*88976e71SPeter Brune   snes->tolerancesset     = PETSC_FALSE;
12729b94acceSBarry Smith   snes->max_its           = 50;
12739750a799SBarry Smith   snes->max_funcs	  = 10000;
12749b94acceSBarry Smith   snes->norm		  = 0.0;
1275b4874afaSBarry Smith   snes->rtol		  = 1.e-8;
1276b4874afaSBarry Smith   snes->ttol              = 0.0;
127770441072SBarry Smith   snes->abstol		  = 1.e-50;
1278c60f73f4SPeter Brune   snes->stol		  = 1.e-8;
12794b27c08aSLois Curfman McInnes   snes->deltatol	  = 1.e-12;
12809b94acceSBarry Smith   snes->nfuncs            = 0;
128150ffb88aSMatthew Knepley   snes->numFailures       = 0;
128250ffb88aSMatthew Knepley   snes->maxFailures       = 1;
12837a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1284e35cf81dSBarry Smith   snes->lagjacobian       = 1;
1285a8054027SBarry Smith   snes->lagpreconditioner = 1;
1286639f9d9dSBarry Smith   snes->numbermonitors    = 0;
12879b94acceSBarry Smith   snes->data              = 0;
12884dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1289186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
12906f24a144SLois Curfman McInnes   snes->nwork             = 0;
129158c9b817SLisandro Dalcin   snes->work              = 0;
129258c9b817SLisandro Dalcin   snes->nvwork            = 0;
129358c9b817SLisandro Dalcin   snes->vwork             = 0;
1294758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1295758f92a0SBarry Smith   snes->conv_hist_max     = 0;
1296758f92a0SBarry Smith   snes->conv_hist         = PETSC_NULL;
1297758f92a0SBarry Smith   snes->conv_hist_its     = PETSC_NULL;
1298758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1299184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
130089b92e6fSPeter Brune   snes->gssweeps          = 1;
13019b94acceSBarry Smith 
13023d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
13033d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
13043d4c4710SBarry Smith 
13059b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
130638f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr);
13079b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
13089b94acceSBarry Smith   kctx->version     = 2;
13099b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
13109b94acceSBarry Smith                              this was too large for some test cases */
131175567043SBarry Smith   kctx->rtol_last   = 0.0;
13129b94acceSBarry Smith   kctx->rtol_max    = .9;
13139b94acceSBarry Smith   kctx->gamma       = 1.0;
131462d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
131571f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
13169b94acceSBarry Smith   kctx->threshold   = .1;
131775567043SBarry Smith   kctx->lresid_last = 0.0;
131875567043SBarry Smith   kctx->norm_last   = 0.0;
13199b94acceSBarry Smith 
13209b94acceSBarry Smith   *outsnes = snes;
13213a40ed3dSBarry Smith   PetscFunctionReturn(0);
13229b94acceSBarry Smith }
13239b94acceSBarry Smith 
13244a2ae208SSatish Balay #undef __FUNCT__
13254a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
13269b94acceSBarry Smith /*@C
13279b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
13289b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
13299b94acceSBarry Smith    equations.
13309b94acceSBarry Smith 
13313f9fe445SBarry Smith    Logically Collective on SNES
1332fee21e36SBarry Smith 
1333c7afd0dbSLois Curfman McInnes    Input Parameters:
1334c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1335c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1336de044059SHong Zhang .  func - function evaluation routine
1337c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1338c7afd0dbSLois Curfman McInnes          function evaluation routine (may be PETSC_NULL)
13399b94acceSBarry Smith 
1340c7afd0dbSLois Curfman McInnes    Calling sequence of func:
13418d76a1e5SLois Curfman McInnes $    func (SNES snes,Vec x,Vec f,void *ctx);
1342c7afd0dbSLois Curfman McInnes 
1343c586c404SJed Brown +  snes - the SNES context
1344c586c404SJed Brown .  x - state at which to evaluate residual
1345c586c404SJed Brown .  f - vector to put residual
1346c7afd0dbSLois Curfman McInnes -  ctx - optional user-defined function context
13479b94acceSBarry Smith 
13489b94acceSBarry Smith    Notes:
13499b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
13509b94acceSBarry Smith $      f'(x) x = -f(x),
1351c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
13529b94acceSBarry Smith 
135336851e7fSLois Curfman McInnes    Level: beginner
135436851e7fSLois Curfman McInnes 
13559b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
13569b94acceSBarry Smith 
13578b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard()
13589b94acceSBarry Smith @*/
13597087cfbeSBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
13609b94acceSBarry Smith {
136185385478SLisandro Dalcin   PetscErrorCode ierr;
13626cab3a1bSJed Brown   DM             dm;
13636cab3a1bSJed Brown 
13643a40ed3dSBarry Smith   PetscFunctionBegin;
13650700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1366d2a683ecSLisandro Dalcin   if (r) {
1367d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1368d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
136985385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
13706bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
137185385478SLisandro Dalcin     snes->vec_func = r;
1372d2a683ecSLisandro Dalcin   }
13736cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
13746cab3a1bSJed Brown   ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr);
13753a40ed3dSBarry Smith   PetscFunctionReturn(0);
13769b94acceSBarry Smith }
13779b94acceSBarry Smith 
1378646217ecSPeter Brune 
1379646217ecSPeter Brune #undef __FUNCT__
1380646217ecSPeter Brune #define __FUNCT__ "SNESSetGS"
1381c79ef259SPeter Brune /*@C
1382c79ef259SPeter Brune    SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for
1383c79ef259SPeter Brune    use with composed nonlinear solvers.
1384c79ef259SPeter Brune 
1385c79ef259SPeter Brune    Input Parameters:
1386c79ef259SPeter Brune +  snes   - the SNES context
1387c79ef259SPeter Brune .  gsfunc - function evaluation routine
1388c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
1389c79ef259SPeter Brune             smoother evaluation routine (may be PETSC_NULL)
1390c79ef259SPeter Brune 
1391c79ef259SPeter Brune    Calling sequence of func:
1392c79ef259SPeter Brune $    func (SNES snes,Vec x,Vec b,void *ctx);
1393c79ef259SPeter Brune 
1394c79ef259SPeter Brune +  X   - solution vector
1395c79ef259SPeter Brune .  B   - RHS vector
1396d28543b3SPeter Brune -  ctx - optional user-defined Gauss-Seidel context
1397c79ef259SPeter Brune 
1398c79ef259SPeter Brune    Notes:
1399c79ef259SPeter Brune    The GS routines are used by the composed nonlinear solver to generate
1400c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
1401c79ef259SPeter Brune 
1402d28543b3SPeter Brune    Level: intermediate
1403c79ef259SPeter Brune 
1404d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel
1405c79ef259SPeter Brune 
1406c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS()
1407c79ef259SPeter Brune @*/
14086cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx)
14096cab3a1bSJed Brown {
14106cab3a1bSJed Brown   PetscErrorCode ierr;
14116cab3a1bSJed Brown   DM dm;
14126cab3a1bSJed Brown 
1413646217ecSPeter Brune   PetscFunctionBegin;
14146cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
14156cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
14166cab3a1bSJed Brown   ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr);
1417646217ecSPeter Brune   PetscFunctionReturn(0);
1418646217ecSPeter Brune }
1419646217ecSPeter Brune 
1420d25893d9SBarry Smith #undef __FUNCT__
142189b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps"
142289b92e6fSPeter Brune /*@
142389b92e6fSPeter Brune    SNESSetGSSweeps - Sets the number of sweeps of GS to use.
142489b92e6fSPeter Brune 
142589b92e6fSPeter Brune    Input Parameters:
142689b92e6fSPeter Brune +  snes   - the SNES context
142789b92e6fSPeter Brune -  sweeps  - the number of sweeps of GS to perform.
142889b92e6fSPeter Brune 
142989b92e6fSPeter Brune    Level: intermediate
143089b92e6fSPeter Brune 
143189b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
143289b92e6fSPeter Brune 
143389b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps()
143489b92e6fSPeter Brune @*/
143589b92e6fSPeter Brune 
143689b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) {
143789b92e6fSPeter Brune   PetscFunctionBegin;
143889b92e6fSPeter Brune   snes->gssweeps = sweeps;
143989b92e6fSPeter Brune   PetscFunctionReturn(0);
144089b92e6fSPeter Brune }
144189b92e6fSPeter Brune 
144289b92e6fSPeter Brune 
144389b92e6fSPeter Brune #undef __FUNCT__
144489b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps"
144589b92e6fSPeter Brune /*@
144689b92e6fSPeter Brune    SNESGetGSSweeps - Gets the number of sweeps GS will use.
144789b92e6fSPeter Brune 
144889b92e6fSPeter Brune    Input Parameters:
144989b92e6fSPeter Brune .  snes   - the SNES context
145089b92e6fSPeter Brune 
145189b92e6fSPeter Brune    Output Parameters:
145289b92e6fSPeter Brune .  sweeps  - the number of sweeps of GS to perform.
145389b92e6fSPeter Brune 
145489b92e6fSPeter Brune    Level: intermediate
145589b92e6fSPeter Brune 
145689b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
145789b92e6fSPeter Brune 
145889b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps()
145989b92e6fSPeter Brune @*/
146089b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) {
146189b92e6fSPeter Brune   PetscFunctionBegin;
146289b92e6fSPeter Brune   *sweeps = snes->gssweeps;
146389b92e6fSPeter Brune   PetscFunctionReturn(0);
146489b92e6fSPeter Brune }
146589b92e6fSPeter Brune 
146689b92e6fSPeter Brune #undef __FUNCT__
14678b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction"
14688b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
14698b0a5094SBarry Smith {
14708b0a5094SBarry Smith   PetscErrorCode ierr;
14716cab3a1bSJed Brown   void *functx,*jacctx;
14726cab3a1bSJed Brown 
14738b0a5094SBarry Smith   PetscFunctionBegin;
14746cab3a1bSJed Brown   ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
14756cab3a1bSJed Brown   ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr);
14768b0a5094SBarry Smith   /*  A(x)*x - b(x) */
14776cab3a1bSJed Brown   ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr);
14786cab3a1bSJed Brown   ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr);
14798b0a5094SBarry Smith   ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
14808b0a5094SBarry Smith   ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
14818b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
14828b0a5094SBarry Smith   ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr);
14838b0a5094SBarry Smith   PetscFunctionReturn(0);
14848b0a5094SBarry Smith }
14858b0a5094SBarry Smith 
14868b0a5094SBarry Smith #undef __FUNCT__
14878b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian"
14888b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
14898b0a5094SBarry Smith {
14908b0a5094SBarry Smith   PetscFunctionBegin;
14918b0a5094SBarry Smith   *flag = snes->matstruct;
14928b0a5094SBarry Smith   PetscFunctionReturn(0);
14938b0a5094SBarry Smith }
14948b0a5094SBarry Smith 
14958b0a5094SBarry Smith #undef __FUNCT__
14968b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard"
14978b0a5094SBarry Smith /*@C
14980d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
14998b0a5094SBarry Smith 
15008b0a5094SBarry Smith    Logically Collective on SNES
15018b0a5094SBarry Smith 
15028b0a5094SBarry Smith    Input Parameters:
15038b0a5094SBarry Smith +  snes - the SNES context
15048b0a5094SBarry Smith .  r - vector to store function value
15058b0a5094SBarry Smith .  func - function evaluation routine
15068b0a5094SBarry 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)
15078b0a5094SBarry Smith .  mat - matrix to store A
15088b0a5094SBarry Smith .  mfunc  - function to compute matrix value
15098b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
15108b0a5094SBarry Smith          function evaluation routine (may be PETSC_NULL)
15118b0a5094SBarry Smith 
15128b0a5094SBarry Smith    Calling sequence of func:
15138b0a5094SBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
15148b0a5094SBarry Smith 
15158b0a5094SBarry Smith +  f - function vector
15168b0a5094SBarry Smith -  ctx - optional user-defined function context
15178b0a5094SBarry Smith 
15188b0a5094SBarry Smith    Calling sequence of mfunc:
15198b0a5094SBarry Smith $     mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx);
15208b0a5094SBarry Smith 
15218b0a5094SBarry Smith +  x - input vector
15228b0a5094SBarry 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(),
15238b0a5094SBarry Smith           normally just pass mat in this location
15248b0a5094SBarry Smith .  mat - form A(x) matrix
15258b0a5094SBarry Smith .  flag - flag indicating information about the preconditioner matrix
15268b0a5094SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
15278b0a5094SBarry Smith -  ctx - [optional] user-defined Jacobian context
15288b0a5094SBarry Smith 
15298b0a5094SBarry Smith    Notes:
15308b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
15318b0a5094SBarry Smith 
15328b0a5094SBarry 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}
15338b0a5094SBarry 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.
15348b0a5094SBarry Smith 
15358b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
15368b0a5094SBarry Smith 
15370d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
15380d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
15398b0a5094SBarry Smith 
15408b0a5094SBarry 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
15418b0a5094SBarry 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
15428b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
15438b0a5094SBarry Smith 
15448b0a5094SBarry Smith    Level: beginner
15458b0a5094SBarry Smith 
15468b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function
15478b0a5094SBarry Smith 
15480d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard()
15498b0a5094SBarry Smith @*/
15508b0a5094SBarry 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)
15518b0a5094SBarry Smith {
15528b0a5094SBarry Smith   PetscErrorCode ierr;
15538b0a5094SBarry Smith   PetscFunctionBegin;
15548b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15558b0a5094SBarry Smith   snes->ops->computepfunction = func;
15568b0a5094SBarry Smith   snes->ops->computepjacobian = mfunc;
15578b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
15588b0a5094SBarry Smith   ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
15598b0a5094SBarry Smith   PetscFunctionReturn(0);
15608b0a5094SBarry Smith }
15618b0a5094SBarry Smith 
15628b0a5094SBarry Smith #undef __FUNCT__
1563d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess"
1564d25893d9SBarry Smith /*@C
1565d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1566d25893d9SBarry Smith 
1567d25893d9SBarry Smith    Logically Collective on SNES
1568d25893d9SBarry Smith 
1569d25893d9SBarry Smith    Input Parameters:
1570d25893d9SBarry Smith +  snes - the SNES context
1571d25893d9SBarry Smith .  func - function evaluation routine
1572d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
1573d25893d9SBarry Smith          function evaluation routine (may be PETSC_NULL)
1574d25893d9SBarry Smith 
1575d25893d9SBarry Smith    Calling sequence of func:
1576d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
1577d25893d9SBarry Smith 
1578d25893d9SBarry Smith .  f - function vector
1579d25893d9SBarry Smith -  ctx - optional user-defined function context
1580d25893d9SBarry Smith 
1581d25893d9SBarry Smith    Level: intermediate
1582d25893d9SBarry Smith 
1583d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
1584d25893d9SBarry Smith 
1585d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1586d25893d9SBarry Smith @*/
1587d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1588d25893d9SBarry Smith {
1589d25893d9SBarry Smith   PetscFunctionBegin;
1590d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1591d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
1592d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
1593d25893d9SBarry Smith   PetscFunctionReturn(0);
1594d25893d9SBarry Smith }
1595d25893d9SBarry Smith 
15963ab0aad5SBarry Smith /* --------------------------------------------------------------- */
15973ab0aad5SBarry Smith #undef __FUNCT__
15981096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
15991096aae1SMatthew Knepley /*@C
16001096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
16011096aae1SMatthew Knepley    it assumes a zero right hand side.
16021096aae1SMatthew Knepley 
16033f9fe445SBarry Smith    Logically Collective on SNES
16041096aae1SMatthew Knepley 
16051096aae1SMatthew Knepley    Input Parameter:
16061096aae1SMatthew Knepley .  snes - the SNES context
16071096aae1SMatthew Knepley 
16081096aae1SMatthew Knepley    Output Parameter:
1609bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
16101096aae1SMatthew Knepley 
16111096aae1SMatthew Knepley    Level: intermediate
16121096aae1SMatthew Knepley 
16131096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
16141096aae1SMatthew Knepley 
161585385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
16161096aae1SMatthew Knepley @*/
16177087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
16181096aae1SMatthew Knepley {
16191096aae1SMatthew Knepley   PetscFunctionBegin;
16200700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
16211096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
162285385478SLisandro Dalcin   *rhs = snes->vec_rhs;
16231096aae1SMatthew Knepley   PetscFunctionReturn(0);
16241096aae1SMatthew Knepley }
16251096aae1SMatthew Knepley 
16261096aae1SMatthew Knepley #undef __FUNCT__
16274a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
16289b94acceSBarry Smith /*@
162936851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
16309b94acceSBarry Smith                          SNESSetFunction().
16319b94acceSBarry Smith 
1632c7afd0dbSLois Curfman McInnes    Collective on SNES
1633c7afd0dbSLois Curfman McInnes 
16349b94acceSBarry Smith    Input Parameters:
1635c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1636c7afd0dbSLois Curfman McInnes -  x - input vector
16379b94acceSBarry Smith 
16389b94acceSBarry Smith    Output Parameter:
16393638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
16409b94acceSBarry Smith 
16411bffabb2SLois Curfman McInnes    Notes:
164236851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
164336851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
164436851e7fSLois Curfman McInnes    themselves.
164536851e7fSLois Curfman McInnes 
164636851e7fSLois Curfman McInnes    Level: developer
164736851e7fSLois Curfman McInnes 
16489b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
16499b94acceSBarry Smith 
1650a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
16519b94acceSBarry Smith @*/
16527087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
16539b94acceSBarry Smith {
1654dfbe8321SBarry Smith   PetscErrorCode ierr;
16556cab3a1bSJed Brown   DM             dm;
16566cab3a1bSJed Brown   SNESDM         sdm;
16579b94acceSBarry Smith 
16583a40ed3dSBarry Smith   PetscFunctionBegin;
16590700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
16600700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
16610700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
1662c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
1663c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
16644ec14c9cSBarry Smith   VecValidValues(x,2,PETSC_TRUE);
1665184914b5SBarry Smith 
16666cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
16676cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
1668d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
16696cab3a1bSJed Brown   if (sdm->computefunction) {
1670d64ed03dSBarry Smith     PetscStackPush("SNES user function");
16716cab3a1bSJed Brown     ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
1672d64ed03dSBarry Smith     PetscStackPop;
167373250ac0SBarry Smith   } else if (snes->dm) {
1674644e2e5bSBarry Smith     ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr);
1675c90fad12SPeter Brune   } else if (snes->vec_rhs) {
1676c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
1677644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
167885385478SLisandro Dalcin   if (snes->vec_rhs) {
167985385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
16803ab0aad5SBarry Smith   }
1681ae3c334cSLois Curfman McInnes   snes->nfuncs++;
1682d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
16834ec14c9cSBarry Smith   VecValidValues(y,3,PETSC_FALSE);
16843a40ed3dSBarry Smith   PetscFunctionReturn(0);
16859b94acceSBarry Smith }
16869b94acceSBarry Smith 
16874a2ae208SSatish Balay #undef __FUNCT__
1688646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS"
1689c79ef259SPeter Brune /*@
1690c79ef259SPeter Brune    SNESComputeGS - Calls the Gauss-Seidel function that has been set with
1691c79ef259SPeter Brune                    SNESSetGS().
1692c79ef259SPeter Brune 
1693c79ef259SPeter Brune    Collective on SNES
1694c79ef259SPeter Brune 
1695c79ef259SPeter Brune    Input Parameters:
1696c79ef259SPeter Brune +  snes - the SNES context
1697c79ef259SPeter Brune .  x - input vector
1698c79ef259SPeter Brune -  b - rhs vector
1699c79ef259SPeter Brune 
1700c79ef259SPeter Brune    Output Parameter:
1701c79ef259SPeter Brune .  x - new solution vector
1702c79ef259SPeter Brune 
1703c79ef259SPeter Brune    Notes:
1704c79ef259SPeter Brune    SNESComputeGS() is typically used within composed nonlinear solver
1705c79ef259SPeter Brune    implementations, so most users would not generally call this routine
1706c79ef259SPeter Brune    themselves.
1707c79ef259SPeter Brune 
1708c79ef259SPeter Brune    Level: developer
1709c79ef259SPeter Brune 
1710c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function
1711c79ef259SPeter Brune 
1712c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction()
1713c79ef259SPeter Brune @*/
1714646217ecSPeter Brune PetscErrorCode  SNESComputeGS(SNES snes,Vec b,Vec x)
1715646217ecSPeter Brune {
1716646217ecSPeter Brune   PetscErrorCode ierr;
171789b92e6fSPeter Brune   PetscInt i;
17186cab3a1bSJed Brown   DM dm;
17196cab3a1bSJed Brown   SNESDM sdm;
1720646217ecSPeter Brune 
1721646217ecSPeter Brune   PetscFunctionBegin;
1722646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1723646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
1724646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
1725646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
1726646217ecSPeter Brune   if(b) PetscCheckSameComm(snes,1,b,3);
17274ec14c9cSBarry Smith   if (b) VecValidValues(b,2,PETSC_TRUE);
1728701cf23dSPeter Brune   ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
17296cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
17306cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
17316cab3a1bSJed Brown   if (sdm->computegs) {
173289b92e6fSPeter Brune     for (i = 0; i < snes->gssweeps; i++) {
1733646217ecSPeter Brune       PetscStackPush("SNES user GS");
17346cab3a1bSJed Brown       ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
1735646217ecSPeter Brune       PetscStackPop;
173689b92e6fSPeter Brune     }
1737646217ecSPeter Brune   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve().");
1738701cf23dSPeter Brune   ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
17394ec14c9cSBarry Smith   VecValidValues(x,3,PETSC_FALSE);
1740646217ecSPeter Brune   PetscFunctionReturn(0);
1741646217ecSPeter Brune }
1742646217ecSPeter Brune 
1743646217ecSPeter Brune 
1744646217ecSPeter Brune #undef __FUNCT__
17454a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
174662fef451SLois Curfman McInnes /*@
174762fef451SLois Curfman McInnes    SNESComputeJacobian - Computes the Jacobian matrix that has been
174862fef451SLois Curfman McInnes    set with SNESSetJacobian().
174962fef451SLois Curfman McInnes 
1750c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
1751c7afd0dbSLois Curfman McInnes 
175262fef451SLois Curfman McInnes    Input Parameters:
1753c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1754c7afd0dbSLois Curfman McInnes -  x - input vector
175562fef451SLois Curfman McInnes 
175662fef451SLois Curfman McInnes    Output Parameters:
1757c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
175862fef451SLois Curfman McInnes .  B - optional preconditioning matrix
17592b668275SBarry Smith -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1760fee21e36SBarry Smith 
1761e35cf81dSBarry Smith   Options Database Keys:
1762e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
1763693365a8SJed Brown .    -snes_lag_jacobian <lag>
1764693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
1765693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
1766693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
17674c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
1768c01495d3SJed Brown .    -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference
1769c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
1770c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
1771c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
1772c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
17734c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
1774c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
1775c01495d3SJed Brown 
1776e35cf81dSBarry Smith 
177762fef451SLois Curfman McInnes    Notes:
177862fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
177962fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
178062fef451SLois Curfman McInnes 
178194b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the
1782dc5a77f8SLois Curfman McInnes    flag parameter.
178362fef451SLois Curfman McInnes 
178436851e7fSLois Curfman McInnes    Level: developer
178536851e7fSLois Curfman McInnes 
178662fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
178762fef451SLois Curfman McInnes 
1788e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
178962fef451SLois Curfman McInnes @*/
17907087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
17919b94acceSBarry Smith {
1792dfbe8321SBarry Smith   PetscErrorCode ierr;
1793ace3abfcSBarry Smith   PetscBool      flag;
17946cab3a1bSJed Brown   DM             dm;
17956cab3a1bSJed Brown   SNESDM         sdm;
17963a40ed3dSBarry Smith 
17973a40ed3dSBarry Smith   PetscFunctionBegin;
17980700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
17990700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
18004482741eSBarry Smith   PetscValidPointer(flg,5);
1801c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
18024ec14c9cSBarry Smith   VecValidValues(X,2,PETSC_TRUE);
18036cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
18046cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
18056cab3a1bSJed Brown   if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
1806ebd3b9afSBarry Smith 
1807ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
1808ebd3b9afSBarry Smith 
1809fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
1810fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
1811fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
1812fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
1813e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1814e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
1815ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1816ebd3b9afSBarry Smith     if (flag) {
1817ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1818ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1819ebd3b9afSBarry Smith     }
1820e35cf81dSBarry Smith     PetscFunctionReturn(0);
1821e35cf81dSBarry Smith   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
1822e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1823e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
1824ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1825ebd3b9afSBarry Smith     if (flag) {
1826ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1827ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1828ebd3b9afSBarry Smith     }
1829e35cf81dSBarry Smith     PetscFunctionReturn(0);
1830e35cf81dSBarry Smith   }
1831e35cf81dSBarry Smith 
1832c4fc05e7SBarry Smith   *flg = DIFFERENT_NONZERO_PATTERN;
1833e35cf81dSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1834d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
18356cab3a1bSJed Brown   ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr);
1836d64ed03dSBarry Smith   PetscStackPop;
1837d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1838a8054027SBarry Smith 
18393b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
18403b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
18413b4f5425SBarry Smith     snes->lagpreconditioner = -1;
18423b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
1843a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1844a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
1845a8054027SBarry Smith   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
1846a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1847a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
1848a8054027SBarry Smith   }
1849a8054027SBarry Smith 
18506d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
18510700a824SBarry Smith   /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
18520700a824SBarry Smith     PetscValidHeaderSpecific(*B,MAT_CLASSID,4);   */
1853693365a8SJed Brown   {
1854693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
1855693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr);
1856693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
1857693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
1858693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr);
1859693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
1860693365a8SJed Brown       Mat Bexp_mine = PETSC_NULL,Bexp,FDexp;
1861693365a8SJed Brown       MatStructure mstruct;
1862693365a8SJed Brown       PetscViewer vdraw,vstdout;
18636b3a5b13SJed Brown       PetscBool flg;
1864693365a8SJed Brown       if (flag_operator) {
1865693365a8SJed Brown         ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr);
1866693365a8SJed Brown         Bexp = Bexp_mine;
1867693365a8SJed Brown       } else {
1868693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
1869693365a8SJed Brown         ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
1870693365a8SJed Brown         if (flg) Bexp = *B;
1871693365a8SJed Brown         else {
1872693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
1873693365a8SJed Brown           ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr);
1874693365a8SJed Brown           Bexp = Bexp_mine;
1875693365a8SJed Brown         }
1876693365a8SJed Brown       }
1877693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
1878693365a8SJed Brown       ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr);
1879693365a8SJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
1880693365a8SJed Brown       if (flag_draw || flag_contour) {
1881693365a8SJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
1882693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
1883693365a8SJed Brown       } else vdraw = PETSC_NULL;
1884693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr);
1885693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
1886693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
1887693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
1888693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
1889693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
1890693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
1891693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
1892693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
1893693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
1894693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
1895693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
1896693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
1897693365a8SJed Brown       }
1898693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
1899693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
1900693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
1901693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
1902693365a8SJed Brown     }
1903693365a8SJed Brown   }
19044c30e9fbSJed Brown   {
19056719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
19066719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
19074c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr);
19086719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr);
19094c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
19104c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
19116719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr);
19126719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr);
19136719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr);
19146719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
19154c30e9fbSJed Brown       Mat Bfd;
19164c30e9fbSJed Brown       MatStructure mstruct;
19174c30e9fbSJed Brown       PetscViewer vdraw,vstdout;
19184c30e9fbSJed Brown       ISColoring iscoloring;
19194c30e9fbSJed Brown       MatFDColoring matfdcoloring;
19204c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
19214c30e9fbSJed Brown       void *funcctx;
19226719d8e4SJed Brown       PetscReal norm1,norm2,normmax;
19234c30e9fbSJed Brown 
19244c30e9fbSJed Brown       ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
19254c30e9fbSJed Brown       ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
19264c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
19274c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
19284c30e9fbSJed Brown 
19294c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
19304c30e9fbSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr);
19314c30e9fbSJed Brown       ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr);
19324c30e9fbSJed Brown       ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
19334c30e9fbSJed Brown       ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
19344c30e9fbSJed Brown       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
19354c30e9fbSJed Brown       ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr);
19364c30e9fbSJed Brown       ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
19374c30e9fbSJed Brown 
19384c30e9fbSJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
19394c30e9fbSJed Brown       if (flag_draw || flag_contour) {
19404c30e9fbSJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
19414c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
19424c30e9fbSJed Brown       } else vdraw = PETSC_NULL;
19434c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
19446719d8e4SJed Brown       if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);}
19454c30e9fbSJed Brown       if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);}
19464c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
19476719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
19484c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
19494c30e9fbSJed Brown       ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
19504c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
19516719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
19524c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
19536719d8e4SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr);
19546719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
19554c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
19564c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
19574c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
19584c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
19594c30e9fbSJed Brown       }
19604c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
19616719d8e4SJed Brown 
19626719d8e4SJed Brown       if (flag_threshold) {
19636719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
19646719d8e4SJed Brown         ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr);
19656719d8e4SJed Brown         ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr);
19666719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
19676719d8e4SJed Brown           const PetscScalar *ba,*ca;
19686719d8e4SJed Brown           const PetscInt *bj,*cj;
19696719d8e4SJed Brown           PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
19706719d8e4SJed Brown           PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0;
19716719d8e4SJed Brown           ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
19726719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
19736719d8e4SJed Brown           if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
19746719d8e4SJed Brown           for (j=0; j<bn; j++) {
19756719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
19766719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
19776719d8e4SJed Brown               maxentrycol = bj[j];
19786719d8e4SJed Brown               maxentry = PetscRealPart(ba[j]);
19796719d8e4SJed Brown             }
19806719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
19816719d8e4SJed Brown               maxdiffcol = bj[j];
19826719d8e4SJed Brown               maxdiff = PetscRealPart(ca[j]);
19836719d8e4SJed Brown             }
19846719d8e4SJed Brown             if (rdiff > maxrdiff) {
19856719d8e4SJed Brown               maxrdiffcol = bj[j];
19866719d8e4SJed Brown               maxrdiff = rdiff;
19876719d8e4SJed Brown             }
19886719d8e4SJed Brown           }
19896719d8e4SJed Brown           if (maxrdiff > 1) {
19906719d8e4SJed 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);
19916719d8e4SJed Brown             for (j=0; j<bn; j++) {
19926719d8e4SJed Brown               PetscReal rdiff;
19936719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
19946719d8e4SJed Brown               if (rdiff > 1) {
19956719d8e4SJed Brown                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr);
19966719d8e4SJed Brown               }
19976719d8e4SJed Brown             }
19986719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
19996719d8e4SJed Brown           }
20006719d8e4SJed Brown           ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
20016719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
20026719d8e4SJed Brown         }
20036719d8e4SJed Brown       }
20044c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
20054c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
20064c30e9fbSJed Brown     }
20074c30e9fbSJed Brown   }
20083a40ed3dSBarry Smith   PetscFunctionReturn(0);
20099b94acceSBarry Smith }
20109b94acceSBarry Smith 
20114a2ae208SSatish Balay #undef __FUNCT__
20124a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
20139b94acceSBarry Smith /*@C
20149b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2015044dda88SLois Curfman McInnes    location to store the matrix.
20169b94acceSBarry Smith 
20173f9fe445SBarry Smith    Logically Collective on SNES and Mat
2018c7afd0dbSLois Curfman McInnes 
20199b94acceSBarry Smith    Input Parameters:
2020c7afd0dbSLois Curfman McInnes +  snes - the SNES context
20219b94acceSBarry Smith .  A - Jacobian matrix
20229b94acceSBarry Smith .  B - preconditioner matrix (usually same as the Jacobian)
2023efd51863SBarry Smith .  func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value)
2024c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
2025efd51863SBarry Smith          Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value)
20269b94acceSBarry Smith 
20279b94acceSBarry Smith    Calling sequence of func:
20288d76a1e5SLois Curfman McInnes $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
20299b94acceSBarry Smith 
2030c7afd0dbSLois Curfman McInnes +  x - input vector
20319b94acceSBarry Smith .  A - Jacobian matrix
20329b94acceSBarry Smith .  B - preconditioner matrix, usually the same as A
2033ac21db08SLois Curfman McInnes .  flag - flag indicating information about the preconditioner matrix
20342b668275SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
2035c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined Jacobian context
20369b94acceSBarry Smith 
20379b94acceSBarry Smith    Notes:
203894b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the flag
20392cd2dfdcSLois Curfman McInnes    output parameter in the routine func().  Be sure to read this information!
2040ac21db08SLois Curfman McInnes 
2041ac21db08SLois Curfman McInnes    The routine func() takes Mat * as the matrix arguments rather than Mat.
20429b94acceSBarry Smith    This allows the Jacobian evaluation routine to replace A and/or B with a
20439b94acceSBarry Smith    completely new new matrix structure (not just different matrix elements)
20449b94acceSBarry Smith    when appropriate, for instance, if the nonzero structure is changing
20459b94acceSBarry Smith    throughout the global iterations.
20469b94acceSBarry Smith 
204716913363SBarry Smith    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
204816913363SBarry Smith    each matrix.
204916913363SBarry Smith 
2050a8a26c1eSJed Brown    If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument
2051a8a26c1eSJed Brown    must be a MatFDColoring.
2052a8a26c1eSJed Brown 
2053c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2054c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2055c3cc8fd1SJed Brown 
205636851e7fSLois Curfman McInnes    Level: beginner
205736851e7fSLois Curfman McInnes 
20589b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
20599b94acceSBarry Smith 
20603ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
20619b94acceSBarry Smith @*/
20627087cfbeSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
20639b94acceSBarry Smith {
2064dfbe8321SBarry Smith   PetscErrorCode ierr;
20656cab3a1bSJed Brown   DM             dm;
20663a7fca6bSBarry Smith 
20673a40ed3dSBarry Smith   PetscFunctionBegin;
20680700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
20690700a824SBarry Smith   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
20700700a824SBarry Smith   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
2071c9780b6fSBarry Smith   if (A) PetscCheckSameComm(snes,1,A,2);
207206975374SJed Brown   if (B) PetscCheckSameComm(snes,1,B,3);
20736cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
20746cab3a1bSJed Brown   ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr);
20753a7fca6bSBarry Smith   if (A) {
20767dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
20776bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
20789b94acceSBarry Smith     snes->jacobian = A;
20793a7fca6bSBarry Smith   }
20803a7fca6bSBarry Smith   if (B) {
20817dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
20826bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
20839b94acceSBarry Smith     snes->jacobian_pre = B;
20843a7fca6bSBarry Smith   }
20853a40ed3dSBarry Smith   PetscFunctionReturn(0);
20869b94acceSBarry Smith }
208762fef451SLois Curfman McInnes 
20884a2ae208SSatish Balay #undef __FUNCT__
20894a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
2090c2aafc4cSSatish Balay /*@C
2091b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2092b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2093b4fd4287SBarry Smith 
2094c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2095c7afd0dbSLois Curfman McInnes 
2096b4fd4287SBarry Smith    Input Parameter:
2097b4fd4287SBarry Smith .  snes - the nonlinear solver context
2098b4fd4287SBarry Smith 
2099b4fd4287SBarry Smith    Output Parameters:
2100c7afd0dbSLois Curfman McInnes +  A - location to stash Jacobian matrix (or PETSC_NULL)
2101b4fd4287SBarry Smith .  B - location to stash preconditioner matrix (or PETSC_NULL)
210270e92668SMatthew Knepley .  func - location to put Jacobian function (or PETSC_NULL)
210370e92668SMatthew Knepley -  ctx - location to stash Jacobian ctx (or PETSC_NULL)
2104fee21e36SBarry Smith 
210536851e7fSLois Curfman McInnes    Level: advanced
210636851e7fSLois Curfman McInnes 
2107b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian()
2108b4fd4287SBarry Smith @*/
21097087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
2110b4fd4287SBarry Smith {
21116cab3a1bSJed Brown   PetscErrorCode ierr;
21126cab3a1bSJed Brown   DM             dm;
21136cab3a1bSJed Brown   SNESDM         sdm;
21146cab3a1bSJed Brown 
21153a40ed3dSBarry Smith   PetscFunctionBegin;
21160700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2117b4fd4287SBarry Smith   if (A)    *A    = snes->jacobian;
2118b4fd4287SBarry Smith   if (B)    *B    = snes->jacobian_pre;
21196cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
21206cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
21216cab3a1bSJed Brown   if (func) *func = sdm->computejacobian;
21226cab3a1bSJed Brown   if (ctx)  *ctx  = sdm->jacobianctx;
21233a40ed3dSBarry Smith   PetscFunctionReturn(0);
2124b4fd4287SBarry Smith }
2125b4fd4287SBarry Smith 
21269b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
21279b94acceSBarry Smith 
21284a2ae208SSatish Balay #undef __FUNCT__
21294a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
21309b94acceSBarry Smith /*@
21319b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
2132272ac6f2SLois Curfman McInnes    of a nonlinear solver.
21339b94acceSBarry Smith 
2134fee21e36SBarry Smith    Collective on SNES
2135fee21e36SBarry Smith 
2136c7afd0dbSLois Curfman McInnes    Input Parameters:
213770e92668SMatthew Knepley .  snes - the SNES context
2138c7afd0dbSLois Curfman McInnes 
2139272ac6f2SLois Curfman McInnes    Notes:
2140272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
2141272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
2142272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
2143272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
2144272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
2145272ac6f2SLois Curfman McInnes 
214636851e7fSLois Curfman McInnes    Level: advanced
214736851e7fSLois Curfman McInnes 
21489b94acceSBarry Smith .keywords: SNES, nonlinear, setup
21499b94acceSBarry Smith 
21509b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
21519b94acceSBarry Smith @*/
21527087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
21539b94acceSBarry Smith {
2154dfbe8321SBarry Smith   PetscErrorCode ierr;
21556cab3a1bSJed Brown   DM             dm;
21566cab3a1bSJed Brown   SNESDM         sdm;
21573a40ed3dSBarry Smith 
21583a40ed3dSBarry Smith   PetscFunctionBegin;
21590700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
21604dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
21619b94acceSBarry Smith 
21627adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
216385385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
216485385478SLisandro Dalcin   }
216585385478SLisandro Dalcin 
2166a63bb30eSJed Brown   ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
216717186662SBarry Smith   if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
216858c9b817SLisandro Dalcin   if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
216958c9b817SLisandro Dalcin 
217058c9b817SLisandro Dalcin   if (!snes->vec_sol_update /* && snes->vec_sol */) {
217158c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
217258c9b817SLisandro Dalcin     ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr);
217358c9b817SLisandro Dalcin   }
217458c9b817SLisandro Dalcin 
21756cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
21766cab3a1bSJed Brown   ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */
21776cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
21786cab3a1bSJed Brown   if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc");
21796cab3a1bSJed Brown   if (!snes->vec_func) {
21806cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2181214df951SJed Brown   }
2182efd51863SBarry Smith 
2183b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
2184b710008aSBarry Smith 
2185f1c6b773SPeter Brune   if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);}
21869e764e56SPeter Brune 
2187d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
2188d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
2189d25893d9SBarry Smith   }
2190d25893d9SBarry Smith 
2191410397dcSLisandro Dalcin   if (snes->ops->setup) {
2192410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2193410397dcSLisandro Dalcin   }
219458c9b817SLisandro Dalcin 
21957aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
21963a40ed3dSBarry Smith   PetscFunctionReturn(0);
21979b94acceSBarry Smith }
21989b94acceSBarry Smith 
21994a2ae208SSatish Balay #undef __FUNCT__
220037596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
220137596af1SLisandro Dalcin /*@
220237596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
220337596af1SLisandro Dalcin 
220437596af1SLisandro Dalcin    Collective on SNES
220537596af1SLisandro Dalcin 
220637596af1SLisandro Dalcin    Input Parameter:
220737596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
220837596af1SLisandro Dalcin 
2209d25893d9SBarry Smith    Level: intermediate
2210d25893d9SBarry Smith 
2211d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
221237596af1SLisandro Dalcin 
221337596af1SLisandro Dalcin .keywords: SNES, destroy
221437596af1SLisandro Dalcin 
221537596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
221637596af1SLisandro Dalcin @*/
221737596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
221837596af1SLisandro Dalcin {
221937596af1SLisandro Dalcin   PetscErrorCode ierr;
222037596af1SLisandro Dalcin 
222137596af1SLisandro Dalcin   PetscFunctionBegin;
222237596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2223d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
2224d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
2225d25893d9SBarry Smith     snes->user = PETSC_NULL;
2226d25893d9SBarry Smith   }
22278a23116dSBarry Smith   if (snes->pc) {
22288a23116dSBarry Smith     ierr = SNESReset(snes->pc);CHKERRQ(ierr);
22298a23116dSBarry Smith   }
22308a23116dSBarry Smith 
223137596af1SLisandro Dalcin   if (snes->ops->reset) {
223237596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
223337596af1SLisandro Dalcin   }
22349e764e56SPeter Brune   if (snes->ksp) {
22359e764e56SPeter Brune     ierr = KSPReset(snes->ksp);CHKERRQ(ierr);
22369e764e56SPeter Brune   }
22379e764e56SPeter Brune 
22389e764e56SPeter Brune   if (snes->linesearch) {
2239f1c6b773SPeter Brune     ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr);
22409e764e56SPeter Brune   }
22419e764e56SPeter Brune 
22426bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
22436bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
22446bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
22456bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
22466bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
22476bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2248c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
2249c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
225037596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
225137596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
225237596af1SLisandro Dalcin   PetscFunctionReturn(0);
225337596af1SLisandro Dalcin }
225437596af1SLisandro Dalcin 
225537596af1SLisandro Dalcin #undef __FUNCT__
22564a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
225752baeb72SSatish Balay /*@
22589b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
22599b94acceSBarry Smith    with SNESCreate().
22609b94acceSBarry Smith 
2261c7afd0dbSLois Curfman McInnes    Collective on SNES
2262c7afd0dbSLois Curfman McInnes 
22639b94acceSBarry Smith    Input Parameter:
22649b94acceSBarry Smith .  snes - the SNES context
22659b94acceSBarry Smith 
226636851e7fSLois Curfman McInnes    Level: beginner
226736851e7fSLois Curfman McInnes 
22689b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
22699b94acceSBarry Smith 
227063a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
22719b94acceSBarry Smith @*/
22726bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
22739b94acceSBarry Smith {
22746849ba73SBarry Smith   PetscErrorCode ierr;
22753a40ed3dSBarry Smith 
22763a40ed3dSBarry Smith   PetscFunctionBegin;
22776bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
22786bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
22796bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2280d4bb536fSBarry Smith 
22816bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
22828a23116dSBarry Smith   ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr);
22836b8b9a38SLisandro Dalcin 
2284be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
22856bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
22866bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
22876d4c513bSLisandro Dalcin 
22886bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
22896bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
2290f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr);
22916b8b9a38SLisandro Dalcin 
22926bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
22936bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
22946bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
22956b8b9a38SLisandro Dalcin   }
22966bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
22976bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
22986bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
229958c9b817SLisandro Dalcin   }
23006bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2301a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
23023a40ed3dSBarry Smith  PetscFunctionReturn(0);
23039b94acceSBarry Smith }
23049b94acceSBarry Smith 
23059b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
23069b94acceSBarry Smith 
23074a2ae208SSatish Balay #undef __FUNCT__
2308a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
2309a8054027SBarry Smith /*@
2310a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2311a8054027SBarry Smith 
23123f9fe445SBarry Smith    Logically Collective on SNES
2313a8054027SBarry Smith 
2314a8054027SBarry Smith    Input Parameters:
2315a8054027SBarry Smith +  snes - the SNES context
2316a8054027SBarry 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
23173b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2318a8054027SBarry Smith 
2319a8054027SBarry Smith    Options Database Keys:
2320a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2321a8054027SBarry Smith 
2322a8054027SBarry Smith    Notes:
2323a8054027SBarry Smith    The default is 1
2324a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2325a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2326a8054027SBarry Smith 
2327a8054027SBarry Smith    Level: intermediate
2328a8054027SBarry Smith 
2329a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2330a8054027SBarry Smith 
2331e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2332a8054027SBarry Smith 
2333a8054027SBarry Smith @*/
23347087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2335a8054027SBarry Smith {
2336a8054027SBarry Smith   PetscFunctionBegin;
23370700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2338e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2339e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2340c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2341a8054027SBarry Smith   snes->lagpreconditioner = lag;
2342a8054027SBarry Smith   PetscFunctionReturn(0);
2343a8054027SBarry Smith }
2344a8054027SBarry Smith 
2345a8054027SBarry Smith #undef __FUNCT__
2346efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
2347efd51863SBarry Smith /*@
2348efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2349efd51863SBarry Smith 
2350efd51863SBarry Smith    Logically Collective on SNES
2351efd51863SBarry Smith 
2352efd51863SBarry Smith    Input Parameters:
2353efd51863SBarry Smith +  snes - the SNES context
2354efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
2355efd51863SBarry Smith 
2356efd51863SBarry Smith    Options Database Keys:
2357efd51863SBarry Smith .    -snes_grid_sequence <steps>
2358efd51863SBarry Smith 
2359efd51863SBarry Smith    Level: intermediate
2360efd51863SBarry Smith 
2361c0df2a02SJed Brown    Notes:
2362c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2363c0df2a02SJed Brown 
2364efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2365efd51863SBarry Smith 
2366efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2367efd51863SBarry Smith 
2368efd51863SBarry Smith @*/
2369efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2370efd51863SBarry Smith {
2371efd51863SBarry Smith   PetscFunctionBegin;
2372efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2373efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
2374efd51863SBarry Smith   snes->gridsequence = steps;
2375efd51863SBarry Smith   PetscFunctionReturn(0);
2376efd51863SBarry Smith }
2377efd51863SBarry Smith 
2378efd51863SBarry Smith #undef __FUNCT__
2379a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
2380a8054027SBarry Smith /*@
2381a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
2382a8054027SBarry Smith 
23833f9fe445SBarry Smith    Not Collective
2384a8054027SBarry Smith 
2385a8054027SBarry Smith    Input Parameter:
2386a8054027SBarry Smith .  snes - the SNES context
2387a8054027SBarry Smith 
2388a8054027SBarry Smith    Output Parameter:
2389a8054027SBarry 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
23903b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2391a8054027SBarry Smith 
2392a8054027SBarry Smith    Options Database Keys:
2393a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2394a8054027SBarry Smith 
2395a8054027SBarry Smith    Notes:
2396a8054027SBarry Smith    The default is 1
2397a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2398a8054027SBarry Smith 
2399a8054027SBarry Smith    Level: intermediate
2400a8054027SBarry Smith 
2401a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2402a8054027SBarry Smith 
2403a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
2404a8054027SBarry Smith 
2405a8054027SBarry Smith @*/
24067087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
2407a8054027SBarry Smith {
2408a8054027SBarry Smith   PetscFunctionBegin;
24090700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2410a8054027SBarry Smith   *lag = snes->lagpreconditioner;
2411a8054027SBarry Smith   PetscFunctionReturn(0);
2412a8054027SBarry Smith }
2413a8054027SBarry Smith 
2414a8054027SBarry Smith #undef __FUNCT__
2415e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
2416e35cf81dSBarry Smith /*@
2417e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
2418e35cf81dSBarry Smith      often the preconditioner is rebuilt.
2419e35cf81dSBarry Smith 
24203f9fe445SBarry Smith    Logically Collective on SNES
2421e35cf81dSBarry Smith 
2422e35cf81dSBarry Smith    Input Parameters:
2423e35cf81dSBarry Smith +  snes - the SNES context
2424e35cf81dSBarry 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
2425fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
2426e35cf81dSBarry Smith 
2427e35cf81dSBarry Smith    Options Database Keys:
2428e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2429e35cf81dSBarry Smith 
2430e35cf81dSBarry Smith    Notes:
2431e35cf81dSBarry Smith    The default is 1
2432e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2433fe3ffe1eSBarry 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
2434fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
2435e35cf81dSBarry Smith 
2436e35cf81dSBarry Smith    Level: intermediate
2437e35cf81dSBarry Smith 
2438e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2439e35cf81dSBarry Smith 
2440e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
2441e35cf81dSBarry Smith 
2442e35cf81dSBarry Smith @*/
24437087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
2444e35cf81dSBarry Smith {
2445e35cf81dSBarry Smith   PetscFunctionBegin;
24460700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2447e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2448e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2449c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2450e35cf81dSBarry Smith   snes->lagjacobian = lag;
2451e35cf81dSBarry Smith   PetscFunctionReturn(0);
2452e35cf81dSBarry Smith }
2453e35cf81dSBarry Smith 
2454e35cf81dSBarry Smith #undef __FUNCT__
2455e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
2456e35cf81dSBarry Smith /*@
2457e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
2458e35cf81dSBarry Smith 
24593f9fe445SBarry Smith    Not Collective
2460e35cf81dSBarry Smith 
2461e35cf81dSBarry Smith    Input Parameter:
2462e35cf81dSBarry Smith .  snes - the SNES context
2463e35cf81dSBarry Smith 
2464e35cf81dSBarry Smith    Output Parameter:
2465e35cf81dSBarry 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
2466e35cf81dSBarry Smith          the Jacobian is built etc.
2467e35cf81dSBarry Smith 
2468e35cf81dSBarry Smith    Options Database Keys:
2469e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2470e35cf81dSBarry Smith 
2471e35cf81dSBarry Smith    Notes:
2472e35cf81dSBarry Smith    The default is 1
2473e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2474e35cf81dSBarry Smith 
2475e35cf81dSBarry Smith    Level: intermediate
2476e35cf81dSBarry Smith 
2477e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2478e35cf81dSBarry Smith 
2479e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
2480e35cf81dSBarry Smith 
2481e35cf81dSBarry Smith @*/
24827087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
2483e35cf81dSBarry Smith {
2484e35cf81dSBarry Smith   PetscFunctionBegin;
24850700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2486e35cf81dSBarry Smith   *lag = snes->lagjacobian;
2487e35cf81dSBarry Smith   PetscFunctionReturn(0);
2488e35cf81dSBarry Smith }
2489e35cf81dSBarry Smith 
2490e35cf81dSBarry Smith #undef __FUNCT__
24914a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
24929b94acceSBarry Smith /*@
2493d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
24949b94acceSBarry Smith 
24953f9fe445SBarry Smith    Logically Collective on SNES
2496c7afd0dbSLois Curfman McInnes 
24979b94acceSBarry Smith    Input Parameters:
2498c7afd0dbSLois Curfman McInnes +  snes - the SNES context
249970441072SBarry Smith .  abstol - absolute convergence tolerance
250033174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
250133174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
250233174efeSLois Curfman McInnes            of the change in the solution between steps
250333174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2504c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2505fee21e36SBarry Smith 
250633174efeSLois Curfman McInnes    Options Database Keys:
250770441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
2508c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
2509c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
2510c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
2511c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
25129b94acceSBarry Smith 
2513d7a720efSLois Curfman McInnes    Notes:
25149b94acceSBarry Smith    The default maximum number of iterations is 50.
25159b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
25169b94acceSBarry Smith 
251736851e7fSLois Curfman McInnes    Level: intermediate
251836851e7fSLois Curfman McInnes 
251933174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
25209b94acceSBarry Smith 
25212492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
25229b94acceSBarry Smith @*/
25237087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
25249b94acceSBarry Smith {
25253a40ed3dSBarry Smith   PetscFunctionBegin;
25260700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2527c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
2528c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
2529c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
2530c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
2531c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
2532c5eb9154SBarry Smith 
2533ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
2534ab54825eSJed Brown     if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol);
2535ab54825eSJed Brown     snes->abstol = abstol;
2536ab54825eSJed Brown   }
2537ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
2538ab54825eSJed 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);
2539ab54825eSJed Brown     snes->rtol = rtol;
2540ab54825eSJed Brown   }
2541ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
2542ab54825eSJed Brown     if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol);
2543c60f73f4SPeter Brune     snes->stol = stol;
2544ab54825eSJed Brown   }
2545ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
2546ab54825eSJed Brown     if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
2547ab54825eSJed Brown     snes->max_its = maxit;
2548ab54825eSJed Brown   }
2549ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
2550ab54825eSJed Brown     if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
2551ab54825eSJed Brown     snes->max_funcs = maxf;
2552ab54825eSJed Brown   }
2553*88976e71SPeter Brune   snes->tolerancesset = PETSC_TRUE;
25543a40ed3dSBarry Smith   PetscFunctionReturn(0);
25559b94acceSBarry Smith }
25569b94acceSBarry Smith 
25574a2ae208SSatish Balay #undef __FUNCT__
25584a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
25599b94acceSBarry Smith /*@
256033174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
256133174efeSLois Curfman McInnes 
2562c7afd0dbSLois Curfman McInnes    Not Collective
2563c7afd0dbSLois Curfman McInnes 
256433174efeSLois Curfman McInnes    Input Parameters:
2565c7afd0dbSLois Curfman McInnes +  snes - the SNES context
256685385478SLisandro Dalcin .  atol - absolute convergence tolerance
256733174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
256833174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
256933174efeSLois Curfman McInnes            of the change in the solution between steps
257033174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2571c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2572fee21e36SBarry Smith 
257333174efeSLois Curfman McInnes    Notes:
257433174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
257533174efeSLois Curfman McInnes 
257636851e7fSLois Curfman McInnes    Level: intermediate
257736851e7fSLois Curfman McInnes 
257833174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
257933174efeSLois Curfman McInnes 
258033174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
258133174efeSLois Curfman McInnes @*/
25827087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
258333174efeSLois Curfman McInnes {
25843a40ed3dSBarry Smith   PetscFunctionBegin;
25850700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
258685385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
258733174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
2588c60f73f4SPeter Brune   if (stol)  *stol  = snes->stol;
258933174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
259033174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
25913a40ed3dSBarry Smith   PetscFunctionReturn(0);
259233174efeSLois Curfman McInnes }
259333174efeSLois Curfman McInnes 
25944a2ae208SSatish Balay #undef __FUNCT__
25954a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
259633174efeSLois Curfman McInnes /*@
25979b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
25989b94acceSBarry Smith 
25993f9fe445SBarry Smith    Logically Collective on SNES
2600fee21e36SBarry Smith 
2601c7afd0dbSLois Curfman McInnes    Input Parameters:
2602c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2603c7afd0dbSLois Curfman McInnes -  tol - tolerance
2604c7afd0dbSLois Curfman McInnes 
26059b94acceSBarry Smith    Options Database Key:
2606c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
26079b94acceSBarry Smith 
260836851e7fSLois Curfman McInnes    Level: intermediate
260936851e7fSLois Curfman McInnes 
26109b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
26119b94acceSBarry Smith 
26122492ecdbSBarry Smith .seealso: SNESSetTolerances()
26139b94acceSBarry Smith @*/
26147087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
26159b94acceSBarry Smith {
26163a40ed3dSBarry Smith   PetscFunctionBegin;
26170700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2618c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
26199b94acceSBarry Smith   snes->deltatol = tol;
26203a40ed3dSBarry Smith   PetscFunctionReturn(0);
26219b94acceSBarry Smith }
26229b94acceSBarry Smith 
2623df9fa365SBarry Smith /*
2624df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
2625df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
2626df9fa365SBarry Smith    macros instead of functions
2627df9fa365SBarry Smith */
26284a2ae208SSatish Balay #undef __FUNCT__
2629a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
26307087cfbeSBarry Smith PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2631ce1608b8SBarry Smith {
2632dfbe8321SBarry Smith   PetscErrorCode ierr;
2633ce1608b8SBarry Smith 
2634ce1608b8SBarry Smith   PetscFunctionBegin;
26350700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2636a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
2637ce1608b8SBarry Smith   PetscFunctionReturn(0);
2638ce1608b8SBarry Smith }
2639ce1608b8SBarry Smith 
26404a2ae208SSatish Balay #undef __FUNCT__
2641a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
26427087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2643df9fa365SBarry Smith {
2644dfbe8321SBarry Smith   PetscErrorCode ierr;
2645df9fa365SBarry Smith 
2646df9fa365SBarry Smith   PetscFunctionBegin;
2647a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2648df9fa365SBarry Smith   PetscFunctionReturn(0);
2649df9fa365SBarry Smith }
2650df9fa365SBarry Smith 
26514a2ae208SSatish Balay #undef __FUNCT__
2652a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
26536bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
2654df9fa365SBarry Smith {
2655dfbe8321SBarry Smith   PetscErrorCode ierr;
2656df9fa365SBarry Smith 
2657df9fa365SBarry Smith   PetscFunctionBegin;
2658a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2659df9fa365SBarry Smith   PetscFunctionReturn(0);
2660df9fa365SBarry Smith }
2661df9fa365SBarry Smith 
26627087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
2663b271bb04SBarry Smith #undef __FUNCT__
2664b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
26657087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2666b271bb04SBarry Smith {
2667b271bb04SBarry Smith   PetscDrawLG      lg;
2668b271bb04SBarry Smith   PetscErrorCode   ierr;
2669b271bb04SBarry Smith   PetscReal        x,y,per;
2670b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
2671b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
2672b271bb04SBarry Smith   PetscDraw        draw;
2673b271bb04SBarry Smith   PetscFunctionBegin;
2674b271bb04SBarry Smith   if (!monctx) {
2675b271bb04SBarry Smith     MPI_Comm    comm;
2676b271bb04SBarry Smith 
2677b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2678b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
2679b271bb04SBarry Smith   }
2680b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
2681b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2682b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2683b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
2684b271bb04SBarry Smith   x = (PetscReal) n;
2685b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
2686b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2687b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2688b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2689b271bb04SBarry Smith   }
2690b271bb04SBarry Smith 
2691b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
2692b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2693b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2694b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
2695b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
2696b271bb04SBarry Smith   x = (PetscReal) n;
2697b271bb04SBarry Smith   y = 100.0*per;
2698b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2699b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2700b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2701b271bb04SBarry Smith   }
2702b271bb04SBarry Smith 
2703b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
2704b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2705b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2706b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
2707b271bb04SBarry Smith   x = (PetscReal) n;
2708b271bb04SBarry Smith   y = (prev - rnorm)/prev;
2709b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2710b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2711b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2712b271bb04SBarry Smith   }
2713b271bb04SBarry Smith 
2714b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
2715b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2716b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2717b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
2718b271bb04SBarry Smith   x = (PetscReal) n;
2719b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
2720b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
2721b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2722b271bb04SBarry Smith   }
2723b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2724b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2725b271bb04SBarry Smith   }
2726b271bb04SBarry Smith   prev = rnorm;
2727b271bb04SBarry Smith   PetscFunctionReturn(0);
2728b271bb04SBarry Smith }
2729b271bb04SBarry Smith 
2730b271bb04SBarry Smith #undef __FUNCT__
2731b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
27327087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2733b271bb04SBarry Smith {
2734b271bb04SBarry Smith   PetscErrorCode ierr;
2735b271bb04SBarry Smith 
2736b271bb04SBarry Smith   PetscFunctionBegin;
2737b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2738b271bb04SBarry Smith   PetscFunctionReturn(0);
2739b271bb04SBarry Smith }
2740b271bb04SBarry Smith 
2741b271bb04SBarry Smith #undef __FUNCT__
2742b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
27436bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG *draw)
2744b271bb04SBarry Smith {
2745b271bb04SBarry Smith   PetscErrorCode ierr;
2746b271bb04SBarry Smith 
2747b271bb04SBarry Smith   PetscFunctionBegin;
2748b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2749b271bb04SBarry Smith   PetscFunctionReturn(0);
2750b271bb04SBarry Smith }
2751b271bb04SBarry Smith 
27527a03ce2fSLisandro Dalcin #undef __FUNCT__
27537a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
2754228d79bcSJed Brown /*@
2755228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
2756228d79bcSJed Brown 
2757228d79bcSJed Brown    Collective on SNES
2758228d79bcSJed Brown 
2759228d79bcSJed Brown    Input Parameters:
2760228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
2761228d79bcSJed Brown .  iter - iteration number
2762228d79bcSJed Brown -  rnorm - relative norm of the residual
2763228d79bcSJed Brown 
2764228d79bcSJed Brown    Notes:
2765228d79bcSJed Brown    This routine is called by the SNES implementations.
2766228d79bcSJed Brown    It does not typically need to be called by the user.
2767228d79bcSJed Brown 
2768228d79bcSJed Brown    Level: developer
2769228d79bcSJed Brown 
2770228d79bcSJed Brown .seealso: SNESMonitorSet()
2771228d79bcSJed Brown @*/
27727a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
27737a03ce2fSLisandro Dalcin {
27747a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
27757a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
27767a03ce2fSLisandro Dalcin 
27777a03ce2fSLisandro Dalcin   PetscFunctionBegin;
27787a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
27797a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
27807a03ce2fSLisandro Dalcin   }
27817a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
27827a03ce2fSLisandro Dalcin }
27837a03ce2fSLisandro Dalcin 
27849b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
27859b94acceSBarry Smith 
27864a2ae208SSatish Balay #undef __FUNCT__
2787a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
27889b94acceSBarry Smith /*@C
2789a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
27909b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
27919b94acceSBarry Smith    progress.
27929b94acceSBarry Smith 
27933f9fe445SBarry Smith    Logically Collective on SNES
2794fee21e36SBarry Smith 
2795c7afd0dbSLois Curfman McInnes    Input Parameters:
2796c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2797c7afd0dbSLois Curfman McInnes .  func - monitoring routine
2798b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
2799e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
2800b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
2801b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
28029b94acceSBarry Smith 
2803c7afd0dbSLois Curfman McInnes    Calling sequence of func:
2804a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
2805c7afd0dbSLois Curfman McInnes 
2806c7afd0dbSLois Curfman McInnes +    snes - the SNES context
2807c7afd0dbSLois Curfman McInnes .    its - iteration number
2808c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
280940a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
28109b94acceSBarry Smith 
28119665c990SLois Curfman McInnes    Options Database Keys:
2812a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
2813a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
2814a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
2815cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
2816c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
2817a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
2818c7afd0dbSLois Curfman McInnes                             does not cancel those set via
2819c7afd0dbSLois Curfman McInnes                             the options database.
28209665c990SLois Curfman McInnes 
2821639f9d9dSBarry Smith    Notes:
28226bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
2823a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
28246bc08f3fSLois Curfman McInnes    order in which they were set.
2825639f9d9dSBarry Smith 
2826025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
2827025f1a04SBarry Smith 
282836851e7fSLois Curfman McInnes    Level: intermediate
282936851e7fSLois Curfman McInnes 
28309b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
28319b94acceSBarry Smith 
2832a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
28339b94acceSBarry Smith @*/
2834c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
28359b94acceSBarry Smith {
2836b90d0a6eSBarry Smith   PetscInt       i;
2837649052a6SBarry Smith   PetscErrorCode ierr;
2838b90d0a6eSBarry Smith 
28393a40ed3dSBarry Smith   PetscFunctionBegin;
28400700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
284117186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
2842b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
2843649052a6SBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
2844649052a6SBarry Smith       if (monitordestroy) {
2845c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
2846649052a6SBarry Smith       }
2847b90d0a6eSBarry Smith       PetscFunctionReturn(0);
2848b90d0a6eSBarry Smith     }
2849b90d0a6eSBarry Smith   }
2850b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
2851b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
2852639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
28533a40ed3dSBarry Smith   PetscFunctionReturn(0);
28549b94acceSBarry Smith }
28559b94acceSBarry Smith 
28564a2ae208SSatish Balay #undef __FUNCT__
2857a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
28585cd90555SBarry Smith /*@C
2859a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
28605cd90555SBarry Smith 
28613f9fe445SBarry Smith    Logically Collective on SNES
2862c7afd0dbSLois Curfman McInnes 
28635cd90555SBarry Smith    Input Parameters:
28645cd90555SBarry Smith .  snes - the SNES context
28655cd90555SBarry Smith 
28661a480d89SAdministrator    Options Database Key:
2867a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
2868a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
2869c7afd0dbSLois Curfman McInnes     set via the options database
28705cd90555SBarry Smith 
28715cd90555SBarry Smith    Notes:
28725cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
28735cd90555SBarry Smith 
287436851e7fSLois Curfman McInnes    Level: intermediate
287536851e7fSLois Curfman McInnes 
28765cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
28775cd90555SBarry Smith 
2878a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
28795cd90555SBarry Smith @*/
28807087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
28815cd90555SBarry Smith {
2882d952e501SBarry Smith   PetscErrorCode ierr;
2883d952e501SBarry Smith   PetscInt       i;
2884d952e501SBarry Smith 
28855cd90555SBarry Smith   PetscFunctionBegin;
28860700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2887d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
2888d952e501SBarry Smith     if (snes->monitordestroy[i]) {
28893c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
2890d952e501SBarry Smith     }
2891d952e501SBarry Smith   }
28925cd90555SBarry Smith   snes->numbermonitors = 0;
28935cd90555SBarry Smith   PetscFunctionReturn(0);
28945cd90555SBarry Smith }
28955cd90555SBarry Smith 
28964a2ae208SSatish Balay #undef __FUNCT__
28974a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
28989b94acceSBarry Smith /*@C
28999b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
29009b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
29019b94acceSBarry Smith 
29023f9fe445SBarry Smith    Logically Collective on SNES
2903fee21e36SBarry Smith 
2904c7afd0dbSLois Curfman McInnes    Input Parameters:
2905c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2906c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
29077f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
29087f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
29099b94acceSBarry Smith 
2910c7afd0dbSLois Curfman McInnes    Calling sequence of func:
291106ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
2912c7afd0dbSLois Curfman McInnes 
2913c7afd0dbSLois Curfman McInnes +    snes - the SNES context
291406ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
2915c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
2916184914b5SBarry Smith .    reason - reason for convergence/divergence
2917c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
29184b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
29194b27c08aSLois Curfman McInnes -    f - 2-norm of function
29209b94acceSBarry Smith 
292136851e7fSLois Curfman McInnes    Level: advanced
292236851e7fSLois Curfman McInnes 
29239b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
29249b94acceSBarry Smith 
292585385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
29269b94acceSBarry Smith @*/
29277087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
29289b94acceSBarry Smith {
29297f7931b9SBarry Smith   PetscErrorCode ierr;
29307f7931b9SBarry Smith 
29313a40ed3dSBarry Smith   PetscFunctionBegin;
29320700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
293385385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
29347f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
29357f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
29367f7931b9SBarry Smith   }
293785385478SLisandro Dalcin   snes->ops->converged        = func;
29387f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
293985385478SLisandro Dalcin   snes->cnvP                  = cctx;
29403a40ed3dSBarry Smith   PetscFunctionReturn(0);
29419b94acceSBarry Smith }
29429b94acceSBarry Smith 
29434a2ae208SSatish Balay #undef __FUNCT__
29444a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
294552baeb72SSatish Balay /*@
2946184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
2947184914b5SBarry Smith 
2948184914b5SBarry Smith    Not Collective
2949184914b5SBarry Smith 
2950184914b5SBarry Smith    Input Parameter:
2951184914b5SBarry Smith .  snes - the SNES context
2952184914b5SBarry Smith 
2953184914b5SBarry Smith    Output Parameter:
29544d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
2955184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
2956184914b5SBarry Smith 
2957184914b5SBarry Smith    Level: intermediate
2958184914b5SBarry Smith 
2959184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
2960184914b5SBarry Smith 
2961184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
2962184914b5SBarry Smith 
296385385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
2964184914b5SBarry Smith @*/
29657087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
2966184914b5SBarry Smith {
2967184914b5SBarry Smith   PetscFunctionBegin;
29680700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
29694482741eSBarry Smith   PetscValidPointer(reason,2);
2970184914b5SBarry Smith   *reason = snes->reason;
2971184914b5SBarry Smith   PetscFunctionReturn(0);
2972184914b5SBarry Smith }
2973184914b5SBarry Smith 
29744a2ae208SSatish Balay #undef __FUNCT__
29754a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
2976c9005455SLois Curfman McInnes /*@
2977c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
2978c9005455SLois Curfman McInnes 
29793f9fe445SBarry Smith    Logically Collective on SNES
2980fee21e36SBarry Smith 
2981c7afd0dbSLois Curfman McInnes    Input Parameters:
2982c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
29838c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
2984cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
2985758f92a0SBarry Smith .  na  - size of a and its
298664731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
2987758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
2988c7afd0dbSLois Curfman McInnes 
2989308dcc3eSBarry Smith    Notes:
2990308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
2991308dcc3eSBarry Smith    default array of length 10000 is allocated.
2992308dcc3eSBarry Smith 
2993c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
2994c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
2995c9005455SLois Curfman McInnes    during the section of code that is being timed.
2996c9005455SLois Curfman McInnes 
299736851e7fSLois Curfman McInnes    Level: intermediate
299836851e7fSLois Curfman McInnes 
2999c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
3000758f92a0SBarry Smith 
300108405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
3002758f92a0SBarry Smith 
3003c9005455SLois Curfman McInnes @*/
30047087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
3005c9005455SLois Curfman McInnes {
3006308dcc3eSBarry Smith   PetscErrorCode ierr;
3007308dcc3eSBarry Smith 
30083a40ed3dSBarry Smith   PetscFunctionBegin;
30090700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
30104482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
3011a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
3012308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
3013308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
3014308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
3015308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
3016308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
3017308dcc3eSBarry Smith   }
3018c9005455SLois Curfman McInnes   snes->conv_hist       = a;
3019758f92a0SBarry Smith   snes->conv_hist_its   = its;
3020758f92a0SBarry Smith   snes->conv_hist_max   = na;
3021a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
3022758f92a0SBarry Smith   snes->conv_hist_reset = reset;
3023758f92a0SBarry Smith   PetscFunctionReturn(0);
3024758f92a0SBarry Smith }
3025758f92a0SBarry Smith 
3026308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3027c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
3028c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
3029308dcc3eSBarry Smith EXTERN_C_BEGIN
3030308dcc3eSBarry Smith #undef __FUNCT__
3031308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
3032308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
3033308dcc3eSBarry Smith {
3034308dcc3eSBarry Smith   mxArray        *mat;
3035308dcc3eSBarry Smith   PetscInt       i;
3036308dcc3eSBarry Smith   PetscReal      *ar;
3037308dcc3eSBarry Smith 
3038308dcc3eSBarry Smith   PetscFunctionBegin;
3039308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
3040308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
3041308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
3042308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
3043308dcc3eSBarry Smith   }
3044308dcc3eSBarry Smith   PetscFunctionReturn(mat);
3045308dcc3eSBarry Smith }
3046308dcc3eSBarry Smith EXTERN_C_END
3047308dcc3eSBarry Smith #endif
3048308dcc3eSBarry Smith 
3049308dcc3eSBarry Smith 
30504a2ae208SSatish Balay #undef __FUNCT__
30514a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
30520c4c9dddSBarry Smith /*@C
3053758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
3054758f92a0SBarry Smith 
30553f9fe445SBarry Smith    Not Collective
3056758f92a0SBarry Smith 
3057758f92a0SBarry Smith    Input Parameter:
3058758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
3059758f92a0SBarry Smith 
3060758f92a0SBarry Smith    Output Parameters:
3061758f92a0SBarry Smith .  a   - array to hold history
3062758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
3063758f92a0SBarry Smith          negative if not converged) for each solve.
3064758f92a0SBarry Smith -  na  - size of a and its
3065758f92a0SBarry Smith 
3066758f92a0SBarry Smith    Notes:
3067758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
3068758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
3069758f92a0SBarry Smith 
3070758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
3071758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
3072758f92a0SBarry Smith    during the section of code that is being timed.
3073758f92a0SBarry Smith 
3074758f92a0SBarry Smith    Level: intermediate
3075758f92a0SBarry Smith 
3076758f92a0SBarry Smith .keywords: SNES, get, convergence, history
3077758f92a0SBarry Smith 
3078758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
3079758f92a0SBarry Smith 
3080758f92a0SBarry Smith @*/
30817087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3082758f92a0SBarry Smith {
3083758f92a0SBarry Smith   PetscFunctionBegin;
30840700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3085758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
3086758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
3087758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
30883a40ed3dSBarry Smith   PetscFunctionReturn(0);
3089c9005455SLois Curfman McInnes }
3090c9005455SLois Curfman McInnes 
3091e74ef692SMatthew Knepley #undef __FUNCT__
3092e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
3093ac226902SBarry Smith /*@C
309476b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
3095eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
30967e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
309776b2cf59SMatthew Knepley 
30983f9fe445SBarry Smith   Logically Collective on SNES
309976b2cf59SMatthew Knepley 
310076b2cf59SMatthew Knepley   Input Parameters:
310176b2cf59SMatthew Knepley . snes - The nonlinear solver context
310276b2cf59SMatthew Knepley . func - The function
310376b2cf59SMatthew Knepley 
310476b2cf59SMatthew Knepley   Calling sequence of func:
3105b5d30489SBarry Smith . func (SNES snes, PetscInt step);
310676b2cf59SMatthew Knepley 
310776b2cf59SMatthew Knepley . step - The current step of the iteration
310876b2cf59SMatthew Knepley 
3109fe97e370SBarry Smith   Level: advanced
3110fe97e370SBarry Smith 
3111fe97e370SBarry 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()
3112fe97e370SBarry Smith         This is not used by most users.
311376b2cf59SMatthew Knepley 
311476b2cf59SMatthew Knepley .keywords: SNES, update
3115b5d30489SBarry Smith 
311685385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
311776b2cf59SMatthew Knepley @*/
31187087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
311976b2cf59SMatthew Knepley {
312076b2cf59SMatthew Knepley   PetscFunctionBegin;
31210700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
3122e7788613SBarry Smith   snes->ops->update = func;
312376b2cf59SMatthew Knepley   PetscFunctionReturn(0);
312476b2cf59SMatthew Knepley }
312576b2cf59SMatthew Knepley 
3126e74ef692SMatthew Knepley #undef __FUNCT__
3127e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
312876b2cf59SMatthew Knepley /*@
312976b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
313076b2cf59SMatthew Knepley 
313176b2cf59SMatthew Knepley   Not collective
313276b2cf59SMatthew Knepley 
313376b2cf59SMatthew Knepley   Input Parameters:
313476b2cf59SMatthew Knepley . snes - The nonlinear solver context
313576b2cf59SMatthew Knepley . step - The current step of the iteration
313676b2cf59SMatthew Knepley 
3137205452f4SMatthew Knepley   Level: intermediate
3138205452f4SMatthew Knepley 
313976b2cf59SMatthew Knepley .keywords: SNES, update
3140a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
314176b2cf59SMatthew Knepley @*/
31427087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
314376b2cf59SMatthew Knepley {
314476b2cf59SMatthew Knepley   PetscFunctionBegin;
314576b2cf59SMatthew Knepley   PetscFunctionReturn(0);
314676b2cf59SMatthew Knepley }
314776b2cf59SMatthew Knepley 
31484a2ae208SSatish Balay #undef __FUNCT__
31494a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
31509b94acceSBarry Smith /*
31519b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
31529b94acceSBarry Smith    positive parameter delta.
31539b94acceSBarry Smith 
31549b94acceSBarry Smith     Input Parameters:
3155c7afd0dbSLois Curfman McInnes +   snes - the SNES context
31569b94acceSBarry Smith .   y - approximate solution of linear system
31579b94acceSBarry Smith .   fnorm - 2-norm of current function
3158c7afd0dbSLois Curfman McInnes -   delta - trust region size
31599b94acceSBarry Smith 
31609b94acceSBarry Smith     Output Parameters:
3161c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
31629b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
31639b94acceSBarry Smith     region, and exceeds zero otherwise.
3164c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
31659b94acceSBarry Smith 
31669b94acceSBarry Smith     Note:
31674b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
31689b94acceSBarry Smith     is set to be the maximum allowable step size.
31699b94acceSBarry Smith 
31709b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
31719b94acceSBarry Smith */
3172dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
31739b94acceSBarry Smith {
3174064f8208SBarry Smith   PetscReal      nrm;
3175ea709b57SSatish Balay   PetscScalar    cnorm;
3176dfbe8321SBarry Smith   PetscErrorCode ierr;
31773a40ed3dSBarry Smith 
31783a40ed3dSBarry Smith   PetscFunctionBegin;
31790700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
31800700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3181c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
3182184914b5SBarry Smith 
3183064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
3184064f8208SBarry Smith   if (nrm > *delta) {
3185064f8208SBarry Smith      nrm = *delta/nrm;
3186064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
3187064f8208SBarry Smith      cnorm = nrm;
31882dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
31899b94acceSBarry Smith      *ynorm = *delta;
31909b94acceSBarry Smith   } else {
31919b94acceSBarry Smith      *gpnorm = 0.0;
3192064f8208SBarry Smith      *ynorm = nrm;
31939b94acceSBarry Smith   }
31943a40ed3dSBarry Smith   PetscFunctionReturn(0);
31959b94acceSBarry Smith }
31969b94acceSBarry Smith 
31974a2ae208SSatish Balay #undef __FUNCT__
31984a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
31996ce558aeSBarry Smith /*@C
3200f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
3201f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
32029b94acceSBarry Smith 
3203c7afd0dbSLois Curfman McInnes    Collective on SNES
3204c7afd0dbSLois Curfman McInnes 
3205b2002411SLois Curfman McInnes    Input Parameters:
3206c7afd0dbSLois Curfman McInnes +  snes - the SNES context
32073cebf274SJed Brown .  b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero.
320885385478SLisandro Dalcin -  x - the solution vector.
32099b94acceSBarry Smith 
3210b2002411SLois Curfman McInnes    Notes:
32118ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
32128ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
32138ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
32148ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
32158ddd3da0SLois Curfman McInnes 
321636851e7fSLois Curfman McInnes    Level: beginner
321736851e7fSLois Curfman McInnes 
32189b94acceSBarry Smith .keywords: SNES, nonlinear, solve
32199b94acceSBarry Smith 
3220c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
32219b94acceSBarry Smith @*/
32227087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
32239b94acceSBarry Smith {
3224dfbe8321SBarry Smith   PetscErrorCode ierr;
3225ace3abfcSBarry Smith   PetscBool      flg;
3226eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
3227eabae89aSBarry Smith   PetscViewer    viewer;
3228efd51863SBarry Smith   PetscInt       grid;
3229a69afd8bSBarry Smith   Vec            xcreated = PETSC_NULL;
3230caa4e7f2SJed Brown   DM             dm;
3231052efed2SBarry Smith 
32323a40ed3dSBarry Smith   PetscFunctionBegin;
32330700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3234a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3235a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
32360700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
323785385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
323885385478SLisandro Dalcin 
3239caa4e7f2SJed Brown   if (!x) {
3240caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3241caa4e7f2SJed Brown     ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr);
3242a69afd8bSBarry Smith     x    = xcreated;
3243a69afd8bSBarry Smith   }
3244a69afd8bSBarry Smith 
3245a8248277SBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);}
3246efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
3247efd51863SBarry Smith 
324885385478SLisandro Dalcin     /* set solution vector */
3249efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
32506bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
325185385478SLisandro Dalcin     snes->vec_sol = x;
3252caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3253caa4e7f2SJed 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 */
3254caa4e7f2SJed Brown 
3255caa4e7f2SJed Brown     /* set affine vector if provided */
325685385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
32576bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
325885385478SLisandro Dalcin     snes->vec_rhs = b;
325985385478SLisandro Dalcin 
326070e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
32613f149594SLisandro Dalcin 
32627eee914bSBarry Smith     if (!grid) {
32637eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
3264d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
3265dd568438SSatish Balay       } else if (snes->dm) {
3266dd568438SSatish Balay         PetscBool ig;
3267dd568438SSatish Balay         ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr);
3268dd568438SSatish Balay         if (ig) {
32697eee914bSBarry Smith           ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr);
32707eee914bSBarry Smith         }
3271d25893d9SBarry Smith       }
3272dd568438SSatish Balay     }
3273d25893d9SBarry Smith 
3274abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
327550ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
3276d5e45103SBarry Smith 
32773f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
32784936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
327985385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
32804936397dSBarry Smith     if (snes->domainerror){
32814936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
32824936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
32834936397dSBarry Smith     }
328417186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
3285caa4e7f2SJed Brown     ierr = DMSNESSetSolution(snes->dm,PETSC_NULL);CHKERRQ(ierr); /* Un-post solution because inner contexts are done using it */
32863f149594SLisandro Dalcin 
32877adad957SLisandro Dalcin     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
3288eabae89aSBarry Smith     if (flg && !PetscPreLoadingOn) {
32897adad957SLisandro Dalcin       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
3290eabae89aSBarry Smith       ierr = SNESView(snes,viewer);CHKERRQ(ierr);
32916bf464f9SBarry Smith       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3292eabae89aSBarry Smith     }
3293eabae89aSBarry Smith 
329490d69ab7SBarry Smith     flg  = PETSC_FALSE;
3295acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
3296da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
32975968eb51SBarry Smith     if (snes->printreason) {
3298a8248277SBarry Smith       ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
32995968eb51SBarry Smith       if (snes->reason > 0) {
3300c7e7b494SJed 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);
33015968eb51SBarry Smith       } else {
3302c7e7b494SJed 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);
33035968eb51SBarry Smith       }
3304a8248277SBarry Smith       ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
33055968eb51SBarry Smith     }
33065968eb51SBarry Smith 
33078501fc72SJed Brown     flg = PETSC_FALSE;
33088501fc72SJed Brown     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
33098501fc72SJed Brown     if (flg) {
33108501fc72SJed Brown       PetscViewer viewer;
33118501fc72SJed Brown       ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
33128501fc72SJed Brown       ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr);
33138501fc72SJed Brown       ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr);
33148501fc72SJed Brown       ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr);
33158501fc72SJed Brown       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
33168501fc72SJed Brown     }
33178501fc72SJed Brown 
3318e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
3319efd51863SBarry Smith     if (grid <  snes->gridsequence) {
3320efd51863SBarry Smith       DM  fine;
3321efd51863SBarry Smith       Vec xnew;
3322efd51863SBarry Smith       Mat interp;
3323efd51863SBarry Smith 
3324efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
3325e727c939SJed Brown       ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
3326efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
3327efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
3328efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
3329efd51863SBarry Smith       x    = xnew;
3330efd51863SBarry Smith 
3331efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
3332efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
3333efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
3334a8248277SBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);
3335efd51863SBarry Smith     }
3336efd51863SBarry Smith   }
3337a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
33383a40ed3dSBarry Smith   PetscFunctionReturn(0);
33399b94acceSBarry Smith }
33409b94acceSBarry Smith 
33419b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
33429b94acceSBarry Smith 
33434a2ae208SSatish Balay #undef __FUNCT__
33444a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
334582bf6240SBarry Smith /*@C
33464b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
33479b94acceSBarry Smith 
3348fee21e36SBarry Smith    Collective on SNES
3349fee21e36SBarry Smith 
3350c7afd0dbSLois Curfman McInnes    Input Parameters:
3351c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3352454a90a3SBarry Smith -  type - a known method
3353c7afd0dbSLois Curfman McInnes 
3354c7afd0dbSLois Curfman McInnes    Options Database Key:
3355454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
3356c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
3357ae12b187SLois Curfman McInnes 
33589b94acceSBarry Smith    Notes:
3359e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
33604b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
3361c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
33624b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
3363c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
33649b94acceSBarry Smith 
3365ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
3366ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
3367ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
3368ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
3369ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
3370ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
3371ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
3372ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
3373ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
3374b0a32e0cSBarry Smith   appropriate method.
337536851e7fSLois Curfman McInnes 
337636851e7fSLois Curfman McInnes   Level: intermediate
3377a703fe33SLois Curfman McInnes 
3378454a90a3SBarry Smith .keywords: SNES, set, type
3379435da068SBarry Smith 
3380435da068SBarry Smith .seealso: SNESType, SNESCreate()
3381435da068SBarry Smith 
33829b94acceSBarry Smith @*/
33837087cfbeSBarry Smith PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
33849b94acceSBarry Smith {
3385dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
3386ace3abfcSBarry Smith   PetscBool      match;
33873a40ed3dSBarry Smith 
33883a40ed3dSBarry Smith   PetscFunctionBegin;
33890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
33904482741eSBarry Smith   PetscValidCharPointer(type,2);
339182bf6240SBarry Smith 
33926831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
33930f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
339492ff6ae8SBarry Smith 
33954b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
3396e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
339775396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
3398b5c23020SJed Brown   if (snes->ops->destroy) {
3399b5c23020SJed Brown     ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
3400b5c23020SJed Brown     snes->ops->destroy = PETSC_NULL;
3401b5c23020SJed Brown   }
340275396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
340375396ef9SLisandro Dalcin   snes->ops->setup          = 0;
340475396ef9SLisandro Dalcin   snes->ops->solve          = 0;
340575396ef9SLisandro Dalcin   snes->ops->view           = 0;
340675396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
340775396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
340875396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
340975396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
3410454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
341103bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
34129fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
34139fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
34149fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
34159fb22e1aSBarry Smith   }
34169fb22e1aSBarry Smith #endif
34173a40ed3dSBarry Smith   PetscFunctionReturn(0);
34189b94acceSBarry Smith }
34199b94acceSBarry Smith 
3420a847f771SSatish Balay 
34219b94acceSBarry Smith /* --------------------------------------------------------------------- */
34224a2ae208SSatish Balay #undef __FUNCT__
34234a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
342452baeb72SSatish Balay /*@
34259b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
3426f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
34279b94acceSBarry Smith 
3428fee21e36SBarry Smith    Not Collective
3429fee21e36SBarry Smith 
343036851e7fSLois Curfman McInnes    Level: advanced
343136851e7fSLois Curfman McInnes 
34329b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
34339b94acceSBarry Smith 
34349b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
34359b94acceSBarry Smith @*/
34367087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
34379b94acceSBarry Smith {
3438dfbe8321SBarry Smith   PetscErrorCode ierr;
343982bf6240SBarry Smith 
34403a40ed3dSBarry Smith   PetscFunctionBegin;
34411441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
34424c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
34433a40ed3dSBarry Smith   PetscFunctionReturn(0);
34449b94acceSBarry Smith }
34459b94acceSBarry Smith 
34464a2ae208SSatish Balay #undef __FUNCT__
34474a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
34489b94acceSBarry Smith /*@C
34499a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
34509b94acceSBarry Smith 
3451c7afd0dbSLois Curfman McInnes    Not Collective
3452c7afd0dbSLois Curfman McInnes 
34539b94acceSBarry Smith    Input Parameter:
34544b0e389bSBarry Smith .  snes - nonlinear solver context
34559b94acceSBarry Smith 
34569b94acceSBarry Smith    Output Parameter:
34573a7fca6bSBarry Smith .  type - SNES method (a character string)
34589b94acceSBarry Smith 
345936851e7fSLois Curfman McInnes    Level: intermediate
346036851e7fSLois Curfman McInnes 
3461454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
34629b94acceSBarry Smith @*/
34637087cfbeSBarry Smith PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
34649b94acceSBarry Smith {
34653a40ed3dSBarry Smith   PetscFunctionBegin;
34660700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
34674482741eSBarry Smith   PetscValidPointer(type,2);
34687adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
34693a40ed3dSBarry Smith   PetscFunctionReturn(0);
34709b94acceSBarry Smith }
34719b94acceSBarry Smith 
34724a2ae208SSatish Balay #undef __FUNCT__
34734a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
347452baeb72SSatish Balay /*@
34759b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
3476c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
34779b94acceSBarry Smith 
3478c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3479c7afd0dbSLois Curfman McInnes 
34809b94acceSBarry Smith    Input Parameter:
34819b94acceSBarry Smith .  snes - the SNES context
34829b94acceSBarry Smith 
34839b94acceSBarry Smith    Output Parameter:
34849b94acceSBarry Smith .  x - the solution
34859b94acceSBarry Smith 
348670e92668SMatthew Knepley    Level: intermediate
348736851e7fSLois Curfman McInnes 
34889b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
34899b94acceSBarry Smith 
349085385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
34919b94acceSBarry Smith @*/
34927087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
34939b94acceSBarry Smith {
34943a40ed3dSBarry Smith   PetscFunctionBegin;
34950700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
34964482741eSBarry Smith   PetscValidPointer(x,2);
349785385478SLisandro Dalcin   *x = snes->vec_sol;
349870e92668SMatthew Knepley   PetscFunctionReturn(0);
349970e92668SMatthew Knepley }
350070e92668SMatthew Knepley 
350170e92668SMatthew Knepley #undef __FUNCT__
35024a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
350352baeb72SSatish Balay /*@
35049b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
35059b94acceSBarry Smith    stored.
35069b94acceSBarry Smith 
3507c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3508c7afd0dbSLois Curfman McInnes 
35099b94acceSBarry Smith    Input Parameter:
35109b94acceSBarry Smith .  snes - the SNES context
35119b94acceSBarry Smith 
35129b94acceSBarry Smith    Output Parameter:
35139b94acceSBarry Smith .  x - the solution update
35149b94acceSBarry Smith 
351536851e7fSLois Curfman McInnes    Level: advanced
351636851e7fSLois Curfman McInnes 
35179b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
35189b94acceSBarry Smith 
351985385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
35209b94acceSBarry Smith @*/
35217087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
35229b94acceSBarry Smith {
35233a40ed3dSBarry Smith   PetscFunctionBegin;
35240700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35254482741eSBarry Smith   PetscValidPointer(x,2);
352685385478SLisandro Dalcin   *x = snes->vec_sol_update;
35273a40ed3dSBarry Smith   PetscFunctionReturn(0);
35289b94acceSBarry Smith }
35299b94acceSBarry Smith 
35304a2ae208SSatish Balay #undef __FUNCT__
35314a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
35329b94acceSBarry Smith /*@C
35333638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
35349b94acceSBarry Smith 
3535a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
3536c7afd0dbSLois Curfman McInnes 
35379b94acceSBarry Smith    Input Parameter:
35389b94acceSBarry Smith .  snes - the SNES context
35399b94acceSBarry Smith 
35409b94acceSBarry Smith    Output Parameter:
35417bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
354270e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
354370e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
35449b94acceSBarry Smith 
354536851e7fSLois Curfman McInnes    Level: advanced
354636851e7fSLois Curfman McInnes 
3547a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
35489b94acceSBarry Smith 
35494b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
35509b94acceSBarry Smith @*/
35517087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
35529b94acceSBarry Smith {
3553a63bb30eSJed Brown   PetscErrorCode ierr;
35546cab3a1bSJed Brown   DM             dm;
3555a63bb30eSJed Brown 
35563a40ed3dSBarry Smith   PetscFunctionBegin;
35570700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3558a63bb30eSJed Brown   if (r) {
3559a63bb30eSJed Brown     if (!snes->vec_func) {
3560a63bb30eSJed Brown       if (snes->vec_rhs) {
3561a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
3562a63bb30eSJed Brown       } else if (snes->vec_sol) {
3563a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
3564a63bb30eSJed Brown       } else if (snes->dm) {
3565a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
3566a63bb30eSJed Brown       }
3567a63bb30eSJed Brown     }
3568a63bb30eSJed Brown     *r = snes->vec_func;
3569a63bb30eSJed Brown   }
35706cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
35716cab3a1bSJed Brown   ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr);
35723a40ed3dSBarry Smith   PetscFunctionReturn(0);
35739b94acceSBarry Smith }
35749b94acceSBarry Smith 
3575c79ef259SPeter Brune /*@C
3576c79ef259SPeter Brune    SNESGetGS - Returns the GS function and context.
3577c79ef259SPeter Brune 
3578c79ef259SPeter Brune    Input Parameter:
3579c79ef259SPeter Brune .  snes - the SNES context
3580c79ef259SPeter Brune 
3581c79ef259SPeter Brune    Output Parameter:
3582c79ef259SPeter Brune +  gsfunc - the function (or PETSC_NULL)
3583c79ef259SPeter Brune -  ctx    - the function context (or PETSC_NULL)
3584c79ef259SPeter Brune 
3585c79ef259SPeter Brune    Level: advanced
3586c79ef259SPeter Brune 
3587c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
3588c79ef259SPeter Brune 
3589c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction()
3590c79ef259SPeter Brune @*/
3591c79ef259SPeter Brune 
35924a2ae208SSatish Balay #undef __FUNCT__
3593646217ecSPeter Brune #define __FUNCT__ "SNESGetGS"
3594646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx)
3595646217ecSPeter Brune {
35966cab3a1bSJed Brown   PetscErrorCode ierr;
35976cab3a1bSJed Brown   DM             dm;
35986cab3a1bSJed Brown 
3599646217ecSPeter Brune   PetscFunctionBegin;
3600646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36016cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
36026cab3a1bSJed Brown   ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr);
3603646217ecSPeter Brune   PetscFunctionReturn(0);
3604646217ecSPeter Brune }
3605646217ecSPeter Brune 
36064a2ae208SSatish Balay #undef __FUNCT__
36074a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
36083c7409f5SSatish Balay /*@C
36093c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
3610d850072dSLois Curfman McInnes    SNES options in the database.
36113c7409f5SSatish Balay 
36123f9fe445SBarry Smith    Logically Collective on SNES
3613fee21e36SBarry Smith 
3614c7afd0dbSLois Curfman McInnes    Input Parameter:
3615c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3616c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3617c7afd0dbSLois Curfman McInnes 
3618d850072dSLois Curfman McInnes    Notes:
3619a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3620c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3621d850072dSLois Curfman McInnes 
362236851e7fSLois Curfman McInnes    Level: advanced
362336851e7fSLois Curfman McInnes 
36243c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
3625a86d99e1SLois Curfman McInnes 
3626a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
36273c7409f5SSatish Balay @*/
36287087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
36293c7409f5SSatish Balay {
3630dfbe8321SBarry Smith   PetscErrorCode ierr;
36313c7409f5SSatish Balay 
36323a40ed3dSBarry Smith   PetscFunctionBegin;
36330700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3634639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
36351cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
363694b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
36373a40ed3dSBarry Smith   PetscFunctionReturn(0);
36383c7409f5SSatish Balay }
36393c7409f5SSatish Balay 
36404a2ae208SSatish Balay #undef __FUNCT__
36414a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
36423c7409f5SSatish Balay /*@C
3643f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
3644d850072dSLois Curfman McInnes    SNES options in the database.
36453c7409f5SSatish Balay 
36463f9fe445SBarry Smith    Logically Collective on SNES
3647fee21e36SBarry Smith 
3648c7afd0dbSLois Curfman McInnes    Input Parameters:
3649c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3650c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3651c7afd0dbSLois Curfman McInnes 
3652d850072dSLois Curfman McInnes    Notes:
3653a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3654c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3655d850072dSLois Curfman McInnes 
365636851e7fSLois Curfman McInnes    Level: advanced
365736851e7fSLois Curfman McInnes 
36583c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
3659a86d99e1SLois Curfman McInnes 
3660a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
36613c7409f5SSatish Balay @*/
36627087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
36633c7409f5SSatish Balay {
3664dfbe8321SBarry Smith   PetscErrorCode ierr;
36653c7409f5SSatish Balay 
36663a40ed3dSBarry Smith   PetscFunctionBegin;
36670700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3668639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
36691cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
367094b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
36713a40ed3dSBarry Smith   PetscFunctionReturn(0);
36723c7409f5SSatish Balay }
36733c7409f5SSatish Balay 
36744a2ae208SSatish Balay #undef __FUNCT__
36754a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
36769ab63eb5SSatish Balay /*@C
36773c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
36783c7409f5SSatish Balay    SNES options in the database.
36793c7409f5SSatish Balay 
3680c7afd0dbSLois Curfman McInnes    Not Collective
3681c7afd0dbSLois Curfman McInnes 
36823c7409f5SSatish Balay    Input Parameter:
36833c7409f5SSatish Balay .  snes - the SNES context
36843c7409f5SSatish Balay 
36853c7409f5SSatish Balay    Output Parameter:
36863c7409f5SSatish Balay .  prefix - pointer to the prefix string used
36873c7409f5SSatish Balay 
36884ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
36899ab63eb5SSatish Balay    sufficient length to hold the prefix.
36909ab63eb5SSatish Balay 
369136851e7fSLois Curfman McInnes    Level: advanced
369236851e7fSLois Curfman McInnes 
36933c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
3694a86d99e1SLois Curfman McInnes 
3695a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
36963c7409f5SSatish Balay @*/
36977087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
36983c7409f5SSatish Balay {
3699dfbe8321SBarry Smith   PetscErrorCode ierr;
37003c7409f5SSatish Balay 
37013a40ed3dSBarry Smith   PetscFunctionBegin;
37020700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3703639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
37043a40ed3dSBarry Smith   PetscFunctionReturn(0);
37053c7409f5SSatish Balay }
37063c7409f5SSatish Balay 
3707b2002411SLois Curfman McInnes 
37084a2ae208SSatish Balay #undef __FUNCT__
37094a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
37103cea93caSBarry Smith /*@C
37113cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
37123cea93caSBarry Smith 
37137f6c08e0SMatthew Knepley   Level: advanced
37143cea93caSBarry Smith @*/
37157087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
3716b2002411SLois Curfman McInnes {
3717e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
3718dfbe8321SBarry Smith   PetscErrorCode ierr;
3719b2002411SLois Curfman McInnes 
3720b2002411SLois Curfman McInnes   PetscFunctionBegin;
3721b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3722c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3723b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
3724b2002411SLois Curfman McInnes }
3725da9b6338SBarry Smith 
3726da9b6338SBarry Smith #undef __FUNCT__
3727da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
37287087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
3729da9b6338SBarry Smith {
3730dfbe8321SBarry Smith   PetscErrorCode ierr;
373177431f27SBarry Smith   PetscInt       N,i,j;
3732da9b6338SBarry Smith   Vec            u,uh,fh;
3733da9b6338SBarry Smith   PetscScalar    value;
3734da9b6338SBarry Smith   PetscReal      norm;
3735da9b6338SBarry Smith 
3736da9b6338SBarry Smith   PetscFunctionBegin;
3737da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
3738da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
3739da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
3740da9b6338SBarry Smith 
3741da9b6338SBarry Smith   /* currently only works for sequential */
3742da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
3743da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
3744da9b6338SBarry Smith   for (i=0; i<N; i++) {
3745da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
374677431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
3747da9b6338SBarry Smith     for (j=-10; j<11; j++) {
3748ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
3749da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
37503ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
3751da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
375277431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
3753da9b6338SBarry Smith       value = -value;
3754da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
3755da9b6338SBarry Smith     }
3756da9b6338SBarry Smith   }
37576bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
37586bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
3759da9b6338SBarry Smith   PetscFunctionReturn(0);
3760da9b6338SBarry Smith }
376171f87433Sdalcinl 
376271f87433Sdalcinl #undef __FUNCT__
3763fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
376471f87433Sdalcinl /*@
3765fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
376671f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
376771f87433Sdalcinl    Newton method.
376871f87433Sdalcinl 
37693f9fe445SBarry Smith    Logically Collective on SNES
377071f87433Sdalcinl 
377171f87433Sdalcinl    Input Parameters:
377271f87433Sdalcinl +  snes - SNES context
377371f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
377471f87433Sdalcinl 
377564ba62caSBarry Smith     Options Database:
377664ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
377764ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
377864ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
377964ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
378064ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
378164ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
378264ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
378364ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
378464ba62caSBarry Smith 
378571f87433Sdalcinl    Notes:
378671f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
378771f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
378871f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
378971f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
379071f87433Sdalcinl    solver.
379171f87433Sdalcinl 
379271f87433Sdalcinl    Level: advanced
379371f87433Sdalcinl 
379471f87433Sdalcinl    Reference:
379571f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
379671f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
379771f87433Sdalcinl 
379871f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
379971f87433Sdalcinl 
3800fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
380171f87433Sdalcinl @*/
38027087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
380371f87433Sdalcinl {
380471f87433Sdalcinl   PetscFunctionBegin;
38050700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3806acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
380771f87433Sdalcinl   snes->ksp_ewconv = flag;
380871f87433Sdalcinl   PetscFunctionReturn(0);
380971f87433Sdalcinl }
381071f87433Sdalcinl 
381171f87433Sdalcinl #undef __FUNCT__
3812fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
381371f87433Sdalcinl /*@
3814fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
381571f87433Sdalcinl    for computing relative tolerance for linear solvers within an
381671f87433Sdalcinl    inexact Newton method.
381771f87433Sdalcinl 
381871f87433Sdalcinl    Not Collective
381971f87433Sdalcinl 
382071f87433Sdalcinl    Input Parameter:
382171f87433Sdalcinl .  snes - SNES context
382271f87433Sdalcinl 
382371f87433Sdalcinl    Output Parameter:
382471f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
382571f87433Sdalcinl 
382671f87433Sdalcinl    Notes:
382771f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
382871f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
382971f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
383071f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
383171f87433Sdalcinl    solver.
383271f87433Sdalcinl 
383371f87433Sdalcinl    Level: advanced
383471f87433Sdalcinl 
383571f87433Sdalcinl    Reference:
383671f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
383771f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
383871f87433Sdalcinl 
383971f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
384071f87433Sdalcinl 
3841fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
384271f87433Sdalcinl @*/
38437087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
384471f87433Sdalcinl {
384571f87433Sdalcinl   PetscFunctionBegin;
38460700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
384771f87433Sdalcinl   PetscValidPointer(flag,2);
384871f87433Sdalcinl   *flag = snes->ksp_ewconv;
384971f87433Sdalcinl   PetscFunctionReturn(0);
385071f87433Sdalcinl }
385171f87433Sdalcinl 
385271f87433Sdalcinl #undef __FUNCT__
3853fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
385471f87433Sdalcinl /*@
3855fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
385671f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
385771f87433Sdalcinl    Newton method.
385871f87433Sdalcinl 
38593f9fe445SBarry Smith    Logically Collective on SNES
386071f87433Sdalcinl 
386171f87433Sdalcinl    Input Parameters:
386271f87433Sdalcinl +    snes - SNES context
386371f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
386471f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
386571f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
386671f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
386771f87433Sdalcinl              (0 <= gamma2 <= 1)
386871f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
386971f87433Sdalcinl .    alpha2 - power for safeguard
387071f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
387171f87433Sdalcinl 
387271f87433Sdalcinl    Note:
387371f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
387471f87433Sdalcinl 
387571f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
387671f87433Sdalcinl 
387771f87433Sdalcinl    Level: advanced
387871f87433Sdalcinl 
387971f87433Sdalcinl    Reference:
388071f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
388171f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
388271f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
388371f87433Sdalcinl 
388471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
388571f87433Sdalcinl 
3886fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
388771f87433Sdalcinl @*/
38887087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
388971f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
389071f87433Sdalcinl {
3891fa9f3622SBarry Smith   SNESKSPEW *kctx;
389271f87433Sdalcinl   PetscFunctionBegin;
38930700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3894fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3895e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
3896c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
3897c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
3898c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
3899c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
3900c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
3901c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
3902c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
390371f87433Sdalcinl 
390471f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
390571f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
390671f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
390771f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
390871f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
390971f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
391071f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
391171f87433Sdalcinl 
391271f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
3913e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
391471f87433Sdalcinl   }
391571f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
3916e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
391771f87433Sdalcinl   }
391871f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
3919e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
392071f87433Sdalcinl   }
392171f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
3922e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
392371f87433Sdalcinl   }
392471f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
3925e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
392671f87433Sdalcinl   }
392771f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
3928e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
392971f87433Sdalcinl   }
393071f87433Sdalcinl   PetscFunctionReturn(0);
393171f87433Sdalcinl }
393271f87433Sdalcinl 
393371f87433Sdalcinl #undef __FUNCT__
3934fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
393571f87433Sdalcinl /*@
3936fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
393771f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
393871f87433Sdalcinl    Newton method.
393971f87433Sdalcinl 
394071f87433Sdalcinl    Not Collective
394171f87433Sdalcinl 
394271f87433Sdalcinl    Input Parameters:
394371f87433Sdalcinl      snes - SNES context
394471f87433Sdalcinl 
394571f87433Sdalcinl    Output Parameters:
394671f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
394771f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
394871f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
394971f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
395071f87433Sdalcinl              (0 <= gamma2 <= 1)
395171f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
395271f87433Sdalcinl .    alpha2 - power for safeguard
395371f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
395471f87433Sdalcinl 
395571f87433Sdalcinl    Level: advanced
395671f87433Sdalcinl 
395771f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
395871f87433Sdalcinl 
3959fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
396071f87433Sdalcinl @*/
39617087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
396271f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
396371f87433Sdalcinl {
3964fa9f3622SBarry Smith   SNESKSPEW *kctx;
396571f87433Sdalcinl   PetscFunctionBegin;
39660700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3967fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3968e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
396971f87433Sdalcinl   if(version)   *version   = kctx->version;
397071f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
397171f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
397271f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
397371f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
397471f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
397571f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
397671f87433Sdalcinl   PetscFunctionReturn(0);
397771f87433Sdalcinl }
397871f87433Sdalcinl 
397971f87433Sdalcinl #undef __FUNCT__
3980fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
3981fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
398271f87433Sdalcinl {
398371f87433Sdalcinl   PetscErrorCode ierr;
3984fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
398571f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
398671f87433Sdalcinl 
398771f87433Sdalcinl   PetscFunctionBegin;
3988e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
398971f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
399071f87433Sdalcinl     rtol = kctx->rtol_0;
399171f87433Sdalcinl   } else {
399271f87433Sdalcinl     if (kctx->version == 1) {
399371f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
399471f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
399571f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
399671f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
399771f87433Sdalcinl     } else if (kctx->version == 2) {
399871f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
399971f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
400071f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
400171f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
400271f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
400371f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
400471f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
400571f87433Sdalcinl       stol = PetscMax(rtol,stol);
400671f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
400771f87433Sdalcinl       /* safeguard: avoid oversolving */
400871f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
400971f87433Sdalcinl       stol = PetscMax(rtol,stol);
401071f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
4011e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
401271f87433Sdalcinl   }
401371f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
401471f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
401571f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
401671f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
401771f87433Sdalcinl   PetscFunctionReturn(0);
401871f87433Sdalcinl }
401971f87433Sdalcinl 
402071f87433Sdalcinl #undef __FUNCT__
4021fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
4022fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
402371f87433Sdalcinl {
402471f87433Sdalcinl   PetscErrorCode ierr;
4025fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
402671f87433Sdalcinl   PCSide         pcside;
402771f87433Sdalcinl   Vec            lres;
402871f87433Sdalcinl 
402971f87433Sdalcinl   PetscFunctionBegin;
4030e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
403171f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
403271f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
403371f87433Sdalcinl   if (kctx->version == 1) {
4034b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
403571f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
403671f87433Sdalcinl       /* KSP residual is true linear residual */
403771f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
403871f87433Sdalcinl     } else {
403971f87433Sdalcinl       /* KSP residual is preconditioned residual */
404071f87433Sdalcinl       /* compute true linear residual norm */
404171f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
404271f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
404371f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
404471f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
40456bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
404671f87433Sdalcinl     }
404771f87433Sdalcinl   }
404871f87433Sdalcinl   PetscFunctionReturn(0);
404971f87433Sdalcinl }
405071f87433Sdalcinl 
405171f87433Sdalcinl #undef __FUNCT__
405271f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
405371f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
405471f87433Sdalcinl {
405571f87433Sdalcinl   PetscErrorCode ierr;
405671f87433Sdalcinl 
405771f87433Sdalcinl   PetscFunctionBegin;
4058fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
405971f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
4060fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
406171f87433Sdalcinl   PetscFunctionReturn(0);
406271f87433Sdalcinl }
40636c699258SBarry Smith 
40646c699258SBarry Smith #undef __FUNCT__
40656c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
40666c699258SBarry Smith /*@
40676c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
40686c699258SBarry Smith 
40693f9fe445SBarry Smith    Logically Collective on SNES
40706c699258SBarry Smith 
40716c699258SBarry Smith    Input Parameters:
40726c699258SBarry Smith +  snes - the preconditioner context
40736c699258SBarry Smith -  dm - the dm
40746c699258SBarry Smith 
40756c699258SBarry Smith    Level: intermediate
40766c699258SBarry Smith 
40776c699258SBarry Smith 
40786c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
40796c699258SBarry Smith @*/
40807087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
40816c699258SBarry Smith {
40826c699258SBarry Smith   PetscErrorCode ierr;
4083345fed2cSBarry Smith   KSP            ksp;
40846cab3a1bSJed Brown   SNESDM         sdm;
40856c699258SBarry Smith 
40866c699258SBarry Smith   PetscFunctionBegin;
40870700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4088d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
40896cab3a1bSJed Brown   if (snes->dm) {               /* Move the SNESDM context over to the new DM unless the new DM already has one */
40906cab3a1bSJed Brown     PetscContainer oldcontainer,container;
40916cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr);
40926cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr);
40936cab3a1bSJed Brown     if (oldcontainer && !container) {
40946cab3a1bSJed Brown       ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr);
40956cab3a1bSJed Brown       ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr);
40966cab3a1bSJed Brown       if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */
40976cab3a1bSJed Brown         sdm->originaldm = dm;
40986cab3a1bSJed Brown       }
40996cab3a1bSJed Brown     }
41006bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
41016cab3a1bSJed Brown   }
41026c699258SBarry Smith   snes->dm = dm;
4103345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4104345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4105f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
41062c155ee1SBarry Smith   if (snes->pc) {
41072c155ee1SBarry Smith     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
41082c155ee1SBarry Smith   }
41096c699258SBarry Smith   PetscFunctionReturn(0);
41106c699258SBarry Smith }
41116c699258SBarry Smith 
41126c699258SBarry Smith #undef __FUNCT__
41136c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
41146c699258SBarry Smith /*@
41156c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
41166c699258SBarry Smith 
41173f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
41186c699258SBarry Smith 
41196c699258SBarry Smith    Input Parameter:
41206c699258SBarry Smith . snes - the preconditioner context
41216c699258SBarry Smith 
41226c699258SBarry Smith    Output Parameter:
41236c699258SBarry Smith .  dm - the dm
41246c699258SBarry Smith 
41256c699258SBarry Smith    Level: intermediate
41266c699258SBarry Smith 
41276c699258SBarry Smith 
41286c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
41296c699258SBarry Smith @*/
41307087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
41316c699258SBarry Smith {
41326cab3a1bSJed Brown   PetscErrorCode ierr;
41336cab3a1bSJed Brown 
41346c699258SBarry Smith   PetscFunctionBegin;
41350700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
41366cab3a1bSJed Brown   if (!snes->dm) {
41376cab3a1bSJed Brown     ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr);
41386cab3a1bSJed Brown   }
41396c699258SBarry Smith   *dm = snes->dm;
41406c699258SBarry Smith   PetscFunctionReturn(0);
41416c699258SBarry Smith }
41420807856dSBarry Smith 
414331823bd8SMatthew G Knepley #undef __FUNCT__
414431823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
414531823bd8SMatthew G Knepley /*@
4146fd4b34e9SJed Brown   SNESSetPC - Sets the nonlinear preconditioner to be used.
414731823bd8SMatthew G Knepley 
414831823bd8SMatthew G Knepley   Collective on SNES
414931823bd8SMatthew G Knepley 
415031823bd8SMatthew G Knepley   Input Parameters:
415131823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
415231823bd8SMatthew G Knepley - pc   - the preconditioner object
415331823bd8SMatthew G Knepley 
415431823bd8SMatthew G Knepley   Notes:
415531823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
415631823bd8SMatthew G Knepley   to configure it using the API).
415731823bd8SMatthew G Knepley 
415831823bd8SMatthew G Knepley   Level: developer
415931823bd8SMatthew G Knepley 
416031823bd8SMatthew G Knepley .keywords: SNES, set, precondition
416131823bd8SMatthew G Knepley .seealso: SNESGetPC()
416231823bd8SMatthew G Knepley @*/
416331823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
416431823bd8SMatthew G Knepley {
416531823bd8SMatthew G Knepley   PetscErrorCode ierr;
416631823bd8SMatthew G Knepley 
416731823bd8SMatthew G Knepley   PetscFunctionBegin;
416831823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
416931823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
417031823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
417131823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4172bf11d3b6SBarry Smith   ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr);
417331823bd8SMatthew G Knepley   snes->pc = pc;
417431823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
417531823bd8SMatthew G Knepley   PetscFunctionReturn(0);
417631823bd8SMatthew G Knepley }
417731823bd8SMatthew G Knepley 
417831823bd8SMatthew G Knepley #undef __FUNCT__
417931823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
418031823bd8SMatthew G Knepley /*@
4181fd4b34e9SJed Brown   SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().
418231823bd8SMatthew G Knepley 
418331823bd8SMatthew G Knepley   Not Collective
418431823bd8SMatthew G Knepley 
418531823bd8SMatthew G Knepley   Input Parameter:
418631823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
418731823bd8SMatthew G Knepley 
418831823bd8SMatthew G Knepley   Output Parameter:
418931823bd8SMatthew G Knepley . pc - preconditioner context
419031823bd8SMatthew G Knepley 
419131823bd8SMatthew G Knepley   Level: developer
419231823bd8SMatthew G Knepley 
419331823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
419431823bd8SMatthew G Knepley .seealso: SNESSetPC()
419531823bd8SMatthew G Knepley @*/
419631823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
419731823bd8SMatthew G Knepley {
419831823bd8SMatthew G Knepley   PetscErrorCode ierr;
419931823bd8SMatthew G Knepley 
420031823bd8SMatthew G Knepley   PetscFunctionBegin;
420131823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
420231823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
420331823bd8SMatthew G Knepley   if (!snes->pc) {
420431823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr);
42054a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr);
420631823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
420731823bd8SMatthew G Knepley   }
420831823bd8SMatthew G Knepley   *pc = snes->pc;
420931823bd8SMatthew G Knepley   PetscFunctionReturn(0);
421031823bd8SMatthew G Knepley }
421131823bd8SMatthew G Knepley 
42129e764e56SPeter Brune #undef __FUNCT__
4213f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch"
42149e764e56SPeter Brune /*@
4215f1c6b773SPeter Brune   SNESSetSNESLineSearch - Sets the linesearch.
42169e764e56SPeter Brune 
42179e764e56SPeter Brune   Collective on SNES
42189e764e56SPeter Brune 
42199e764e56SPeter Brune   Input Parameters:
42209e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
42219e764e56SPeter Brune - linesearch   - the linesearch object
42229e764e56SPeter Brune 
42239e764e56SPeter Brune   Notes:
4224f1c6b773SPeter Brune   Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example,
42259e764e56SPeter Brune   to configure it using the API).
42269e764e56SPeter Brune 
42279e764e56SPeter Brune   Level: developer
42289e764e56SPeter Brune 
42299e764e56SPeter Brune .keywords: SNES, set, linesearch
4230f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch()
42319e764e56SPeter Brune @*/
4232f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch)
42339e764e56SPeter Brune {
42349e764e56SPeter Brune   PetscErrorCode ierr;
42359e764e56SPeter Brune 
42369e764e56SPeter Brune   PetscFunctionBegin;
42379e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4238f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
42399e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
42409e764e56SPeter Brune   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
4241f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
42429e764e56SPeter Brune   snes->linesearch = linesearch;
42439e764e56SPeter Brune   ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
42449e764e56SPeter Brune   PetscFunctionReturn(0);
42459e764e56SPeter Brune }
42469e764e56SPeter Brune 
42479e764e56SPeter Brune #undef __FUNCT__
4248f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch"
4249ea5d4fccSPeter Brune /*@C
4250f1c6b773SPeter Brune   SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch().
42519e764e56SPeter Brune 
42529e764e56SPeter Brune   Not Collective
42539e764e56SPeter Brune 
42549e764e56SPeter Brune   Input Parameter:
42559e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
42569e764e56SPeter Brune 
42579e764e56SPeter Brune   Output Parameter:
42589e764e56SPeter Brune . linesearch - linesearch context
42599e764e56SPeter Brune 
42609e764e56SPeter Brune   Level: developer
42619e764e56SPeter Brune 
42629e764e56SPeter Brune .keywords: SNES, get, linesearch
4263f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch()
42649e764e56SPeter Brune @*/
4265f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch)
42669e764e56SPeter Brune {
42679e764e56SPeter Brune   PetscErrorCode ierr;
42689e764e56SPeter Brune   const char     *optionsprefix;
42699e764e56SPeter Brune 
42709e764e56SPeter Brune   PetscFunctionBegin;
42719e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
42729e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
42739e764e56SPeter Brune   if (!snes->linesearch) {
42749e764e56SPeter Brune     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
4275f1c6b773SPeter Brune     ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr);
4276f1c6b773SPeter Brune     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
42779e764e56SPeter Brune     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
42789e764e56SPeter Brune     ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
42799e764e56SPeter Brune   }
42809e764e56SPeter Brune   *linesearch = snes->linesearch;
42819e764e56SPeter Brune   PetscFunctionReturn(0);
42829e764e56SPeter Brune }
42839e764e56SPeter Brune 
428469b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4285c6db04a5SJed Brown #include <mex.h>
428669b4f73cSBarry Smith 
42878f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
42888f6e6473SBarry Smith 
42890807856dSBarry Smith #undef __FUNCT__
42900807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
42910807856dSBarry Smith /*
42920807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
42930807856dSBarry Smith                          SNESSetFunctionMatlab().
42940807856dSBarry Smith 
42950807856dSBarry Smith    Collective on SNES
42960807856dSBarry Smith 
42970807856dSBarry Smith    Input Parameters:
42980807856dSBarry Smith +  snes - the SNES context
42990807856dSBarry Smith -  x - input vector
43000807856dSBarry Smith 
43010807856dSBarry Smith    Output Parameter:
43020807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
43030807856dSBarry Smith 
43040807856dSBarry Smith    Notes:
43050807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
43060807856dSBarry Smith    implementations, so most users would not generally call this routine
43070807856dSBarry Smith    themselves.
43080807856dSBarry Smith 
43090807856dSBarry Smith    Level: developer
43100807856dSBarry Smith 
43110807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
43120807856dSBarry Smith 
43130807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
431461b2408cSBarry Smith */
43157087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
43160807856dSBarry Smith {
4317e650e774SBarry Smith   PetscErrorCode    ierr;
43188f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
43198f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
43208f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
432191621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
4322e650e774SBarry Smith 
43230807856dSBarry Smith   PetscFunctionBegin;
43240807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
43250807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
43260807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
43270807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
43280807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
43290807856dSBarry Smith 
43300807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
4331e650e774SBarry Smith 
433291621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4333e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4334e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
433591621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
433691621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
433791621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
43388f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
43398f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
4340b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
4341e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4342e650e774SBarry Smith   mxDestroyArray(prhs[0]);
4343e650e774SBarry Smith   mxDestroyArray(prhs[1]);
4344e650e774SBarry Smith   mxDestroyArray(prhs[2]);
43458f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
4346e650e774SBarry Smith   mxDestroyArray(plhs[0]);
43470807856dSBarry Smith   PetscFunctionReturn(0);
43480807856dSBarry Smith }
43490807856dSBarry Smith 
43500807856dSBarry Smith 
43510807856dSBarry Smith #undef __FUNCT__
43520807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
435361b2408cSBarry Smith /*
43540807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
43550807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4356e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
43570807856dSBarry Smith 
43580807856dSBarry Smith    Logically Collective on SNES
43590807856dSBarry Smith 
43600807856dSBarry Smith    Input Parameters:
43610807856dSBarry Smith +  snes - the SNES context
43620807856dSBarry Smith .  r - vector to store function value
43630807856dSBarry Smith -  func - function evaluation routine
43640807856dSBarry Smith 
43650807856dSBarry Smith    Calling sequence of func:
436661b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
43670807856dSBarry Smith 
43680807856dSBarry Smith 
43690807856dSBarry Smith    Notes:
43700807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
43710807856dSBarry Smith $      f'(x) x = -f(x),
43720807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
43730807856dSBarry Smith 
43740807856dSBarry Smith    Level: beginner
43750807856dSBarry Smith 
43760807856dSBarry Smith .keywords: SNES, nonlinear, set, function
43770807856dSBarry Smith 
43780807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
437961b2408cSBarry Smith */
43807087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
43810807856dSBarry Smith {
43820807856dSBarry Smith   PetscErrorCode    ierr;
43838f6e6473SBarry Smith   SNESMatlabContext *sctx;
43840807856dSBarry Smith 
43850807856dSBarry Smith   PetscFunctionBegin;
43868f6e6473SBarry Smith   /* currently sctx is memory bleed */
43878f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
43888f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
43898f6e6473SBarry Smith   /*
43908f6e6473SBarry Smith      This should work, but it doesn't
43918f6e6473SBarry Smith   sctx->ctx = ctx;
43928f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
43938f6e6473SBarry Smith   */
43948f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
43958f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
43960807856dSBarry Smith   PetscFunctionReturn(0);
43970807856dSBarry Smith }
439869b4f73cSBarry Smith 
439961b2408cSBarry Smith #undef __FUNCT__
440061b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
440161b2408cSBarry Smith /*
440261b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
440361b2408cSBarry Smith                          SNESSetJacobianMatlab().
440461b2408cSBarry Smith 
440561b2408cSBarry Smith    Collective on SNES
440661b2408cSBarry Smith 
440761b2408cSBarry Smith    Input Parameters:
440861b2408cSBarry Smith +  snes - the SNES context
440961b2408cSBarry Smith .  x - input vector
441061b2408cSBarry Smith .  A, B - the matrices
441161b2408cSBarry Smith -  ctx - user context
441261b2408cSBarry Smith 
441361b2408cSBarry Smith    Output Parameter:
441461b2408cSBarry Smith .  flag - structure of the matrix
441561b2408cSBarry Smith 
441661b2408cSBarry Smith    Level: developer
441761b2408cSBarry Smith 
441861b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
441961b2408cSBarry Smith 
442061b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
442161b2408cSBarry Smith @*/
44227087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
442361b2408cSBarry Smith {
442461b2408cSBarry Smith   PetscErrorCode    ierr;
442561b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
442661b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
442761b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
442861b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
442961b2408cSBarry Smith 
443061b2408cSBarry Smith   PetscFunctionBegin;
443161b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
443261b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
443361b2408cSBarry Smith 
443461b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
443561b2408cSBarry Smith 
443661b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
443761b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
443861b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
443961b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
444061b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
444161b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
444261b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
444361b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
444461b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
444561b2408cSBarry Smith   prhs[5] =  sctx->ctx;
4446b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
444761b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
444861b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
444961b2408cSBarry Smith   mxDestroyArray(prhs[0]);
445061b2408cSBarry Smith   mxDestroyArray(prhs[1]);
445161b2408cSBarry Smith   mxDestroyArray(prhs[2]);
445261b2408cSBarry Smith   mxDestroyArray(prhs[3]);
445361b2408cSBarry Smith   mxDestroyArray(prhs[4]);
445461b2408cSBarry Smith   mxDestroyArray(plhs[0]);
445561b2408cSBarry Smith   mxDestroyArray(plhs[1]);
445661b2408cSBarry Smith   PetscFunctionReturn(0);
445761b2408cSBarry Smith }
445861b2408cSBarry Smith 
445961b2408cSBarry Smith 
446061b2408cSBarry Smith #undef __FUNCT__
446161b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
446261b2408cSBarry Smith /*
446361b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
446461b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4465e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
446661b2408cSBarry Smith 
446761b2408cSBarry Smith    Logically Collective on SNES
446861b2408cSBarry Smith 
446961b2408cSBarry Smith    Input Parameters:
447061b2408cSBarry Smith +  snes - the SNES context
447161b2408cSBarry Smith .  A,B - Jacobian matrices
447261b2408cSBarry Smith .  func - function evaluation routine
447361b2408cSBarry Smith -  ctx - user context
447461b2408cSBarry Smith 
447561b2408cSBarry Smith    Calling sequence of func:
447661b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
447761b2408cSBarry Smith 
447861b2408cSBarry Smith 
447961b2408cSBarry Smith    Level: developer
448061b2408cSBarry Smith 
448161b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
448261b2408cSBarry Smith 
448361b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
448461b2408cSBarry Smith */
44857087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
448661b2408cSBarry Smith {
448761b2408cSBarry Smith   PetscErrorCode    ierr;
448861b2408cSBarry Smith   SNESMatlabContext *sctx;
448961b2408cSBarry Smith 
449061b2408cSBarry Smith   PetscFunctionBegin;
449161b2408cSBarry Smith   /* currently sctx is memory bleed */
449261b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
449361b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
449461b2408cSBarry Smith   /*
449561b2408cSBarry Smith      This should work, but it doesn't
449661b2408cSBarry Smith   sctx->ctx = ctx;
449761b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
449861b2408cSBarry Smith   */
449961b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
450061b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
450161b2408cSBarry Smith   PetscFunctionReturn(0);
450261b2408cSBarry Smith }
450369b4f73cSBarry Smith 
4504f9eb7ae2SShri Abhyankar #undef __FUNCT__
4505f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
4506f9eb7ae2SShri Abhyankar /*
4507f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
4508f9eb7ae2SShri Abhyankar 
4509f9eb7ae2SShri Abhyankar    Collective on SNES
4510f9eb7ae2SShri Abhyankar 
4511f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
4512f9eb7ae2SShri Abhyankar @*/
45137087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
4514f9eb7ae2SShri Abhyankar {
4515f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
451648f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
4517f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
4518f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
4519f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
4520f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
4521f9eb7ae2SShri Abhyankar 
4522f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4523f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4524f9eb7ae2SShri Abhyankar 
4525f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4526f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4527f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
4528f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
4529f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
4530f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
4531f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
4532f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
4533f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
4534f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4535f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
4536f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
4537f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
4538f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
4539f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
4540f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
4541f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4542f9eb7ae2SShri Abhyankar }
4543f9eb7ae2SShri Abhyankar 
4544f9eb7ae2SShri Abhyankar 
4545f9eb7ae2SShri Abhyankar #undef __FUNCT__
4546f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
4547f9eb7ae2SShri Abhyankar /*
4548e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
4549f9eb7ae2SShri Abhyankar 
4550f9eb7ae2SShri Abhyankar    Level: developer
4551f9eb7ae2SShri Abhyankar 
4552f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
4553f9eb7ae2SShri Abhyankar 
4554f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
4555f9eb7ae2SShri Abhyankar */
45567087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
4557f9eb7ae2SShri Abhyankar {
4558f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
4559f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
4560f9eb7ae2SShri Abhyankar 
4561f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4562f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
4563f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
4564f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4565f9eb7ae2SShri Abhyankar   /*
4566f9eb7ae2SShri Abhyankar      This should work, but it doesn't
4567f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
4568f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
4569f9eb7ae2SShri Abhyankar   */
4570f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
4571f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4572f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4573f9eb7ae2SShri Abhyankar }
4574f9eb7ae2SShri Abhyankar 
457569b4f73cSBarry Smith #endif
4576